完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我做的一个基于单片机的温湿度控制 传感器使用的是SHT11我自己找不出程序的错误 可是仿真确无法成功,望大侠指点一二啊 用液晶显示所测温湿度 接的是单片机P1口,由于只需要向其写数据 所以R/W接地,程序有详细的说明 求指教 急 谢谢了 #include #include #include #include #include #define uchar unsigned char #define uint unsigned int #define uiong unsigned long ***it DAT=P2^7;//SHT11数据 ***it SCK=P2^6;//SHT11时钟 ***it lcden=P3^6;//LCD命令/时钟端口 ***it lcdrs=P3^7;//lcd使能端 uchar error;//全局错误变量 uchar ack;//全局应答变量 uchar data_h;//数据高位 uchar data_l;//数据低位 int temp;//温度显值 int humi;//湿度显值 int dis_buf[5];//显示缓冲区 uchar code dis1[]={"temp:"};//第一行显示表头 uchar code dis2[]={"Humi:"};//第二行显示表头 uchar code dis[]={"0123456789."};//显示数值 #define TEMP_ML 0x03//000 0001 1 温度命令 #define HUMI_ML 0x05//000 0010 1 湿度命令 void delay(uint count)//时间延时函数 { uint i,j; for(i=count;i>0;i--) for(j=110;j>0;j--); } void sht11_start()//SHT11启动程序 { DAT=1;SCK=0; _nop_(); SCK=1; _nop_(); DAT=0; _nop_(); SCK=0; _nop_(); _nop_(); _nop_(); SCK=1; _nop_(); DAT=1; _nop_(); SCK=0; } void sht11_rest(void)//SHT11复位程序 { uchar i; DAT=1; SCK=0; for(i=0;i<9;i++) { SCK=1; SCK=0; } sht11_start(); } void read(void)//读两个字节,返回应答信号 { uchar i,val; data_l=0; data_h=0; //SCK=0; /*读高八位*/ DAT=1;//释放数据总线 for(i=0x80;i>0;i/=2)//移位8位 { SCK=1;//上升沿读入 if(DAT) val=(val | i);//确定值先读入高位 SCK=0; } DAT=0;//应答信号 有应答为0,无为1 SCK=1;//第九个脉冲 _nop_();_nop_();_nop_();//脉冲宽度为5us SCK=0;DAT=1;//释放数据总线 data_h=val;//存测高字节 /*读低八位*/ val=0; DAT=1;//释放数据总线 for(i=0x80;i>0;i/=2) { SCK=1;//上升沿读入 if(DAT) val=(val | i);//确定值 SCK=0; } DAT=1; SCK=1;//第九个脉冲 _nop_();_nop_();_nop_();//脉冲宽度为5us SCK=0; DAT=1;//释放数据总线 data_l=val; } char write(uchar value)//写一个字节返回应答信号 { uchar i; ack=0;//默认低电平表示有应答 SCK=0; for(i=0x80;i>0;i/=2)//释放数据总线 { if(i & value)//先写入高值 DAT=1;//写入值1 else DAT=0; SCK=1;//上升沿写入 _nop_();_nop_();_nop_();//脉冲宽度为5us SCK=0; } DAT=1; //释放数据总线 SCK=1;//第九个脉冲 if(DAT==1)//读应答信号 ack=1;//高电平表示未应答,低电平表示有应答 SCK=0; return ack;//返回ack,1为没有应答,0为有应答 } void measure(uchar m1)//测量温度或者湿度返回校验值 { uint i; sht11_start();//启动 write(m1);//写入测温度或湿度指令 if(ack==1)//无应答 { sht11_rest();//复位 write(m1);//再次写入 } /* for(i=0;i<55535;i++)//判断是否处于忙状态 { if(DAT==0)//有应答就退出 break; else _nop_();//无应答就显示 }*/ read();//度温度或湿度 } void comp_temp(void)//计算温度 { float aa=0,temp_zi; aa=(float)(data_h*256)+(float)data_l;//高低字节合并 temp_zi=0.01*aa-40.1; if(temp_zi<0)//低于0以0计算 { temp_zi=0; } temp_zi=temp_zi*10;//保留一位 temp=(int)temp_zi;//温度 } void comp_humi(void)//计算湿度 { float aa=0,bb=0,humi_zi; int abcd=0; aa=(float)data_h*256+(float)data_l;//高低字节合并 bb=-4+0.0405*aa-aa*aa*0.0000028; humi_zi=((float)(temp)/10-25)*(0.01+0.00008*aa)+bb;//湿度信号补偿 humi_zi=bb*10;//保留小数点后面1位 humi=(int)humi_zi;//湿度 } void comp_temp_humi(void)//温湿度处理 { error=0; ack=0; sht11_rest();//复位 measure(TEMP_ML);//测温度 comp_temp();//计算温度 measure(HUMI_ML);//测湿度 comp_humi();//计算湿度 } void dat_wrt(uchar dat)//写数据 { lcden=0; delay(5); lcdrs=1;//RS=1;为写数据 delay(5); P1=dat;//写数据 delay(5); lcden=1;//高电平写入 delay(5); lcden=0; } void cmd_wrt(uchar cmd)//写命令 { lcden=0; delay(5); lcdrs=0;//RS=1;为写命令 delay(5); P1=cmd;//写入命令 delay(5); lcden=1;//上升沿写入 delay(5); lcden=0; } void init_1602(void) { cmd_wrt(0x01);//清屏 cmd_wrt(0x0c);//开显示,不显示光标,不闪烁 cmd_wrt(0x06);//光标左移显示不发生移位 cmd_wrt(0x38);//16*2显示,8位数据接口,5*7点阵 } void lcd_start(uchar start) { cmd_wrt(start|0x80);//确保显示在LCD上的位置 } uchar dat_adj(int dat1) { uchar i; dis_buf[0]=(int)(dat1/1000);//千位 dis_buf[1]=(int)((dat1%1000)/100);//百位 dis_buf[2]=(int)((dat1%100)/10);//十位 dis_buf[3]=10;//小数点 dis_buf[4]=(int)(dat1%10);//小数点后个位 for(i=0;i<2;i++) { if(dis_buf[i]!=0)//明确显示位数 break; } return(i); } void disp(int dat,uchar k) { uchar temp,j; temp=dat_adj(dat); lcd_start(k+temp);//确定显示位置 for(j=temp;j<5;j++) dat_wrt(dis[dis_buf[j]]);//写显示数据 } void print(uchar *str) { while(*str!=' |