找回密码
 立即注册

QQ登录

只需一步,快速开始

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

这是个关于DS18B20的单片机测温程序 但是显示的温度为什么一直在15度啊 求大神

[复制链接]
跳转到指定楼层
楼主


单片机源程序如下:
  1. #include<reg51.h>                              
  2. #include<intrins.h>
  3. #include <absacc.h>
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. #define BUSY  0x80
  7. void Delay(uint);
  8. void init_LCD();
  9. void LCD_Com(uchar,uchar);
  10. void LCD_Data(uchar);
  11. void ReadyLCD();
  12. void Display_char(uchar X,uchar Y,uchar Data);
  13. void Display_str(uchar,uchar,uchar code *Data);
  14. void LCDDisplay();
  15. void init_18B20();
  16. uchar Read_18B20();
  17. void Write_18B20(uchar dat);
  18. void Read_temp1();
  19. void Delay_us(uchar i);
  20. void Key_scan( );
  21. void Key_set( );
  22. void Key_inc( );
  23. void Key_dec( );
  24. void Alarm( );
  25. sbit relay=P3^3;
  26. sbit triac1=P3^0;
  27. sbit triac2=P3^1;
  28. sbit triac3=P3^2;
  29. sbit LCD_RS=P2^0;
  30. sbit LCD_RW=P2^1;
  31. sbit LCD_EN=P2^2;
  32. sbit DQ=P1^7;
  33. sbit Normal=P2^4;
  34. sbit Alarm_B=P2^5;
  35. sbit Alarm_R=P2^6;
  36. sbit Alarm_BEEP=P2^7;

  37. uchar Set_flag=0;
  38. uchar Temp_set1,Temp_set2;        //用于存放读到的值
  39. uchar temp,temp1,temp2;
  40. extern uchar code str0[]={"C   :    D :    "};                        //显示设置1
  41. extern uchar code str1[]={"Mode:    DC:    "};                        //显示设置2
  42. extern uchar code str2[]={"    Hellow!!    "};
  43. extern uchar code str3[]={"0123456789"};
  44. extern uchar code mode[]={"NCD"};
  45. bit ON_OFF=0;   
  46. bit outflag;   
  47. bit write=0;  

  48. void main()                        //主程序
  49. {
  50.         P1=0xff;
  51.         P2|=0x70;
  52.         P2&=0x7f;
  53.         Temp_set1=40;          //设置温度40
  54.         Temp_set2=1;          //设置档位1
  55.         Delay(500);             //延时500ms
  56.         init_LCD();              //LCD初始化
  57.         init_18B20();            //DS18B20初始化
  58.         Display_str(0,0,str2);     //开机界面
  59.         Display_str(0,1,str2);     //开机界面
  60.         Delay(2000);                           //延迟
  61.         Display_str(0,0,str0);           //显示设置str0
  62.         Display_str(0,1,str1);           //显示设置str1
  63.         while(1)
  64.         {
  65.                 Key_scan();       //扫描键盘
  66.                 Read_temp1();     //读取温度
  67.                
  68.                 LCDDisplay();        //显示
  69.                 Alarm();         //指示灯与报警程序
  70.                 Delay(1000);                 //延迟
  71.         }
  72. }

  73. /********延时kms********/
  74. void Delay(uint k)
  75. {
  76.         uint i,j;
  77.         for(i=0;i<k;i++)
  78.         {
  79.                 for(j=0;j<60;j++)
  80.                 {
  81.                         ;
  82.                 }
  83.         }
  84. }
  85. /********精确延时********/
  86. void Delay_us(uchar i)
  87. {
  88.   while(--i);
  89. }

  90. /********显示模块********/
  91. /********LCD初始化********/
  92. void init_LCD()
  93. {
  94.         P0=0;
  95.         Delay(15);
  96.         LCD_Com(0x38,0);
  97.         Delay(5);
  98.         LCD_Com(0x38,0);
  99.         Delay(5);
  100.         LCD_Com(0x38,0);
  101.         Delay(5);
  102.         LCD_Com(0x38,1);  //8位数据传送,2行显示,5*7字形
  103.         LCD_Com(0x08,1);  //关闭显示
  104.         LCD_Com(0x01,1);  //清屏
  105.         LCD_Com(0x06,1);  //显示光标右移设置
  106.         LCD_Com(0x0c,1);  //显示屏打开,光标不显示不闪烁
  107. }

  108. /********写指令数据到LCD********/
  109. void LCD_Com(uchar LC,uchar BC)
  110. {
  111.         if(BC) ReadyLCD();
  112.         P0=LC;
  113.         LCD_RS=0;      //选中指令寄存器
  114.         LCD_RW=0;      //写模式
  115.         LCD_EN=1;
  116.         _nop_();
  117.         _nop_();
  118.         _nop_();
  119.         LCD_EN=0;
  120. }

  121. /********写显示数据到LCD********/
  122. void LCD_Data(uchar LD)
  123. {
  124.         ReadyLCD();
  125.         P0=LD;
  126.         LCD_RS=1;      //选中数据寄存器
  127.         LCD_RW=0;      //写模式
  128.         LCD_EN=1;
  129.         _nop_();
  130.         _nop_();
  131.         _nop_();
  132.         LCD_EN=0;
  133. }

  134. /********检测LCD忙状态********/
  135. void ReadyLCD()
  136. {
  137.         P0=0xff;
  138.         LCD_RS=0;
  139.         LCD_RW=1;
  140.         LCD_EN=1;
  141.         _nop_();
  142.         while(P0&BUSY)
  143.         {
  144.                 LCD_EN=0;
  145.                 _nop_();
  146.           _nop_();
  147.                 LCD_EN=1;
  148.                 _nop_();
  149.           _nop_();
  150.         }
  151.   LCD_EN=0;
  152. }

  153. /********显示一个字符********/
  154. void Display_char(uchar X,uchar Y,uchar Data)
  155. {
  156.         Y&=1;
  157.         X&=15;
  158.         if(Y) X|=0x40;
  159.         X|=0x80;
  160.         LCD_Com(X,0);
  161.         LCD_Data(Data);
  162. }

  163. /********显示一串字符********/
  164. void Display_str(uchar X,uchar Y,uchar code *Data)
  165. {
  166.         uchar List=0;
  167.         Y&=0x01;
  168.         X&=0x0f;
  169.         while(X<16)
  170.         {
  171.                 Display_char(X,Y,Data[List]);
  172.                 List++;
  173.                 X++;
  174.         }               
  175. }




  176. /********温度测量模块********/
  177. /********DS18B20初始化********/
  178. void init_18B20()
  179. {
  180.         uchar x=0;
  181.         DQ=1;            //DQ复位
  182.         Delay_us(8);       //延时
  183.         DQ=0;            //将DQ拉低
  184.         Delay_us(480);     //精确延时大于480us
  185.         DQ=1;            //拉高总线
  186.         Delay_us(15);
  187.         x=DQ;
  188.         Delay_us(20);
  189. }

  190. /********从DS18B20读取一个字节数据********/
  191. uchar Read_18B20()
  192. {
  193.         uchar i=0;
  194.         uchar dat=0;
  195.         for(i=8;i>0;i--)
  196.         {
  197.                 DQ=0;
  198.                 dat>>=1;
  199.                 DQ=1;
  200.                 Delay_us(1);
  201.                 if(DQ)
  202.         dat|=0x80;
  203.                 Delay_us(10);
  204.         }
  205.         return(dat);
  206. }


  207. /********向DS18B20写入一个字节数据********/
  208. void Write_18B20(uchar dat)
  209. {
  210.         uchar i=0;
  211.         for(i=8;i>0;i--)
  212.         {
  213.                 DQ=0;
  214.                 _nop_();
  215.                 DQ=dat&0x01;
  216.                 Delay_us(10);
  217.                 DQ=1;
  218.                 dat>>=1;
  219.                 Delay_us(10);
  220.         }
  221. }

  222. /********从DS18B20读取温度********/
  223. void Read_temp1()
  224. {
  225.         uchar a=0;
  226.         uchar b=0;
  227.         uchar t=0;
  228.         init_18B20();
  229.         Write_18B20(0xcc);                //写跳过读ROM指令
  230.         Write_18B20(0x44);                //写跳过读ROM指令
  231.     Delay_us(100);
  232.         init_18B20();
  233.         Write_18B20(0xcc);
  234.         Write_18B20(0xbe);
  235.         a=Read_18B20();
  236.         b=Read_18B20();
  237.     Delay_us(100);
  238.         t=b;
  239.         t<<=8;
  240.         t=t|a;
  241.   temp=t*(0.625);           //温度值扩大10倍

  242. }

  243. /********显示子程序********/
  244. void LCDDisplay()
  245. {        LCD_Com(0x0c,1);                        
  246.     Display_str(0,0,str0);     
  247.     Display_str(0,1,str1);   
  248.         Display_char(5,0,str3[Temp_set1/10]);
  249.         Display_char(6,0,str3[Temp_set1%10]);
  250.         Display_char(13,0,str3[Temp_set2/10]);
  251.         Display_char(14,0,str3[Temp_set2%10]);
  252.         Display_char(5,1,mode[Set_flag]);
  253.         Display_char(13,1,str3[temp%1000/100]);
  254.         Display_char(14,1,str3[temp%100/10]);

  255. }
  256. /********键盘扫描程序********/
  257. void Key_scan( )
  258. {

  259.         P1=0xff;
  260.         if(P1!=0xff)
  261.         {
  262.                 Delay(20);  //延时消抖
  263.                 if(P1!=0xff)
  264.                 {
  265.                        
  266.                         switch(P1)
  267.                         {
  268.                                 case 0xfe:Key_set();break; //P1.0按下,功能选择
  269.                                 case 0xfd:Key_inc();break; //P1.1按下,数字加一
  270.                                 case 0xfb:Key_dec();break; //P1.2按下,数字减一
  271.                                 default:break;
  272.                         }
  273.                 }
  274.         }
  275. }

  276. /********工作模式子程序********/
  277. void Key_set( )
  278. {
  279.         Set_flag++;
  280.         if(Set_flag>=3)  //设定温度值
  281.                 Set_flag=0;    //设定档位值
  282. }

  283. /********按键加一子程序********/
  284. void Key_inc( )
  285. {
  286.         switch(Set_flag)
  287.         {
  288.                 case 1:Temp_set1++;
  289.                        if(Temp_set1>=99) Temp_set1=99;break;
  290.                 case 2:Temp_set2++;
  291.                        if(Temp_set2>=Temp_set1) Temp_set2=Temp_set1;break;
  292.                 default:break;
  293.         }
  294. }

  295. /********按键减一子程序********/
  296. void Key_dec( )
  297. {
  298.       
  299.         switch(Set_flag)
  300.         {
  301.                 case 1:Temp_set1--;
  302.                        if(Temp_set1<=Temp_set2) Temp_set1=Temp_set2;break;
  303.                 case 2:Temp_set2--;
  304.                        if(Temp_set2<=1) Temp_set2=1;break;
  305.                 default:break;
  306.         }
  307. }

  308. /********报警和指示程序********/
  309. void Alarm( )
  310. {
  311.         uchar C;

  312.         C=Temp_set1+5;
  313.       
  314.         if(temp>C)
  315.         {
  316.                 Normal=1;
  317.                 Alarm_B=0;
  318.                 Alarm_R=1;
  319.                 Alarm_BEEP=1;
  320.   }
  321.          else
  322.          {
  323.             Normal=1;
  324.                 Alarm_B=1;
  325.                 Alarm_R=0;
  326.                 Alarm_BEEP=0;
  327.          }
  328. }

复制代码


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

使用道具 举报

沙发
ID:213173 发表于 2019-4-29 09:14 | 只看该作者
你的程序主要有两处错误:
1.DS18B20读取时序错误,Delay_us(480);uchar最大只能255,其它小延时也做了调整。
2.需要显示的数据分解方法错误,temp是uchar型数据,怎么能str3[temp%1000/100])、str3[temp%100/10]);
修改后的程序如下:




  1. #include<reg51.h>                              
  2. #include<intrins.h>
  3. #include <absacc.h>
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. #define BUSY  0x80
  7. void Delay(uint);
  8. void init_LCD();
  9. void LCD_Com(uchar,uchar);
  10. void LCD_Data(uchar);
  11. void ReadyLCD();
  12. void Display_char(uchar X,uchar Y,uchar Data);
  13. void Display_str(uchar,uchar,uchar code *Data);
  14. void LCDDisplay();
  15. void init_18B20();
  16. uchar Read_18B20();
  17. void Write_18B20(uchar dat);
  18. void Read_temp1();
  19. void Delay_us(uchar i);
  20. void Key_scan( );
  21. void Key_set( );
  22. void Key_inc( );
  23. void Key_dec( );
  24. void Alarm( );
  25. sbit relay=P3^3;
  26. sbit triac1=P3^0;
  27. sbit triac2=P3^1;
  28. sbit triac3=P3^2;
  29. sbit LCD_RS=P2^0;
  30. sbit LCD_RW=P2^1;
  31. sbit LCD_EN=P2^2;
  32. sbit DQ=P1^7;
  33. sbit Normal=P2^4;
  34. sbit Alarm_B=P2^5;
  35. sbit Alarm_R=P2^6;
  36. sbit Alarm_BEEP=P2^7;

  37. uchar Set_flag=0;
  38. uchar Temp_set1,Temp_set2;        //用于存放读到的值
  39. uchar temp,temp1,temp2;
  40. extern uchar code str0[]={"C   :    D :    "};                        //显示设置1
  41. extern uchar code str1[]={"Mode:    DC:    "};                        //显示设置2
  42. extern uchar code str2[]={"    Hellow!!    "};
  43. extern uchar code str3[]={"0123456789"};
  44. extern uchar code mode[]={"NCD"};
  45. bit ON_OFF=0;   
  46. bit outflag;   
  47. bit write=0;  

  48. void main()                        //主程序
  49. {
  50.         P1=0xff;
  51.         P2|=0x70;
  52.         P2&=0x7f;
  53.         Temp_set1=40;          //设置温度40
  54.         Temp_set2=1;          //设置档位1
  55.         Delay(500);             //延时500ms
  56.         init_LCD();              //LCD初始化
  57.         init_18B20();            //DS18B20初始化
  58.         Display_str(0,0,str2);     //开机界面
  59.         Display_str(0,1,str2);     //开机界面
  60.         Delay(2000);                           //延迟
  61.         Display_str(0,0,str0);           //显示设置str0
  62.         Display_str(0,1,str1);           //显示设置str1
  63.         while(1)
  64.         {
  65.                 Key_scan();       //扫描键盘
  66.                 Read_temp1();     //读取温度               
  67.                 LCDDisplay();        //显示
  68.                 Alarm();         //指示灯与报警程序
  69.                 Delay(1000);                 //延迟
  70.         }
  71. }

  72. /********延时kms********/
  73. void Delay(uint k)
  74. {
  75.         uint i,j;
  76.         for(i=0;i<k;i++)
  77.                 for(j=0;j<60;j++);
  78. }
  79. /********精确延时********/
  80. void Delay_us(uchar i)
  81. {
  82.   while(--i);
  83. }

  84. /********显示模块********/
  85. /********LCD初始化********/
  86. void init_LCD()
  87. {
  88.         P0=0;
  89.         Delay(15);
  90.         LCD_Com(0x38,0);
  91.         Delay(5);
  92.         LCD_Com(0x38,0);
  93.         Delay(5);
  94.         LCD_Com(0x38,0);
  95.         Delay(5);
  96.         LCD_Com(0x38,1);  //8位数据传送,2行显示,5*7字形
  97.         LCD_Com(0x08,1);  //关闭显示
  98.         LCD_Com(0x01,1);  //清屏
  99.         LCD_Com(0x06,1);  //显示光标右移设置
  100.         LCD_Com(0x0c,1);  //显示屏打开,光标不显示不闪烁
  101. }

  102. /********写指令数据到LCD********/
  103. void LCD_Com(uchar LC,uchar BC)
  104. {
  105.         if(BC) ReadyLCD();
  106.         P0=LC;
  107.         LCD_RS=0;      //选中指令寄存器
  108.         LCD_RW=0;      //写模式
  109.         LCD_EN=1;
  110.         _nop_();
  111.         _nop_();
  112.         _nop_();
  113.         LCD_EN=0;
  114. }

  115. /********写显示数据到LCD********/
  116. void LCD_Data(uchar LD)
  117. {
  118.         ReadyLCD();
  119.         P0=LD;
  120.         LCD_RS=1;      //选中数据寄存器
  121.         LCD_RW=0;      //写模式
  122.         LCD_EN=1;
  123.         _nop_();
  124.         _nop_();
  125.         _nop_();
  126.         LCD_EN=0;
  127. }

  128. /********检测LCD忙状态********/
  129. void ReadyLCD()
  130. {
  131.         P0=0xff;
  132.         LCD_RS=0;
  133.         LCD_RW=1;
  134.         LCD_EN=1;
  135.         _nop_();
  136.         while(P0&BUSY)
  137.         {
  138.                 LCD_EN=0;
  139.                 _nop_();
  140.           _nop_();
  141.                 LCD_EN=1;
  142.                 _nop_();
  143.           _nop_();
  144.         }
  145.   LCD_EN=0;
  146. }

  147. /********显示一个字符********/
  148. void Display_char(uchar X,uchar Y,uchar Data)
  149. {
  150.         Y&=1;
  151.         X&=15;
  152.         if(Y) X|=0x40;
  153.         X|=0x80;
  154.         LCD_Com(X,0);
  155.         LCD_Data(Data);
  156. }

  157. /********显示一串字符********/
  158. void Display_str(uchar X,uchar Y,uchar code *Data)
  159. {
  160.         uchar List=0;
  161.         Y&=0x01;
  162.         X&=0x0f;
  163.         while(X<16)
  164.         {
  165.                 Display_char(X,Y,Data[List]);
  166.                 List++;
  167.                 X++;
  168.         }               
  169. }




  170. /********温度测量模块********/
  171. /********DS18B20初始化********/
  172. void init_18B20()
  173. {
  174.         uchar x=0;
  175.         DQ=1;            //DQ复位
  176.         Delay_us(5);       //延时
  177.         DQ=0;            //将DQ拉低
  178.         Delay_us(200);     //精确延时大于480us
  179.         Delay_us(200);
  180.         DQ=1;            //拉高总线
  181.         Delay_us(50);
  182.         x=DQ;
  183.         Delay_us(25);
  184. }

  185. /********从DS18B20读取一个字节数据********/
  186. uchar Read_18B20()
  187. {
  188.         uchar i=0;
  189.         uchar dat=0;
  190.         for(i=8;i>0;i--)
  191.         {
  192.                 DQ=0;
  193.                 dat>>=1;
  194.                 DQ=1;
  195. //                Delay_us(1);
  196.                 if(DQ)
  197.                 dat|=0x80;
  198.                 Delay_us(25);
  199.         }
  200.         return(dat);
  201. }


  202. /********向DS18B20写入一个字节数据********/
  203. void Write_18B20(uchar dat)
  204. {
  205.         uchar i=0;
  206.         for(i=8;i>0;i--)
  207.         {
  208.                 DQ=0;
  209.                 _nop_();
  210.                 DQ=dat&0x01;
  211.                 Delay_us(25);
  212.                 DQ=1;
  213.                 dat>>=1;
  214.                 Delay_us(25);
  215.         }
  216. }

  217. /********从DS18B20读取温度********/
  218. void Read_temp1()
  219. {
  220.         uchar a=0;
  221.         uint b=0;
  222.         uint t=0;
  223. //        float tt;
  224.         init_18B20();
  225.         Write_18B20(0xcc);                //写跳过读ROM指令
  226.         Write_18B20(0x44);                //写跳过读ROM指令
  227.         Delay(20);
  228.         init_18B20();
  229.         Write_18B20(0xcc);
  230.         Write_18B20(0xbe);
  231.         a=Read_18B20();
  232.         b=Read_18B20();
  233.         b<<=8;
  234.         t=a+b;
  235.         temp=t>>4;
  236. }

  237. /********显示子程序********/
  238. void LCDDisplay()
  239. {
  240.         LCD_Com(0x0c,1);                        
  241.         Display_str(0,0,str0);     
  242.         Display_str(0,1,str1);   
  243.         Display_char(5,0,str3[Temp_set1/10]);
  244.         Display_char(6,0,str3[Temp_set1%10]);
  245.         Display_char(13,0,str3[Temp_set2/10]);
  246.         Display_char(14,0,str3[Temp_set2%10]);
  247.         Display_char(5,1,mode[Set_flag]);
  248.         Display_char(13,1,str3[temp/10%10]);
  249.         Display_char(14,1,str3[temp%10]);
  250. }
  251. /********键盘扫描程序********/
  252. void Key_scan( )
  253. {

  254.         P1=0xff;
  255.         if(P1!=0xff)
  256.         {
  257.                 Delay(20);  //延时消抖
  258.                 if(P1!=0xff)
  259.                 {
  260.                        
  261.                         switch(P1)
  262.                         {
  263.                                 case 0xfe:Key_set();break; //P1.0按下,功能选择
  264.                                 case 0xfd:Key_inc();break; //P1.1按下,数字加一
  265.                                 case 0xfb:Key_dec();break; //P1.2按下,数字减一
  266.                                 default:break;
  267.                         }
  268.                 }
  269.         }
  270. }

  271. /********工作模式子程序********/
  272. void Key_set( )
  273. {
  274.         Set_flag++;
  275.         if(Set_flag>=3)  //设定温度值
  276.                 Set_flag=0;    //设定档位值
  277. }

  278. /********按键加一子程序********/
  279. void Key_inc( )
  280. {
  281.         switch(Set_flag)
  282.         {
  283.                 case 1:Temp_set1++;
  284.                        if(Temp_set1>=99) Temp_set1=99;break;
  285.                 case 2:Temp_set2++;
  286.                        if(Temp_set2>=Temp_set1) Temp_set2=Temp_set1;break;
  287.                 default:break;
  288.         }
  289. }

  290. /********按键减一子程序********/
  291. void Key_dec( )
  292. {
  293.       
  294.         switch(Set_flag)
  295.         {
  296.                 case 1:Temp_set1--;
  297.                        if(Temp_set1<=Temp_set2) Temp_set1=Temp_set2;break;
  298.                 case 2:Temp_set2--;
  299.                        if(Temp_set2<=1) Temp_set2=1;break;
  300.                 default:break;
  301.         }
  302. }

  303. /********报警和指示程序********/
  304. void Alarm( )
  305. {
  306.         uchar C;

  307.         C=Temp_set1+5;
  308.       
  309.         if(temp>C)
  310.         {
  311.                 Normal=1;
  312.                 Alarm_B=0;
  313.                 Alarm_R=1;
  314.                 Alarm_BEEP=1;
  315.   }
  316.          else
  317.          {
  318.             Normal=1;
  319.                 Alarm_B=1;
  320.                 Alarm_R=0;
  321.                 Alarm_BEEP=0;
  322.          }
  323. }

复制代码



回复

使用道具 举报

板凳
ID:539433 发表于 2019-6-4 10:28 | 只看该作者
wulin 发表于 2019-4-29 09:14
你的程序主要有两处错误:
1.DS18B20读取时序错误,Delay_us(480);uchar最大只能255,其它小延时也做了调 ...

这个帖子对我太有用了,最近也在研究lcd显示
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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