找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1209|回复: 2
收起左侧

STC12C5A60单片机程序实现DS18B20温度检测

[复制链接]
ID:1020872 发表于 2023-9-13 14:40 | 显示全部楼层 |阅读模式
要想成功读取DS18B20的温度,那么时序很重要,因为STC12C5A60是1T的单片机,跟STC89C52的延时是不一样的,所以在程序处理时,一定要特别注意延时是否正确,我在DS18B20身上研究了很久,一开始还以为是接线的问题或者是元件坏了,温度一直显示-0.006,后面查了很多资料才发现是时序不对,导致初始化不成功,如果看到我的帖子,希望对大家有所帮助
  1. /*-----------------------------------------------
  2.   名称:18B20温度传感器
  3. ------------------------------------------------*/
  4. #include"delay.h"
  5. #include"18b20.h"
  6. #include"LCD1602.h"
  7. uchar fu;
  8. /*------------------------------------------------
  9.                     端口定义
  10. ------------------------------------------------*/
  11. sbit DQ=P1^3;//ds18b20 端口
  12. sbit beep=P2^3;

  13. /*------------------------------------------------
  14.                     18b20初始化
  15. ------------------------------------------------*/
  16. unsigned char ds18b20_init(void)
  17. {
  18. unsigned char presence;

  19. DQ = 1;
  20. delay_us(2);
  21. DQ = 0;
  22. delay_us(500);
  23. DQ = 1;
  24. delay_us(70);
  25. presence = DQ;
  26. delay_us(500);
  27. return presence;
  28. }
  29. /*------------------------------------------------
  30.                     读一位
  31. ------------------------------------------------*/
  32. bit tmpreadbit(void)      
  33. {
  34. unsigned char a;
  35. DQ = 0;
  36. delay_us(5);
  37. DQ = 1;
  38. delay_us(5);
  39. a = DQ;
  40. delay_us(50);
  41. return a;
  42. }
  43. /*------------------------------------------------
  44.                     读一个字节
  45. ------------------------------------------------*/
  46. unsigned char ReadOneChar(void)  //read a byte date
  47. {
  48.   uchar i,j,dat;
  49.   dat=0;
  50.   for(i=1;i<=8;i++)
  51.   {
  52.     j=tmpreadbit();
  53.     dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里
  54.   }
  55.   return(dat);
  56. }

  57. /*------------------------------------------------
  58.                     写入一位
  59. ------------------------------------------------*/
  60. void ds18b20_writebit(unsigned char a)
  61. {

  62. DQ = 0;
  63. delay_us(10);
  64. DQ = a;
  65. delay_us(50);
  66. DQ = 1;
  67. }

  68. /*------------------------------------------------
  69.                     写入一个字节
  70. ------------------------------------------------*/
  71. void WriteOneChar(unsigned char dat)
  72. {
  73. unsigned char j;
  74.   bit testb;
  75.   for(j=1;j<=8;j++)
  76.   {
  77.     testb=dat&0x01;
  78.     dat=dat>>1;
  79.                 ds18b20_writebit(testb);
  80. }
  81. }


  82. void tmpchange(void)  //DS18B20开始获取温度并转换
  83. {
  84.   ds18b20_init();
  85.   DelayMs(1);
  86.   WriteOneChar(0xcc);  // address all drivers on bus
  87.   WriteOneChar(0x44);  //  initiates a single temperature conversion
  88. }

  89. /*------------------------------------------------
  90.                     读取温度
  91. ------------------------------------------------*/
  92. unsigned int ReadTemperature(void)
  93. {
  94.   unsigned char a,b;
  95.         unsigned int g,c,d,e;
  96. ds18b20_init();
  97. DelayMs(1);
  98. WriteOneChar(0xCC); //跳过读序号列号的操作
  99. WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  100. a=ReadOneChar();   //先读低位
  101. b=ReadOneChar();   //再读高位
  102. if(!(b&0x08))
  103. {
  104.         fu=1;
  105.         g=b;
  106.         c=((g<<8)|a)*6.25;        
  107. }
  108. else
  109. {
  110.   fu=0;
  111.         d=((b<<8)|a);
  112.         e=((~d)+1);
  113.         c=e*6.25;        
  114. }
  115. return(c);
  116. }


  117. void warn(uint s,uchar led)//蜂鸣器报警和灯闪烁 s控制音调,led控制灯
  118. {
  119.         uchar i;
  120.         i=s;
  121.         beep=0;     //蜂鸣器响
  122.         P1=~(led);  //控制相应的灯亮
  123.         while(i--)
  124.         {
  125.                 distemperature();//用温度显示函数起到延时的作用
  126.         }
  127.         beep=1;   //蜂鸣器不响
  128.         P1=0xff;  //控制相应的灯灭
  129.         i=s;
  130.         while(i--)
  131.         {
  132.                 distemperature();//用温度显示函数起到延时的作用
  133.         }        
  134. }

  135. void deal(uint t) //温度区间报警
  136. {
  137.         uchar i;
  138.         if((t>2700)&&(t<=2500)) //大于25度小于27度
  139.         {
  140.                 warn(40,0x01);  //第一个灯亮,蜂鸣器发出"滴"声
  141.         }
  142.         else if(t<=2500) //小于25度
  143.         {
  144.                 warn(10,0x03);//第一个和第二灯亮,蜂鸣器发出"滴"声
  145.         }
  146.         else if((t<3200)&&(t>=3000)) //小于32度大于30度
  147.         {
  148.                 warn(40,0x04);//第三个灯亮,蜂鸣器发出"滴"声
  149.         }
  150.         else if(t>=3200)//大于32度
  151.         {
  152.                 warn(10,0x0C);//第三个和第四个灯亮,蜂鸣器发出"滴"声
  153.         }
  154.         else //在27度和30度之间时只是调用显示函数延时
  155. {
  156.         i=40;
  157.         while(i--)
  158.         {
  159.           distemperature();        //用温度显示函数起到延时的作用
  160.         }
  161. }
  162. }


  163. void distemperature(void)
  164. {
  165.          unsigned int m1,m2,m3,m4,m5,temperature;
  166.          tmpchange();
  167.    temperature=ReadTemperature();//读取温度
  168.    if(fu==0)
  169.          {
  170.     LCD_Write_Char(5,1,'-');//写入负号的位置,如果是负温度就显示
  171.          }
  172.    else
  173.          {
  174.           LCD_Write_Char(5,1,0x20);//是正温度就显示空格,0x20在ASCII字符表里表示空格
  175.          }
  176.          m1=temperature/10000+48;  //1602字符显示ASCII的地址位0X30,0~9,对应的地址是48~57,所以计算出来的数要加48,48=0x30  /号是求整 %是求余  
  177.          m2=temperature%10000/1000+48;//为什么要除于10000呢,因为一开始温度换算的时就已经乘以100倍了,如果温度是110度,此时得出来的数就是11000,所以要除于10000
  178.          m3=temperature%1000/100+48;
  179.          m4=temperature%100/10+48;
  180.          m5=temperature%10+48;
  181.          LCD_Write_Char(6,1,m1);
  182.    LCD_Write_Char(7,1,m2);
  183.           LCD_Write_Char(8,1,m3);
  184.          LCD_Write_Char(9,1,'.');
  185.          LCD_Write_Char(10,1,m4);
  186.    LCD_Write_Char(11,1,m5);
  187. }
复制代码
原理图: 无
仿真: 无
代码: 1602 18b20.zip (58.15 KB, 下载次数: 35)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:852195 发表于 2023-9-23 17:15 | 显示全部楼层
感谢分享,移植到1T机的确成功。
回复

使用道具 举报

ID:1094355 发表于 2023-9-23 20:27 | 显示全部楼层
真是及时雨.正在找stc读取温度的资料
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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