找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12887|回复: 11
收起左侧

基于51单片机的温度采集显示系统

  [复制链接]
ID:281191 发表于 2018-2-1 14:44 | 显示全部楼层 |阅读模式
新手,小试牛刀,通过18b20采集温度,然后通过四位数码管显示出来。
以下是proteus仿真和源程序。
大家多多指教
仿真图.png

单片机源程序:
  1. #include <REGX52.H>
  2. #define uint8  unsigned char
  3. #define uint16 unsigned int
  4. sbit  DQ  =P3^7;//DS18B20数据端
  5. sbit KEY1=P1^0;
  6. sbit KEY2=P1^1;
  7. sbit KEY3=P1^2;
  8. uint16 Temperature;
  9. uint16 TemperatureSave;
  10. uint8 ReadFlag;//温度读取标志位
  11. uint16 RecTemperature[10];//记录的温度
  12. uint8 RecSum=0;//记录的数量最多10
  13. uint8 Fin;
  14. uint8 mode=0;
  15. uint8 code DuCode[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  16. 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴数码管段选码表,0-F无小数点
  17. uint8 code WeiCode[4]={0xFE,0xFD,0xFB,0xF7};//
  18. uint8 SegBus[4]={0x40,0x40,0x40,0x40};//数码管显示缓存
  19. code uint8 DecimalNum[16]={0,1,1,2,3,3,4,
  20. 4,5,6,6,7,8,8,9,9};//DS18B20读取的16bit数据最低4位对应的小数4舍5入取一位
  21. void SegShow(void);//数码管显示函数
  22. void Timer0Init(void);//定时器初始化函数
  23. uint16 ReadTemp(uint8 mode);//读取温度函数
  24. void ShowTemperature(uint16 temperature,uint8* str);
  25. void main(void)
  26. {Timer0Init();
  27.     ReadTemp(0);
  28.     while(1)
  29.     {
  30.         if(KEY1==0)
  31.         {
  32.             mode=(mode+1)%2;//模式
  33.             while(KEY1==0);
  34.         }
  35.         if(mode==1)//温度查询 +
  36.         {
  37.             if(KEY2==0)
  38.             {
  39.                 Fin=(Fin+1)%10;
  40.                 while(KEY2==0);
  41.             }
  42.             if(KEY3==0)
  43.             {
  44.                 if(--Fin==255)Fin=0;
  45.                 while(KEY3==0);
  46.             }
  47.                            
  48.         }

  49.         if(ReadFlag)//已经读取到温度
  50.         {
  51.             ReadFlag=0;
  52.             if(TemperatureSave!=Temperature)
  53.             {
  54.                 TemperatureSave=Temperature;
  55.                 RecTemperature[RecSum++]=Temperature;
  56.                 RecSum=RecSum%10;               
  57.             }
  58.             if(mode==0)
  59.             {
  60.                 ShowTemperature(Temperature,SegBus);
  61.             }
  62.             else
  63.             {
  64.                 ShowTemperature(RecTemperature[Fin],SegBus);
  65.             }
  66.             SegBus[2]|=0x80;//添加小数点;
  67.         }
  68.         SegShow();
  69.     }
  70. }

  71. /**************************************************
  72. 定时器初始化函数50ms定时中断
  73. **************************************************/
  74. void Timer0Init(void)
  75. {
  76.     TMOD=0x01;
  77.     TH0=(65536-50000)/256;
  78.     TL0=(65536-50000)%256;
  79.     TR0=1;
  80.     ET0=1;
  81.     EA=1;
  82. }
  83. /**************************************************
  84. 定时器中断函数
  85. **************************************************/
  86. void Timer0_ISR(void) interrupt 1
  87. {
  88.     static uint8 cnt=0;
  89.     TH0=(65536-50000)/256;
  90.     TL0=(65536-50000)%256;
  91.     cnt++;
  92.     if(cnt>15)//每隔750ms读取一次温度
  93.     {
  94.         Temperature=ReadTemp(1);//读取温度
  95.         cnt=0;
  96.         ReadTemp(0);//启动温度转换
  97.         ReadFlag=1;
  98.     }
  99. }
  100. /**************************************************
  101. 数码管用延时函数
  102. **************************************************/
  103. void DelaySeg(void)
  104. {
  105.     uint8 i;
  106.     for(i=0;i<110;i--);   
  107. }
  108. /**************************************************
  109. 1位十进制转数码管段码
  110. **************************************************/
  111. void Dec1ToSeg(uint8 dec,uint8 *str)
  112. {
  113.         str[0]=0;//百位不显示
  114.         str[1]=0;//个位不显示
  115.         str[2]=DuCode[dec];
  116. }
  117. /**************************************************
  118. 2位十进制转数码管段码
  119. **************************************************/
  120. void Dec2ToSeg(uint8 dec,uint8 *str)
  121. {
  122.         str[0]=0;
  123.         str[1]=DuCode[dec/10];
  124.         str[2]=DuCode[dec%10];
  125. }
  126. /**************************************************
  127. 3位十进制转数码管段码
  128. **************************************************/
  129. void Dec3ToSeg(uint8 dec,uint8 *str)
  130. {
  131.         str[0]=DuCode[dec/100];
  132.         str[1]=DuCode[dec%100/10];
  133.         str[2]=DuCode[dec%10];
  134. }
  135. /**************************************************
  136. 显示温度信息
  137. **************************************************/
  138. void ShowTemperature(uint16 temperature,uint8* str)
  139. {
  140.         if(temperature&0x8000)//负温度
  141.         {
  142.                 temperature=~temperature+1;
  143.                 str[3]=DuCode[DecimalNum[temperature&0x0f]];//计算小数部分
  144.                 temperature=temperature>>4;
  145.                 if(temperature>9)//负温度的时候最多只有2位整数部分
  146.                 {
  147.                         Dec3ToSeg(temperature,str);
  148.                         str[0]=0x40;//-                                
  149.                 }
  150.                 else
  151.                 {
  152.                         Dec2ToSeg(temperature,str);
  153.                         str[1]=0x40;//-;        
  154.                 }
  155.         }
  156.         else
  157.         {
  158.                 str[3]=DuCode[DecimalNum[temperature&0x0f]];//计算小数部分
  159.                 temperature=temperature>>4;
  160.                 if(temperature>99)
  161.                 {
  162.                         Dec3ToSeg(temperature,str);                        
  163.                 }
  164.                 else if(temperature>9)
  165.                 {
  166.                         Dec2ToSeg(temperature,str);                        
  167.                 }
  168.                 else
  169.                 {
  170.                         Dec1ToSeg(temperature,str);                        
  171.                 }                                
  172.         }
  173. }
  174. /**************************************************
  175. 数码管显示
  176. **************************************************/
  177. void SegShow(void)
  178. {
  179.     P0=0x00;
  180.     P2=WeiCode[0];
  181.     P0=SegBus[0];
  182.     DelaySeg();
  183.     P0=0x00;
  184.     P2=WeiCode[1];
  185.     P0=SegBus[1];
  186.     DelaySeg();
  187.     P0=0x00;
  188.     P2=WeiCode[2];
  189.     P0=SegBus[2];
  190.     DelaySeg();
  191.     P0=0x00;
  192.     P2=WeiCode[3];
  193.     P0=SegBus[3];
  194.     DelaySeg();            
  195. }
  196. /**************************************************
  197. 大致延时一次延时2*t+7us
  198. **************************************************/
  199. void DelayUs(uint8 t)
  200. {
  201.     while(--t);
  202. }
  203. /**************************************************
  204. DS18B20初始化
  205. **************************************************/
  206. void DS18B20Init(void)
  207. {
  208.    DQ = 1;      //DQ复位
  209.    DelayUs(10);  //稍做延时
  210.    DQ = 0;      //单片机将DQ拉低
  211.    DelayUs(200);//精确延时 大于 480us 小于960us
  212.    DelayUs(200);
  213.    DQ = 1;      //拉高总线
  214.    DelayUs(75); //15~60us 后 接收60-240us的存在脉冲
  215.    DelayUs(75);
  216. }
  217. /**************************************************
  218. 读取一个字节数据,返回uchar类型数据
  219. **************************************************/
  220. uint8 DS18B20Read(void)
  221. {
  222.    uint8 i=0;
  223.    uint8 cdat=0;
  224.    for(i=8;i>0;i--)
  225.    {
  226.           DQ=0;//给脉冲信号
  227.           cdat>>=1;
  228.           DQ = 1; // 给脉冲信号
  229.           if(DQ)
  230.             cdat|=0x80;
  231.       DelayUs(50);
  232.    }
  233.    return (cdat);
  234. }
  235. /**************************************************
  236. * 功能描述: 向DS18B20写一个字节数据
  237. **************************************************/
  238. void DS18B20Write(uint8 cdat)
  239. {
  240.         unsigned char i=0;
  241.         for(i=8;i>0;i--)
  242.         {
  243.            DQ=0;
  244.            DQ=cdat&0x01;
  245.            DelayUs(50);
  246.            DQ=1;
  247.            cdat>>=1;
  248.         }
  249.         DelayUs(50);
  250. }
  251. /**************************************************
  252. * 功能描述: 读取温度值,返回uint类型数据
  253. **************************************************/
  254. uint16 ReadTemp(uint8 mode)
  255. {
  256.    unsigned char a=0;
  257.    unsigned int b,t;
  258.     DS18B20Init();
  259.    DS18B20Write(0xCC); // 跳过读序号列号的操作
  260.    switch(mode)
  261.    {
  262.      case 0:
  263.        DS18B20Write(0x44); // 启动温度转换
  264.        return 0;
  265.      case 1:
  266.        DS18B20Write(0xBE); //读取温度寄存器
  267.        a=DS18B20Read();   //低位
  268.        b=DS18B20Read();   //高位
  269.        b<<=8;
  270.        t=a+b;
  271.        return (t);
  272.     default:return 0;
  273.    }
  274.    return (0);
  275. }
复制代码
0.png
下载:
数码管DS18B20温度整点记录.zip (70.75 KB, 下载次数: 122)

评分

参与人数 1黑币 +4 收起 理由
旋风sv + 4 很给力!

查看全部评分

回复

使用道具 举报

ID:338804 发表于 2018-5-28 08:46 | 显示全部楼层
仿真呢?
回复

使用道具 举报

ID:65956 发表于 2018-5-30 09:00 | 显示全部楼层
测试了,显示都不正常,确定程序可行?
回复

使用道具 举报

ID:363822 发表于 2018-7-3 11:18 | 显示全部楼层
用的是51 为什么定义为52
回复

使用道具 举报

ID:363959 发表于 2018-7-3 15:01 | 显示全部楼层
大哥你这张图11和12引脚后面连得什么,看不了啊
回复

使用道具 举报

ID:363959 发表于 2018-7-3 15:14 | 显示全部楼层
后面是不是接电源和地
回复

使用道具 举报

ID:363959 发表于 2018-7-3 15:14 | 显示全部楼层
还是有什么附加功能吗
回复

使用道具 举报

ID:364266 发表于 2018-7-3 19:22 | 显示全部楼层
我仿真18B20输出数据都是0
回复

使用道具 举报

ID:373169 发表于 2018-7-17 16:16 | 显示全部楼层
下载的文件会详尽一点么
回复

使用道具 举报

ID:661298 发表于 2019-12-24 10:42 | 显示全部楼层
为什么仿真的时候温度只显示一个数据呢?我的只显示8
回复

使用道具 举报

ID:739415 发表于 2020-4-28 08:50 | 显示全部楼层
感谢!
回复

使用道具 举报

ID:840996 发表于 2020-11-9 16:00 | 显示全部楼层
10、11脚连什么阿,楼主,急!!!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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