找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于STC8H8K64U单片机和DS18B20实现温度的串口通信读取

[复制链接]
跳转到指定楼层
楼主
功能实现和项目描述
单片机读取温度传感器数据,并通过串口发送至电脑
电路及实现效果


单片机代码如下:

  1. /*--------- DS18B20 -----------
  2. Function: Display temperature by UART
  3. Board: STC8H8K64U
  4. Main Fosc: 22.1184 MHz
  5. Baud rate: 9600 bps
  6. Connect: DQ --> P20
  7. Author: Jin-Lei Li
  8. Email: lijinlei0907@163.com
  9. Date: June.27, 2024
  10. Ref: UART section in STC32 series datasheet
  11. ------------------------------*/

  12. #include "STC8H.h"
  13. #include "intrins.h"

  14. typedef unsigned char u8;
  15. typedef unsigned int u16;
  16. typedef unsigned long int u32;

  17. #define MAIN_Fosc     22118400UL
  18. #define Baudrate      9600
  19. #define BRT           (65536 - (MAIN_Fosc/Baudrate + 2)/4)

  20. sbit DQ = P2^0;

  21. /*-- UART --*/
  22. bit busy;
  23. u8 wptr;
  24. u8 rptr;
  25. u8 buffer[16];
  26. /*---------*/
  27. bit MinusFlag;                //温度正负  0:正数  1:负数
  28. //u16 Temper; // temperature
  29. void GPIO_Init();
  30. void UartInit();
  31. void UartSend(u8 dat);
  32. void UartSendStr(u8 *p);
  33. void Display();
  34. void Delay_ms(u16 ms);
  35. /*----------- Main Program ----------------*/
  36. void main(void)
  37. {
  38.         P_SW2 |= 0x80; //扩展寄存器(XFR)访问使能
  39.         
  40.         GPIO_Init();
  41.   UartInit();
  42.         ES = 1;
  43.   EA = 1;
  44.   while(1)
  45.   {
  46.                 Display();
  47.     Delay_ms(500);
  48.   }
  49. }
  50. /*-------------- GPIO initialize ------------------*/
  51. void GPIO_Init()
  52. {
  53.         P0M1 = 0x00;   P0M0 = 0x00;
  54.   P1M1 = 0x00;   P1M0 = 0x00;
  55.   P2M1 = 0x00;   P2M0 = 0x00;
  56.   P3M1 = 0x00;   P3M0 = 0x00;
  57.   P4M1 = 0x00;   P4M0 = 0x00;
  58.   P5M1 = 0x00;   P5M0 = 0x00;
  59.         P6M1 = 0x00;   P6M0 = 0x00;
  60.   P7M1 = 0x00;   P7M0 = 0x00;
  61. }
  62. /*----------- Delay time ----------------*/
  63. void Delay1us(void)        //@22.1184MHz
  64. {
  65.         u8 data i;

  66.         _nop_();
  67.         i = 5;
  68.         while (--i);
  69. }

  70. void Delay60us(void)        //@22.1184MHz
  71. {
  72.         u8 data i, j;

  73.         _nop_();
  74.         _nop_();
  75.         i = 2;
  76.         j = 182;
  77.         do
  78.         {
  79.                 while (--j);
  80.         } while (--i);
  81. }

  82. void Delay480us(void)        //@22.1184MHz
  83. {
  84.         u8 data i, j;

  85.         _nop_();
  86.         i = 14;
  87.         j = 199;
  88.         do
  89.         {
  90.                 while (--j);
  91.         } while (--i);
  92. }

  93. void Delay_ms(u16 ms)
  94. {
  95.         u16 i;
  96.   do{
  97.       i = MAIN_Fosc / 10000;
  98.       while(--i);
  99.     }while(--ms);
  100. }
  101. /*-------------- UART Send byte ------------------*/
  102. void UartSend(u8 dat)
  103. {
  104.     while (busy);
  105.     busy = 1;
  106.     SBUF = dat;
  107. }
  108. /*-------------- UART Send string ------------------*/
  109. void UartSendStr(u8 *p)
  110. {
  111.     while (*p)
  112.     {
  113.         UartSend(*p++);
  114.     }
  115. }
  116. /*-------------- UART isr ------------------*/
  117. void UartIsr() interrupt 4
  118. {
  119.     if (TI)
  120.     {
  121.         TI = 0;
  122.         busy = 0;
  123.     }
  124.     if (RI)
  125.     {
  126.         RI = 0;
  127.         buffer[wptr++] = SBUF;
  128.         wptr &= 0x0f;
  129.     }
  130. }
  131. /*---------------- UART initial -----------------*/
  132. void UartInit()
  133. {
  134.     SCON = 0x50;
  135.         TMOD = 0x00;
  136.         TL1 = BRT;
  137.         TH1 = BRT>>8;
  138.         TR1 = 1;
  139.     AUXR = 0x40;
  140.     wptr = 0x00;
  141.     rptr = 0x00;
  142.     busy = 0;
  143. }
  144. /*----------- Initialize DS18B20 ----------------*/
  145. void Init_DS18B20(void)//初始化ds1820
  146. {
  147.   bit flag = 1;
  148.   while( flag )
  149.         {
  150.                 DQ = 0;                                //输出低电平
  151.                 Delay480us();
  152.                 DQ = 1;                                //输出高电平
  153.                 Delay60us();
  154.                 flag = DQ;                        //读取当前电平
  155.                 Delay480us();        
  156.         }
  157. }
  158. void DS18b20_Write_0(void)                //写逻辑0码
  159. {
  160.         DQ = 0;                                //输出低电平
  161.         Delay60us();
  162.         DQ = 1;                                //输出高电平
  163.         Delay1us();               
  164.         Delay1us();        
  165. }

  166. void DS18b20_Write_1(void)                //写逻辑1码
  167. {
  168.         DQ = 0;                                //输出低电平
  169.         Delay1us();        
  170.         Delay1us();        
  171.         DQ = 1;                                //输出高电平
  172.         Delay60us();        
  173. }
  174. /*----------- Read level ----------------*/
  175. bit DS18b20_Read(void)                //读取电平
  176. {
  177.         bit state ;
  178.         
  179.         DQ = 0;                                //输出低电平
  180.         Delay1us();        
  181.         Delay1us();        
  182.         DQ = 1;                                //输出低电平
  183.         Delay1us();        
  184.         Delay1us();        
  185.         state = DQ;                        //读取当前电平

  186.         Delay60us();

  187.         return         state;
  188. }
  189. /*----------- Write byte ----------------*/
  190. void WriteOneChar(u8 dat)//写一个字节
  191. {
  192.   u8 i;
  193.         for( i=0;i<8;i++ )                //循环八次
  194.         {
  195.                 if( dat & 0x01 )
  196.                         DS18b20_Write_1();
  197.                 else
  198.                         DS18b20_Write_0();
  199.                 dat >>=1;
  200.         }
  201. }
  202. /*----------- Read byte ----------------*/
  203. u8 ReadOneChar(void)//读一个字节
  204. {
  205.     u8 i = 0;
  206.     u8 dat = 0;
  207.     for (i=8;i>0;i--)
  208.     {
  209.       DQ = 0; // 给脉冲信号
  210.       dat >>= 1;
  211.       DQ = 1; // 给脉冲信号
  212.       if( DS18b20_Read() )        //如果读取到的是1,
  213.                         dat |= 0x80;
  214.     }
  215.     return dat;
  216. }

  217. /*----------- Start ----------------*/
  218. void Start_Convert()
  219. {
  220.         Init_DS18B20();
  221.         WriteOneChar(0xcc);
  222.         WriteOneChar(0x44);
  223. }
  224. /*----------- Read Temperature ----------------*/
  225. u16 Readtemp(void)
  226. {
  227.   u8 Low = 0;
  228.   u8 High = 0;
  229.   u16 Temper = 0; // temperature
  230.   float Tt = 0;
  231.         
  232.         Start_Convert();
  233.         while(!DQ);                                //4.等待DQ变成高电平
  234.         
  235.         Init_DS18B20();
  236.         WriteOneChar(0xCC); //跳过读序号列号的操作
  237.         WriteOneChar(0xBE); //读取温度寄存器
  238.         
  239.         Low = ReadOneChar();   //连续读两个字节数据   //读低8位
  240.         High = ReadOneChar();                          //读高8位
  241.         
  242.         if( High & 0XF8 )                                                        //有1出现就是负数
  243.         {
  244.                 MinusFlag = 1;                                                        //标志位负数
  245.                 Temper = (High<<8) | Low;                //将温度换算成16位
  246.                 Temper = (~Temper) +1;                         //按位取反+1
  247.                 Tt = Temper*0.0625;                //得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度
  248.                 Temper = Tt*10 + 0.5; //放大十倍,以便保留一位小数,并四舍五入
  249.         }
  250.         else
  251.         {
  252.                 MinusFlag = 0;                                                        //标志位正数
  253.                 Temper = (High<<8) | Low;                //将温度换算成16位
  254.                 Tt = Temper*0.0625;                //最终温度保留一位小数
  255.                 Temper = Tt*10 + 0.5;
  256.         }
  257.         return Temper;
  258. }
  259. /*----------- Display temperature ----------------*/
  260. void Display()
  261. {
  262.     u16 val;
  263.     u16 shi,ge,xiaoshu;
  264.     val = Readtemp();
  265.     shi = val/100+48;
  266.     ge = val/10%10+48;
  267.     xiaoshu = val%10+48;
  268.         if( MinusFlag==1 ) // negtive
  269.         {
  270.                 UartSendStr("Temperature: ");
  271.                 UartSend('-');
  272.     UartSend(shi);
  273.     UartSend(ge);
  274.     UartSend('.');
  275.     UartSend(xiaoshu);
  276.                 UartSendStr("\r\n");
  277.         }
  278.         else // MinusFlag==0, positive
  279.         {
  280.                 UartSendStr("Temperature: ");
  281.     UartSend(shi);
  282.     UartSend(ge);
  283.     UartSend('.');
  284.     UartSend(xiaoshu);
  285.                 UartSendStr("\r\n");
  286.         }
  287. }
复制代码
转载请注明出处和来源,如有问题请联系本人 lijinlei0907@163.com

评分

参与人数 2黑币 +55 收起 理由
STC庄伟 + 5 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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