//****************************************************************////AM系列读单总线使用范例//单片机:AT89S52或STC89C52RC//功能:串口发送温湿度数据波特率9600//晶振:12M(用户系统时钟如不是12M请更改相关宏定义及注释的延时时间)//编译环境:Keil3//公司:奥松电子//****************************************************************//#includereg52.h#includeintrins.h//用户根据自己的晶振修改相应值#defineFOSC12000000#defineBAUD9600//读传感器端口位定义,可修改sbitSensor_SDA=P0^0;sbitSensor_SCL=P0^1;//变量定义unsignedcharSensor_Data[5]={0x00,0x00,0x00,0x00,0x00};unsignedcharSensor_Check;//校验和unsignedcharSensor_AnswerFlag;//收到起始标志位unsignedcharSensor_ErrorFlag;//读取传感器错误标志unsignedintSys_CNT;unsignedintTmp;unsignedchar*String;//字符串定义#defineS_TempTemp:#defineS_RHRH:#defineS_CRCTCheck:True#defineS_CRCFCheck:Wrong#defineS_DataData:#defineS_NotSSensorNotConnected/********************************************\|*功能:延时晶振为12M时*||*t=1为20us然后成倍增加10us左右*|\********************************************/voidDelay_N10us(unsignedchart){while(t--){_nop_();}}/********************************************\|*功能:延时晶振为12M时*||*延时大约1ms*|\********************************************/voidDelay_N1ms(unsignedintt){unsignedinti;unsignedintj;for(j=t;j0;j--)for(i=124;i0;i--);//延时大约1ms}/********************************************\|*功能:初始化串口*|\********************************************/voidInitUART(void){unsignedintiTmpBaud;unsignedlonglTmpBaud;iTmpBaud=0;//首先选定定时器2作为波特率发生器,16位定时器,自动装载SCON=0x50;//SM0SM1SM2RENTB8RB8TIRI//01010000PCON=0x00;//PCON的地址是87H,这里SMOD=0T2CON=0x30;//TF2EXF2RCLKTCLKEXEN2TR2C(/T2)CP(/RL2)//00110000T2MOD=0x00;////////T2OEDCEN//00000000lTmpBaud=FOSC/BAUD;lTmpBaud/=32;//12T-modeiTmpBaud=lTmpBaud&0xFFFF;iTmpBaud=65536-iTmpBaud;RCAP2H=(iTmpBaud8)&0x0FF;RCAP2L=iTmpBaud&0x0FF;RI=0;//清除接收中断标志REN=1;//允许串行接收ES=1;//允许串行中断TR2=1;//启动定时器1EA=1;//开总中断}/********************************************\|*功能:串口发送函数*|\********************************************/voidUARTSend(charUCHAR){SBUF=UCHAR;while(TI==0);TI=0;}/********************************************\|*功能:串口中断函数*|\********************************************/voidUARTRead(void)interrupt4{chartemp;if(RI){RI=0;temp=SBUF;}}/********************************************\|*功能:串口发送子函数*|\********************************************/voidUART_PutString(unsignedchar*buf){while(*buf)UARTSend(*buf++);}voidUART_PutStringAndNum(unsignedchar*buf,unsignedintnum){unsignedchara[3],i;a[3]='0'+num%10;a[2]='.';a[1]='0'+num/10%10;a[0]='0'+num/100%10;while(*buf)UARTSend(*buf++);UARTSend('');for(i=0;i4;i++){UARTSend(a[i]);}}voidUART_PutStringAnd_Data(unsignedchar*buf,unsignedchar*bufdata){unsignedchara[2],i,j;while(*buf)UARTSend(*buf++);UARTSend('');for(i=0;i5;i++){a[0]=bufdata[i]/16;a[1]=bufdata[i]%16;for(j=0;j2;j++){if(a[j]9){a[j]=(a[j]-10)+'A';}else{a[j]=a[j]+'0';}UARTSend(a[j]);}UARTSend('');}}/********************************************\|*功能:串口发送传感器数据函数*|\********************************************/voidUARTSend_Nbyte(void){if(Sensor_AnswerFlag==1){Sensor_Check=Sensor_Data[0]+Sensor_Data[1]+Sensor_Data[2]+Sensor_Data[3];//校验成功if(Sensor_Check==Sensor_Data[4]){String=S_RH;//RH:;Tmp=Sensor_Data[0]*256+Sensor_Data[1];UART_PutStringAndNum(String,Tmp);UARTSend('');UARTSend('');String=S_Temp;//Temp:;Tmp=Sensor_Data[2]*256+Sensor_Data[3];UART_PutStringAndNum(String,Tmp);UARTSend('');UARTSend('');String=S_CRCT;//Check:True;UART_PutString(String);}else//校验失败送上读到数据{String=S_Data;//Data:;UART_PutStringAnd_Data(String,Sensor_Data);UARTSend('');UARTSend('');String=S_CRCF;//Check:Wrong;UART_PutString(String);}}//传感器未连接else{String=S_NotS;//SensorNotConnected;UART_PutString(String);}UARTSend(0x0A);}voidClear_Data(void){inti;for(i=0;i5;i++){Sensor_Data[i]=0x00;}//接收数据清零}/********************************************\|*功能:读传感器发送的单个字节*|\********************************************/unsignedcharRead_SensorData(void){unsignedchari,cnt;unsignedcharbuffer,tmp;buffer=0;for(i=0;i8;i++){cnt=0;while(!Sensor_SDA)//检测上次低电平是否结束{if(++cnt=300){break;}}//延时Min=26usMax50us跳过数据0的高电平Delay_N10us(2);//延时30us//判断传感器发送数据位tmp=0;if(Sensor_SDA){tmp=1;}cnt=0;while(Sensor_SDA)//等待高电平结束{if(++cnt=200){break;}}buffer=1;buffer|=tmp;}returnbuffer;}/********************************************\|*功能:读传感器*|\********************************************/unsignedcharRead_Sensor(void){unsignedchari;//主机拉低(Min=800USMax=20Ms)Sensor_SDA=0;Delay_N1ms(2);//延时2Ms//释放总线延时(Min=30usMax=50us)Sensor_SDA=1;Delay_N10us(1);//延时30us//主机设为输入判断传感器响应信号Sensor_SDA=1;Sensor_AnswerFlag=0;//传感器响应标志//判断从机是否有低电平响应信号如不响应则跳出,响应则向下运行if(Sensor_SDA==0){Sensor_AnswerFlag=1;//收到起始信号Sys_CNT=0;//判断从机是否发出80us的低电平响应信号是否结束while((!Sensor_SDA)){if(++Sys_CNT300)//防止进入死循环{Sensor_ErrorFlag=1;return0;}}Sys_CNT=0;//判断从机是否发出80us的高电平,如发出则进入数据接收状态while((Sensor_SDA)){if(++Sys_CNT300)//防止进入死循环{Sensor_ErrorFlag=1;return0;}}//数据接收传感器共发送40位数据//即5个字节高位先送5个字节分别为湿度高位湿度低位温度高位温度低位校验和//校验和为:湿度高位+湿度低位+温度高位+温度低位for(i=0;i5;i++){Sensor_Data[i]=Read_SensorData();}}else{Sensor_AnswerFlag=0;//未收到传感器响应}return1;}voidmain(void){Sensor_SCL=0;InitUART();//初始串口发送函数while(1){Clear_Data();//清除收到数据Read_Sensor();//读取传感器数据UARTSend_Nbyte(