找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1700|回复: 0
收起左侧

单片机+DS18B20温度显示问题,求教

[复制链接]
ID:713190 发表于 2020-3-22 04:40 | 显示全部楼层 |阅读模式
本帖最后由 喵喵喵喵喵喵喵 于 2020-3-22 17:27 编辑

IMG20200322042344.jpg

单片机源程序如下:

  1. #include<reg52.h>
  2. #include "intrins.h"
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. uchar a,miao,shi,fen,ri,yue,nian,week,keynum,temp,flagtime,ledcount,count,alarmflag,flagT/*时间分段标志*/,year1,month1,day1,lednum;
  6. uint flag;//取温度

  7. bit c_moon;
  8. data uchar year_moon,month_moon,day_moon;

  9. #define h1 0x80 //LCD第一行的初始化位置
  10. #define h2 0x80+0x40 //LCD第二行初始化位置
  11. sbit Gled=P1^6;//定义粉色led灯的管脚
  12. sbit Yled=P3^7;//定义黄色led灯的管脚

  13. //定义1602相关管脚
  14. sbit rs=P2^7;
  15. sbit en=P2^5;
  16. sbit rw=P2^6;
  17. //sbit led=P2^3;/*控制背光:15脚(串联10欧电阻)背光源正极*/
  18. //sbit busy=P0^7;//测忙线
  19. //DS1302芯片的管脚定义
  20. sbit IO=P2^2;
  21. sbit SCLK=P2^1;
  22. sbit RST=P2^3;

  23. sbit DQ=P2^0;/*定义DS18b20管脚*/

  24. sbit ACC0=ACC^0;//设置累加器
  25. sbit ACC7=ACC^7;

  26. //按键
  27. sbit key1=P3^0;//设置按键
  28. sbit key2=P3^4;
  29. sbit key3=P3^6;
  30. sbit beep=P1^7;//蜂鸣器,用于报时

  31. sbit lcdbusy=P0^7;

  32. void delay(uint z)//延时函数
  33. {
  34.         uint x,y;
  35.         for(x=z;x>0;x--)
  36.         for(y=110;y>0;y--);
  37. }
  38. void testbusy()//测忙
  39. {
  40.         P0=0xff;//注意是P0组
  41.         rs=0;
  42.         rw=1;
  43.         en=1;
  44.         while(lcdbusy);//等待不忙
  45.         en=0;
  46. }
  47. void writecom(uchar com)//写入指令函数
  48. {
  49.         testbusy();
  50.         P0=com;
  51.         rs=0;
  52.         rw=0;
  53.         en=1;
  54.         en=0;
  55. }
  56. void writedata(uchar dat)//写入数据函数
  57. {
  58.         testbusy();//先测忙
  59.         P0=dat;
  60.         rs=1;
  61.         rw=0;
  62.         en=1;
  63.         en=0;
  64. }
  65. void print(uchar a3,uchar *str)//写字符串函数(没有延时)
  66. {
  67.         writecom(a3|0x80);
  68.         while(*str!='\0')
  69.         {
  70.                 //delay(100);//延时一下
  71.                 writedata(*str++);
  72.         }
  73.         *str=0;
  74. }
  75. void print2(uchar a2,uchar *str)//用于头字条的显示延时
  76. {
  77.         writecom(a2|0x80);
  78.         while(*str!='\0')
  79.         {
  80.                 delay(130);//延时一下
  81.                 writedata(*str++);
  82.         }
  83.         *str=0;
  84. }
  85. void lcdinit()//1602初始化函数
  86. {
  87.         writecom(0x38);//设置为两行显示,8位显示
  88.         writecom(0x0c);//开显示,不显示光标
  89.         writecom(0x06);//光标右移
  90.         writecom(0x01);//清零
  91.         print2(0x80,"^_^ @_@  U_U -_-");//第一行显示制作者
  92.         print2(0x40,"Enjoy Your Life!");//第二行显示制作人
  93.         delay(3000);// 延时3秒
  94.         //writecom(0x01);//再次清零
  95.         //writecom(h1);//第一行第一个字开始写入
  96. }


  97. /*以下是温度芯片DS18b20的相关函数*/
  98. void delay2(uint s)//延时,用于温度程序部分
  99. {
  100.         while(s--);//区分i,用s表示
  101. }
  102. void Init_DS18B20(void)//初始化DS18b20
  103. {
  104.         uchar W=0;//注意是w
  105.         DQ=1;
  106.         delay2(8);
  107.         DQ=0;//拉低
  108.         delay2(29);//延时大于480us(此处延时时间不确定,实际时修改)
  109.         DQ=1;//拉高
  110.         delay2(3);//(时间不确定)
  111.         W=DQ;//稍作延时后如W=0则初始化成功
  112.         delay2(20);
  113. }
  114. uchar ReadOneChar(void)//DS18b20读一个字节函数
  115. {
  116.         uchar i=0;
  117.         uchar dat=0;
  118.         for(i=8;i>0;i--)
  119.         {
  120.                 DQ=0;//给脉冲信号
  121.                 dat>>=1;//右移一位
  122.                 DQ=1;//给脉冲信号
  123.                 if(DQ)
  124.                 dat|=0x80;
  125.                 delay2(4);
  126.         }
  127.         return(dat);
  128. }
  129. void WriteOneChar(uchar dat)//写一个字节函数
  130. {
  131.         uchar i=0;
  132.         for(i=8;i>0;i--)
  133.         {
  134.                 DQ=0;
  135.                 DQ=dat&0x01;
  136.                 delay2(5);
  137.                 DQ=1;
  138.                 dat>>=1;
  139.         }
  140. }
  141. uint ReadTemperature(void)//读取温度
  142. {
  143.         uchar a1=0;//用于合并
  144.         uchar b1=0;
  145.         uint t=0;
  146.         float tt=0;
  147.         Init_DS18B20();
  148.         WriteOneChar(0xCC);//跳过读取序列号的操作
  149.         WriteOneChar(0x44);//启动温度转换
  150.         Init_DS18B20();//再次初始化
  151.         WriteOneChar(0xCC);//跳过读取序列号
  152.         WriteOneChar(0xBE);//读取温度寄存器
  153.         a1=ReadOneChar();//先读取低位
  154.         b1=ReadOneChar();//后读取高位
  155.         t=b1;
  156.         t<<=8;
  157.         t=t|a1;
  158.         tt=t*0.0625;
  159.         t=tt*10+0.5;//放大10倍并四舍五入
  160.         return(t);
  161. }

  162. /*下面是相关数据的显示函数*/
  163. //温度显示函数
  164. void writetemp(uchar add,uint dat)//写入温度值函数指定位置
  165. {
  166.         uchar gw,sw,xw;//个位,十位,小数位(注意得到为三位有效数)
  167.         gw=dat%100/10;/*特别注意此处*/
  168.         sw=dat/100;
  169.         xw=dat%10;
  170.         writecom(h2+add);//h2为头文件规定的值0x80+0x40
  171.         writedata(0x30+sw);//数字+30得到显示码
  172.         writedata(0x30+gw);//个位数
  173.         writedata(0x2e);//小数点
  174.         writedata(0x30+xw);//小数位
  175.         writedata(0xdf);//显示“°”(度)
  176.         //writedata(0x43);//显示“C”符号,为液晶字符的地址码(考虑是否要)
  177. }
  178. /*以下是主函数部分*/
  179. void main()
  180. {
  181.         alarmflag=1;
  182.         //led=0;
  183.         lcdinit();//初始化液晶函数
  184.         ds1302_init();//DS1302时钟芯片初始化函数
  185.         init();//定时器初始化函数
  186.         beep=0;
  187.         delay(200);
  188.         beep=1;
  189.         //led=0;
  190.         while(1)
  191.         {
  192.                 year1=(nian)/10*16+(nian)%10;//转换为bcd码
  193.                 month1=(yue)/10*16+(yue)%10;
  194.                 day1=(ri)/10*16+(ri)%10;
  195.                 chushihua();//初始化时间函数
  196.             Conversion(0,year1,month1,day1);//
  197.                 timealarm();//报时程序
  198.                 keyscan();//不断扫面按键函数
  199.                 /*if(key2==1)//加键不按下时才有用
  200.                 {
  201.         ledcontrol();//背光控制
  202.                 } */
  203.         }
  204. }
  205. void timer0() interrupt 1//中断任务:取数据并显示
  206. {
  207.         TH0=(65536-60000)/256;//重新赋初值
  208.         TL0=(65536-60000)%256;
  209.         //读取数据
  210.         flag=ReadTemperature();//读取温度(考虑是否放在此处)
  211.         miao=turnBCD(read_1302(0x81));//读出秒
  212.         fen=turnBCD(read_1302(0x83));//读出分
  213.         shi=turnBCD(read_1302(0x85));//读出时
  214.         ri=turnBCD(read_1302(0x87));//读出日
  215.         yue=turnBCD(read_1302(0x89));//读出月
  216.         nian=turnBCD(read_1302(0x8d));//读出年
  217.         week=turnBCD(read_1302(0x8b));//读出周
  218.         //显示数据
  219.         
  220.         if(((0<=miao)&&(miao<15))||(((miao/10==2)||(miao/10==4))&&(miao%10<=5))||((54<=miao)&&(miao<60))) /*显示所有信息的时间段*/
  221.         {
  222.                 print(0x80,"20  /  /   W < >");
  223.                 writecom(h1+0x0c);
  224.                 writedata(0x7e);//→右箭头
  225.                 writeday(8,ri);//显示日
  226.                 writeday(5,yue);//显示月
  227.                 writeday(2,nian);//显示年
  228.                 writeweek(week);//显示星期
  229.                 print(0x40,"  :  :          ");
  230.                 writetemp(9,flag);//显示温度,第二行显示
  231.                 writetime(6,miao);//显示出秒
  232.                 writetime(3,fen);//显示出分
  233.                 writetime(0,shi);//显示出时,第二行第一个开始
  234.         }

  235.         //if(15<=miao)/*当秒大于15时才显示*/
  236.         //{
  237.                 if(((miao/10==1)||(miao/10==3))&&(miao%10>=5))
  238.                 {
  239.                 switch(flag/100)//取出温度的十位数
  240.                 {
  241.                         case 0:print(0x80,"Pretty cold now!");
  242.                                    break;
  243.                         case 1:print(0x80,"little cold now!");
  244.                                    break;
  245.                         case 2:print(0x80,"It is warm now. ");
  246.                                    break;
  247.                         case 3:print(0x80,"It's hot !!!    ");
  248.                                    break;
  249.                         case 4:print(0x80,"Very very hot!!!");
  250.                                    break;
  251.                         case 5:print(0x80,"Very very hot!!!");
  252.                                    break;
  253.                         case 6:print(0x80,"Very very hot!!!");
  254.                                    break;
  255.                 }
  256.         
  257.                 //print(0x80,"It is warm now. ");
  258.                 print(0x40,"  :  :          ");
  259.                 writetemp(9,flag);//显示温度,第二行显示
  260.                 writetime(6,miao);//显示出秒
  261.                 writetime(3,fen);//显示出分
  262.                 writetime(0,shi);//显示出时,第二行第一个开始
  263.                 }
  264.                
  265. }

复制代码

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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