本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要 登录 才可以下载或查看,没有账号?注册会员
×
//#include "reg51.h"
//#include "intrins.h"
#include "128_64.h"
//#include "am2311.h"
#include "delay.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define IIC_Add 0xB8 //器件地址
#define IIC_RX_Length 15
//端口位定义,可修改
sbit mune=P0^0;
sbit SDA=P2^0;
sbit SCL=P2^1;
unsigned char m=0,O=0,PP=0,D=0;
unsigned char IIC_TX_Buffer[]={0x03,0x00,0x04}; //读温湿度命令(无CRC校验)
unsigned char IIC_RX_Buffer[IIC_RX_Length] = {0x00,0x00,0x00,0xa0,0x00,0x00};//读回的温湿度
unsigned char a[2];
unsigned char Uart_RX_Buffer[30] = {0x00};
unsigned char *String;
unsigned char WR_Flag;
//**********************************************
//送起始位 sda=1->0
void I2C_Start()
{
SDA=1;
SCL=1;
delay10us();
SDA=0;
delay10us();
SCL=0;
}
//************************************************
//送停止位 sda=0->1
void I2C_Stop()
{
SDA=0;
delay10us();
SCL=1;
delay10us();
SDA=1;
delay10us();
}
//************************************************
//主应答(包含ack:sda=0和no_ack:sda=0)
void Ack(void)
{
SDA=0;
SCL=1;
delay5us();
SCL=0;
delay5us();
SDA=1;
delay5us();
}
void NoAck(void)
{
SDA=1;
delay10us();
SCL=1;
delay10us();
SCL=0;
delay10us();
SDA=0;
delay10us();
}
bit Test_Ack()
{
bit ACK_Flag=0;
SCL=0;
SDA=1;//读入数据
SCL=1;
_nop_(); _nop_(); _nop_(); _nop_();
if(SDA==0)
ACK_Flag = 1;
else
ACK_Flag = 0;
SCL=0;
return ACK_Flag;
}
//*************************************************
//字节发送程序
//发送c(可以是数据也可是地址),送完后接收从应答
//不考虑从应答位
void SendData(unsigned char buffer)
{
unsigned char BitCnt=8;//一字节8位
do
{
SCL=0;
delay5us();
if((buffer&0x80)==0) //判断最高位是0还是1
SDA=0;
else
SDA=1;
SCL=1;
delay5us();
buffer=buffer<<1;//将buffer中的数据左移一位
BitCnt--;
}
while(BitCnt);
SCL=0;
}
//**************************************************
//字节接收程序
//接收器件传来的数据,此程序应配合|主应答函数|i2c_ack_main()使用
//return: uchar型1字节
unsigned char ReceiveData()
{
unsigned char BitCnt=8,IIC_RX_Data=0;
unsigned char temp=0;
SDA=1; //读入数据
do
{
SCL=0;
delay5us();
IIC_RX_Data=_crol_(IIC_RX_Data,1); //数据左移一位
BitCnt--;
SCL=1;
delay5us();
if(SDA==1)
IIC_RX_Data = IIC_RX_Data|0x01; //低位置1
else
IIC_RX_Data = IIC_RX_Data&0x0fe; //低位清0
}
while(BitCnt);
SCL=0;
return IIC_RX_Data;
}
bit WriteNByte(unsigned char sla,unsigned char *s,unsigned char n)
{
unsigned char i;
I2C_Start();//启动I2C
SendData(sla);//发送器件地址
if(!Test_Ack())
{
WR_Flag = 1;
return(0);
}
for(i=0;i<n;i++)//写入8字节数据
{
SendData(*(s+i));
if(!Test_Ack())
{
WR_Flag = 1;
return(0);
}
}
I2C_Stop();
return(1);
}
bit ReadNByte(unsigned char Sal, unsigned char *p,unsigned char n)
{
unsigned char i;
I2C_Start(); // 启动I2C
SendData((Sal)| 0x01); //发送器件地址
if(!Test_Ack())
{
WR_Flag = 1;
return(0);
}
delay10us(); // 延时时间必须大于30us
/* for(i=0;i<9;i++) //读取字节数据
{
*(p+i)=ReceiveData(); //读取数据
Ack();
} */
for(i=0;i<n-1;i++) //读取字节数据
{
*(p+i)=ReceiveData(); //读取数据
Ack();
}
*(p+n-1)=ReceiveData();
NoAck();
I2C_Stop();
return(1);
}
unsigned int CRC16(unsigned char *ptr, unsigned char len)
{
unsigned int crc=0xffff;
unsigned char i;
while(len--)
{
crc ^=*ptr++;
for(i=0;i<8;i++)
{
if(crc & 0x1)
{
crc>>=1;
crc^=0xa001;
}
else
{
crc>>=1;
}
}
}
return crc;
}
///检测CRC校验码是否正确
unsigned char CheckCRC(unsigned char *ptr,unsigned char len)
{
unsigned int crc;
crc=(unsigned int)CRC16(ptr,len-2);
if(ptr[len-1]==(crc>>8) && ptr[len-2]==(crc & 0x00ff))
{
return 0xff;
}
else
{
return 0x0;
}
}
void Waken(void)
{
I2C_Start(); //启动I2C
SendData(IIC_Add); // 发送器件地址
Test_Ack();
//Ack();
delay1ms(2);//至少延时1个Ms
I2C_Stop();
}
void shuju_zhuanhua(unsigned int num)
{
a[2]=num/100%10;
a[1]=num/10%10;
a[0]=num%10;
}
void nbyte()
{
int tmp;
if(CheckCRC(IIC_RX_Buffer,8))
{
tmp=IIC_RX_Buffer[2]*256+IIC_RX_Buffer[3];
tmp=tmp/10;
shuju_zhuanhua(tmp);
shuzi_lcd(5,48,a[2]);
shuzi_lcd(5,56,a[1]);
display_GB2312_string(5,64,".");
shuzi_lcd(5,72,a[0]);
tmp=IIC_RX_Buffer[4]*256+IIC_RX_Buffer[5];
tmp=(tmp&0x7fff)/10;
shuju_zhuanhua(tmp);
shuzi_lcd(7,48,a[2]);
shuzi_lcd(7,56,a[1]);
display_GB2312_string(7,64,".");
shuzi_lcd(7,72,a[0]);
display_GB2312_string(7,80," %RH");
}
display_GB2312_string(7,1,"请接温湿度传感器");
}
void Clear_Data (void)
{
int i;
for(i=0;i<IIC_RX_Length;i++)
{
IIC_RX_Buffer[i] = 0x00;
}//接收数据清零
}
////////////////////////////////////////////////////////////////////////////////////////////////
void main()
{
initial_lcd();
clear_screen(); //全屏清
//display_GB2312_string(1,16,"xx"); //开机画面
// display_GB2312_string(3,1,"xx"); //开机画面
//display_GB2312_string(5,1,"xxx"); //开机画面
//display_GB2312_string(7,1,"电话:xxxxxx"); //开机画面
//delay1(6);
// clear_screen();
clear_screen();
while(1)
{
WR_Flag = 0;
Waken(); // 唤醒传感器
WriteNByte(IIC_Add,IIC_TX_Buffer,3);
// 发送读取或写数据命令后,至少等待2MS(给探头返回数据作时间准备)
delay1ms(4);
ReadNByte(IIC_Add,IIC_RX_Buffer,8);
SCL = 1; SDA = 1; //确认释放总线
nbyte();
delay1ms(2000);
//yy();yx();
}
} |