找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2249|回复: 3
打印 上一主题 下一主题
收起左侧

单片机12864显示光照强度和温湿度 程序问题

[复制链接]
跳转到指定楼层
楼主
ID:377872 发表于 2019-10-14 10:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
10黑币
基于51单片机的用12864显示光照强度和温湿度,想多加两个温度过高或过低的指示灯,不知道为什么只能一个灯亮,温度变化灯也不会改变
单片机源程序如下:
  1. #include  <REG51.H>
  2. #include  <math.h>    //Keil library  
  3. #include  <stdio.h>   //Keil library
  4. #include  <INTRINS.H>
  5. #define   uchar unsigned char
  6. #define   uint unsigned int
  7. #define   DataPort P0  //LCD1602数据端口
  8. sbit   SCL=P2^1;      //IIC时钟引脚定义
  9. sbit     SDA=P2^2;      //IIC数据引脚定义
  10. sbit CS=P2^5;     //片选信号
  11. sbit SID=P2^6;  //数据信号
  12. sbit SCLK=P2^7;  //时钟信号
  13. sbit RST=P2^3;  //复位信号
  14. sbit CH = P2^4;  //并行、串行选择信号
  15. sbit dht_dat=P2^0; //用哪个I/O口自选,注意不要用P3口
  16. sbit LED1=P1^0;
  17. sbit LED2=P1^1;
  18. sbit FAN=P1^2;
  19. sbit key1=P1^3;
  20. sbit key2=P1^4;
  21. sbit buzzer=P1^5;
  22. uchar dht_num=0; //用于while循环中计数,超时则跳出循环
  23. uchar code table[]={"温度:"};
  24. uchar code table1[]={"湿度:"};
  25. uchar code table2[]={"℃"};
  26. uchar dht_d1=0,dht_d2=0,shidu=0        ;        //依次为湿度整数部分和湿度小数部
  27. uchar dht_t1=0,dht_t2=0 ,wendu=0       ;  //依次为温度整数部分和温度小数部分
  28. uchar dht_j=0;        //和校验,可选择是否使用,具体参照数据手
  29. uchar i,t11,t12,d11,d12;
  30. uchar t21,t22,d21,d22;
  31. #define   SlaveAddress   0x46 //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
  32.                             //ALT  ADDRESS引脚接地时地址为0x46,接电源时地址为0xB8
  33. typedef   unsigned char BYTE;
  34. typedef   unsigned short WORD;[/font]
  35. [font=黑体]BYTE    BUF[8];                         //接收数据缓存区      
  36. uchar   ge,shi,bai,qian,wan;            //显示变量
  37. int     dis_data;                       //变量[/font]
  38. [font=黑体]void delay_nms(unsigned int k);
  39. void InitLcd();
  40. void Init_BH1750(void);[/font]
  41. [font=黑体]void WriteDataLCM(uchar dataW);
  42. void WriteCommandLCM(uchar CMD,uchar Attribc);
  43. void DisplayOneChar(uchar DData);
  44. void conversion(uint temp_data);[/font]
  45. [font=黑体]void  Single_Write_BH1750(uchar REG_Address);               //单个写入数据
  46. uchar Single_Read_BH1750(uchar REG_Address);                //单个读取内部寄存器数据
  47. void  Multiple_Read_BH1750();                               //连续的读取内部寄存器数据
  48. //------------------------------------
  49. void Delay5us();
  50. void Delay5ms();
  51. void BH1750_Start();                    //起始信号
  52. void BH1750_Stop();                     //停止信号
  53. void BH1750_SendACK(bit ack);           //应答ACK
  54. bit  BH1750_RecvACK();                  //读ack
  55. void BH1750_SendByte(BYTE dat);         //IIC单个字节写
  56. BYTE BH1750_RecvByte();                 //IIC单个字节读[/font]
  57. [font=黑体]//-----------------------------------[/font]
  58. [font=黑体]//*********************************************************
  59. void conversion(uint temp_data)  //  数据转换出 个,十,百,千,万
  60. {  
  61.     wan=temp_data/10000+0x30 ;
  62.     temp_data=temp_data%10000;   //取余运算
  63. qian=temp_data/1000+0x30 ;
  64.     temp_data=temp_data%1000;    //取余运算
  65.     bai=temp_data/100+0x30   ;
  66.     temp_data=temp_data%100;     //取余运算
  67.     shi=temp_data/10+0x30    ;
  68.     temp_data=temp_data%10;      //取余运算
  69.     ge=temp_data+0x30;  
  70. }[/font]
  71. [font=黑体]//毫秒延时**************************
  72. void delay_nms(unsigned int k)
  73. {      
  74. unsigned int i,j;   
  75. for(i=0;i<k;i++)
  76. {   
  77. for(j=0;j<121;j++)   
  78. {;}}      
  79. }
  80. void delay(unsigned int t)
  81. {
  82. unsigned int i,j;
  83. for(i=0; i<t;  i++)
  84.     for(j=0; j<10; j++);
  85. }
  86. void sendbyte(unsigned char zdata)
  87. {
  88. unsigned int i;
  89. for(i=0; i<8; i++)
  90. {
  91.   if((zdata << i) & 0x80)
  92.   {
  93.    SID = 1;
  94.   }
  95.   else
  96.   {
  97.    SID = 0;
  98.   }
  99.   SCLK = 0;
  100.   SCLK = 1;
  101. }
  102. }[/font]
  103. [font=黑体]/********************************************************************
  104. * 名称 : write_com()
  105. * 功能 : 写串口指令
  106. * 输入 : cmdcode
  107. * 输出 : 无
  108. ***********************************************************************/
  109. void write_com(unsigned char cmdcode)
  110. {
  111. CS = 1;
  112. sendbyte(0xf8);
  113. sendbyte(cmdcode & 0xf0);
  114. sendbyte((cmdcode << 4) & 0xf0);
  115. delay(2);
  116. }[/font]
  117. [font=黑体]/********************************************************************
  118. * 名称 : write_data()
  119. * 功能 : 写串口指令
  120. * 输入 : cmdcode
  121. * 输出 : 无
  122. ***********************************************************************/
  123. void write_data(unsigned char Dispdata)
  124. {
  125. CS = 1;
  126. sendbyte(0xfa);
  127. sendbyte(Dispdata & 0xf0);
  128. sendbyte((Dispdata << 4) & 0xf0);
  129. delay(2);
  130. }[/font]
  131. [font=黑体]/********************************************************************
  132. * 名称 : lcdinit()
  133. * 功能 : 初始化函数
  134. * 输入 : cmdcode
  135. * 输出 : 无
  136. ***********************************************************************/
  137. void lcdinit()
  138. {  
  139. RST = 0;
  140. delay(100);
  141. RST = 1;
  142. delay(20000);
  143. write_com(0x30);
  144. delay(50);
  145. write_com(0x0c);
  146. delay(50);
  147. }[/font]
  148. [font=黑体]/********************************************************************
  149. * 名称 : hzkdis()
  150. * 功能 : 显示字符串
  151. * 输入 : *s
  152. * 输出 : 无
  153. ***********************************************************************/
  154. void hzkdis(unsigned char code *s)
  155. {  
  156. while(*s > 0)
  157.     {
  158.   write_data(*s);
  159.   s++;
  160.   delay(50);
  161.     }
  162. }[/font]
  163. [font=黑体]/********************************************************************
  164. * 名称 : Test()
  165. * 功能 : 显示子函数
  166. * 输入 : 无
  167. * 输出 : 无
  168. ***********************************************************************/[/font]
  169. [font=黑体]void DisplayOneChar(uchar DData)
  170. {      
  171. //Y&=4;      
  172. //X&=15;      
  173. //if(Y)X|=0x40;     
  174. //X|=0x80;   
  175. //WriteCommandLCM(X,0);  
  176. write_data(DData);  
  177. }      [/font]
  178. [font=黑体]/**************************************
  179. 延时5微秒(STC90C52RC@12M)
  180. 不同的工作环境,需要调整此函数,注意时钟过快时需要修改
  181. 当改用1T的MCU时,请调整此延时函数
  182. **************************************/
  183. void Delay5us()
  184. {
  185.     _nop_();_nop_();_nop_();_nop_();
  186.     _nop_();_nop_();_nop_();_nop_();
  187. _nop_();_nop_();_nop_();_nop_();
  188. _nop_();_nop_();_nop_();_nop_();
  189. }[/font]
  190. [font=黑体]/**************************************
  191. 延时5毫秒(STC90C52RC@12M)
  192. 不同的工作环境,需要调整此函数
  193. 当改用1T的MCU时,请调整此延时函数
  194. **************************************/
  195. void Delay5ms()
  196. {
  197.     WORD n = 560;[/font]
  198. [font=黑体]    while (n--);
  199. }[/font]
  200. [font=黑体]/**************************************
  201. 起始信号
  202. **************************************/
  203. void BH1750_Start()
  204. {
  205.     SDA = 1;                    //拉高数据线
  206.     SCL = 1;                    //拉高时钟线
  207.     Delay5us();                 //延时
  208.     SDA = 0;                    //产生下降沿
  209.     Delay5us();                 //延时
  210.     SCL = 0;                    //拉低时钟线
  211. }[/font]
  212. [font=黑体]/**************************************
  213. 停止信号
  214. **************************************/
  215. void BH1750_Stop()
  216. {
  217.     SDA = 0;                    //拉低数据线
  218.     SCL = 1;                    //拉高时钟线
  219.     Delay5us();                 //延时
  220.     SDA = 1;                    //产生上升沿
  221.     Delay5us();                 //延时
  222. }[/font]
  223. [font=黑体]/**************************************
  224. 发送应答信号
  225. 入口参数:ack (0:ACK 1:NAK)
  226. **************************************/
  227. void BH1750_SendACK(bit ack)
  228. {
  229.     SDA = ack;                  //写应答信号
  230.     SCL = 1;                    //拉高时钟线
  231.     Delay5us();                 //延时
  232.     SCL = 0;                    //拉低时钟线
  233.     Delay5us();                 //延时
  234. }[/font]
  235. [font=黑体]/**************************************
  236. 接收应答信号
  237. **************************************/
  238. bit BH1750_RecvACK()
  239. {
  240.     SCL = 1;                    //拉高时钟线
  241.     Delay5us();                 //延时
  242.     CY = SDA;                   //读应答信号
  243.     SCL = 0;                    //拉低时钟线
  244.     Delay5us();                 //延时[/font]
  245. [font=黑体]    return CY;
  246. }[/font]
  247. [font=黑体]/**************************************
  248. 向IIC总线发送一个字节数据
  249. **************************************/
  250. void BH1750_SendByte(BYTE dat)
  251. {
  252.     BYTE i;[/font]
  253. [font=黑体]    for (i=0; i<8; i++)         //8位计数器
  254.     {
  255.         dat <<= 1;              //移出数据的最高位
  256.         SDA = CY;               //送数据口
  257.         SCL = 1;                //拉高时钟线
  258.         Delay5us();             //延时
  259.         SCL = 0;                //拉低时钟线
  260.         Delay5us();             //延时
  261.     }
  262.     BH1750_RecvACK();
  263. }[/font]
  264. [font=黑体]/**************************************
  265. 从IIC总线接收一个字节数据
  266. **************************************/
  267. BYTE BH1750_RecvByte()
  268. {
  269.     BYTE i;
  270.     BYTE dat = 0;[/font]
  271. [font=黑体]    SDA = 1;                    //使能内部上拉,准备读取数据,
  272.     for (i=0; i<8; i++)         //8位计数器
  273.     {
  274.         dat <<= 1;
  275.         SCL = 1;                //拉高时钟线
  276.         Delay5us();             //延时
  277.         dat |= SDA;             //读数据               
  278.         SCL = 0;                //拉低时钟线
  279.         Delay5us();             //延时
  280.     }
  281.     return dat;
  282. }[/font]
  283. [font=黑体]//*********************************[/font]
  284. [font=黑体]void Single_Write_BH1750(uchar REG_Address)
  285. {
  286.     BH1750_Start();                  //起始信号
  287.     BH1750_SendByte(SlaveAddress);   //发送设备地址+写信号
  288.     BH1750_SendByte(REG_Address);    //内部寄存器地址,
  289.   //  BH1750_SendByte(REG_data);       //内部寄存器数据,
  290.     BH1750_Stop();                   //发送停止信号
  291. }[/font]
  292. [font=黑体]//********单字节读取*****************************************
  293. /*
  294. uchar Single_Read_BH1750(uchar REG_Address)
  295. {  uchar REG_data;
  296.     BH1750_Start();                          //起始信号
  297.     BH1750_SendByte(SlaveAddress);           //发送设备地址+写信号
  298.     BH1750_SendByte(REG_Address);                   //发送存储单元地址,从0开始
  299.     BH1750_Start();                          //起始信号
  300.     BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  301.     REG_data=BH1750_RecvByte();              //读出寄存器数据
  302. BH1750_SendACK(1);   
  303. BH1750_Stop();                           //停止信号
  304.     return REG_data;
  305. }
  306. */
  307. //*********************************************************
  308. //
  309. //连续读出BH1750内部数据
  310. //
  311. //*********************************************************
  312. void Multiple_read_BH1750(void)
  313. {   uchar i;
  314.     BH1750_Start();                          //起始信号
  315.     BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号

  316.   for (i=0; i<3; i++)                      //连续读取2个地址数据,存储中BUF
  317.     {
  318.         BUF[i] = BH1750_RecvByte();          //BUF[0]存储0x32地址中的数据
  319.         if (i == 3)
  320.         {[/i][/font][i]
  321. [font=黑体]           BH1750_SendACK(1);                //最后一个数据需要回NOACK
  322.         }
  323.         else
  324.         {  
  325.           BH1750_SendACK(0);                //回应ACK
  326.        }
  327.    }[/font]
  328. [font=黑体]    BH1750_Stop();                          //停止信号
  329.     Delay5ms();
  330. }[/font]
  331. [font=黑体]
  332. //初始化BH1750,根据需要请参考pdf进行修改****
  333. void Init_BH1750()
  334. {
  335.    Single_Write_BH1750(0x01);  
  336. }
  337. void delay1(uint xms)
  338. {
  339. uint i,j;
  340. for(i=xms;i>0;i--)
  341.         for(j=110;j>0;j--);
  342. }
  343. /*****************us延时函数*****************************/
  344. void delay_10us()
  345. {
  346.         _nop_();
  347.         _nop_();
  348.         _nop_();
  349.         _nop_();
  350.         _nop_();
  351.         _nop_();
  352. }
  353. /*写指令函数*/
  354. /*rs=l,rw=l,en=高脉冲,D0-D7=指令码。*/
  355. void write_cmd(uchar cmd)
  356. {
  357.         CS=0;
  358.         SID=0;
  359.         SCLK=0;
  360.         P0=cmd;
  361.         delay1(5);
  362.         SCLK=1;
  363.         delay1(5);
  364.         SCLK=0;
  365. }
  366. /***************************写显示数据************************/
  367. /*rs=h,rw=l,*/
  368. void write_dat(uchar date)
  369. {
  370. CS=1;
  371. SID=0;
  372. SCLK=0;
  373. P0=date;
  374. delay1(5);
  375. SCLK=1;
  376. delay1(5);
  377. SCLK=0;
  378. }
  379. /*****************初始化************************/
  380. void init()
  381. {        
  382.       SCLK=0;
  383.        SID=0;
  384.        CH=1;                  //并口方式
  385.         write_cmd(0x30);                //基本指令操作
  386.         delay1(5);
  387.         write_cmd(0x0c);                //显示开,关光标
  388.         delay1(5);
  389.         write_cmd(0x06);
  390.     delay1(2);
  391.         write_cmd(0x01);                //清除显示内容
  392.         delay1(5);
  393.                                 
  394.                                                                                                         
  395. }
  396. void dht_init()
  397. {
  398.    delay1(1000);          //DHT11上电前准备时间,大概1s
  399.    dht_dat=1;             //         //总线准备
  400. }
  401. uchar read_date()        //接收一个8位数据,先高位后低位
  402. {
  403.         uchar i,dat;
  404.         for(i=0;i<8;i++)   //也就是说程序是循环八次,把判断有“1”输出到dat中,然后输出一个八位的数据。
  405.         {
  406.                 dht_num=2;
  407.                 while((dht_dat==0)&&(dht_num++)); //dht_dat 数据线由DH11拉低准备发送数据
  408.                 delay_10us();
  409.                                 delay_10us();
  410.                 delay_10us();
  411.                                 delay_10us();
  412.                 dat=dat<<1;
  413.                 if(dht_dat==1)
  414.                 {
  415.                         dht_num=2;
  416.                         dat=dat|0x01;  //如果来自DQ的数据是高电平1,则把1放到dat的最低位
  417.                         while((dht_dat==1)&&(dht_num++));
  418.                 }
  419.         }
  420.         return dat;        
  421. }
  422. void get_temp()        //给DHT11一个开始信号,然后读取一次数据,共五个8位字节
  423. {
  424.         dht_dat=0;
  425.         delay1(25);
  426.         dht_dat=1;        //单片机给起始脉冲信号
  427.         delay_10us();
  428.         delay_10us();
  429.         delay_10us();
  430.         delay_10us();
  431.         dht_dat=1;         //稍作延时,等待DHT11返回响应(响应为低电 平)
  432.         if(dht_dat==0)         //有响应才接收数据,否则不作处理
  433.         {
  434.                 dht_num=2;
  435.                 while((dht_dat==0)&&(dht_num++));
  436.                 dht_num=2;
  437.                 while((dht_dat==1)&&(dht_num++));
  438.                 dht_d1=read_date();
  439.                 dht_d2=read_date();
  440.                 dht_t1=read_date();
  441.                 dht_t2=read_date();
  442.                 dht_j=read_date(); //一次读出五个数据
  443.         }
  444.         dht_dat=1;        //释放总线
  445.         delay1(10);
  446.         d11=dht_d1/10;
  447.         d12=dht_d1%10;
  448.         t11=dht_t1/10;
  449.         t12=dht_t1%10;
  450.                
  451.         d21=dht_d2/10;
  452.         d22=dht_d2%10;
  453.         t21=dht_t2/10;
  454.         t22=dht_t2%10;
  455.          
  456. }
  457. void guangzhaochushi()
  458. {

  459.    CH = 0;
  460. delay(1);
  461. lcdinit();
  462. delay(10);
  463.    Init_BH1750();       //初始化BH1750
  464. }
  465. //void gz()

  466. //*********************************************************
  467. //主程序********
  468. //*********************************************************
  469. void wenshi()
  470. {
  471. get_temp();
  472.                
  473.         
  474.                
  475.                
  476.                 write_cmd(0x80);
  477.                 for(i=0;i<6;i++)
  478.                 {
  479.                 write_dat(table[i]);
  480.                 }
  481.                 write_cmd(0x83);        
  482.                 write_dat(0x30+t11);
  483.                 write_dat(0x30+t12);
  484.                 write_cmd(0x80+4);
  485.                 write_dat('.');                                         
  486.                 write_dat(0x30+t21);
  487.                 write_cmd(0x85);                                
  488.                 write_dat(0x30+t22);                                                      
  489.                 write_cmd(0x86);
  490.         for(i=0;i<4;i++)
  491.         {
  492.          write_dat(table2[i]);                                 
  493.         }
  494.                 write_cmd(0x90);
  495.         for(i=0;i<6;i++)
  496.         {
  497.           write_dat(table1[i]);
  498.         }
  499.                 write_cmd(0x93);
  500.                 write_dat(0x30+d11);
  501.                 write_dat(0x30+d12);
  502.                 write_cmd(0x94);
  503.                 write_dat('.');                                                
  504.                 write_dat(0x30+d21);
  505.                 write_cmd(0x95);
  506.                 write_dat(0x30+d22);
  507.                 write_cmd(0x96);
  508.                 write_dat('%');      
  509. }
  510. void kongzhi()
  511. {
  512. if(wendu<35)
  513.   {
  514.    LED1=0;
  515.    delay_nms(10);
  516. //   buzzer=0;delay_nms(10);
  517.    LED2=1;delay_nms(10);
  518. //   FAN=1;delay_nms(10);
  519.   }
  520.   if(wendu>35)
  521.   {
  522. //    buzzer=1;delay_nms(10);
  523.    LED1=1;delay_nms(10);
  524.    LED2=0; delay_nms(10);
  525. //   FAN=0;delay_nms(10);
  526.   }
  527. // if(key1==0)
  528. // { delay_nms(10);
  529. //  if(key1==0)
  530. //  {
  531. //   gz();
  532. //   key2=1;
  533. //  }
  534. // }
  535. // if(key2==0)
  536. // { delay_nms(10);
  537. //  if(key2==0)
  538. //  {
  539. //   gz();
  540. //   wenshi();
  541. //  }
  542. // }
  543. }
  544. void main()
  545. {float temp;  
  546. buzzer=0;
  547. { delay_nms(100);     //延时100ms
  548. guangzhaochushi();
  549. { Single_Write_BH1750(0x01);   // power on
  550.     Single_Write_BH1750(0x10);   // H- resolution mode
  551.      delay_nms(180);              //延时180ms
  552.     Multiple_Read_BH1750();       //连续读出数据,存储在BUF中
  553.     dis_data=BUF[0];
  554.     dis_data=(dis_data<<8)+BUF[1];//合成数据,即光照数据
  555.    
  556.     temp=(float)dis_data/1.2;
  557.     conversion(temp);         //计算数据和显示
  558.   
  559. write_com(0x03);
  560. delay(50);   
  561. write_com(0x81);
  562. hzkdis("植物精准监控");
  563. write_com(0x91);
  564. hzkdis("17电子二班");
  565.   write_com(0x89);
  566.   hzkdis("光照强度:");
  567. write_com(0x98);
  568. hzkdis(" ");
  569. DisplayOneChar(wan);
  570. hzkdis(" ");
  571. DisplayOneChar(qian);
  572. hzkdis(" ");
  573. DisplayOneChar(bai);
  574. hzkdis(" ");
  575. DisplayOneChar(shi);
  576. hzkdis(" ");
  577. DisplayOneChar(ge);
  578. hzkdis(" ");
  579. hzkdis(" lx  ");  
  580. }
  581. }
  582. delay_nms(5000);
  583. dht_init();
  584. init();   
  585.   while(1)              //循环
  586.   {
  587.     wenshi();
  588.   delay_nms(5);
  589.   wendu=dht_d1+ (dht_d2)*10;
  590.     shidu=dht_t1+ (dht_t2)*10;
  591.     delay_nms(5);  
  592.   kongzhi();
  593.   delay_nms(5);
  594.   }
  595. }
复制代码

STC_BH1750.zip

59.3 KB, 下载次数: 22

51单片机控制12864显示光照和温湿

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:624334 发表于 2019-10-15 10:47 | 只看该作者
#在这里快速回复#51单片机控制12864显示光照和温湿
回复

使用道具 举报

板凳
ID:688460 发表于 2020-4-24 23:28 | 只看该作者
谢谢楼主的分享!好好学习天天向上!
回复

使用道具 举报

地板
ID:728680 发表于 2020-5-3 11:21 来自手机 | 只看该作者
楼上迷惑行为
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表