[CW32F030系列] 【CW32F030FxPx StartKit开发板】DS18B20通过串口与QT上位机通信

[复制链接]
 楼主| 新曲难觅旧知音 发表于 2024-6-17 14:06 | 显示全部楼层 |阅读模式
本帖最后由 新曲难觅旧知音 于 2024-6-17 15:31 编辑

#申请原创#@21小跑堂
最近这里气温实在是太高了,所以打算做个东西放外面实时监测现在的温度,
计划实现多平台数据显示,能够实时查看当前温度。后续打算增加联网及温度报警功能

首先安装keil的扩展包,官网翻了一下发现合并在库文件的压缩包里了
本次要用到串口和GPIO,又是第一次用这个系列的芯片找个串口的例程打开先跑一下,了解下CW32的库。
75ffdb7a732b1e0241bb42247cc7d62f
编译下载一气呵成。结果一点反应没有
原来开发板设计时候每个电路都是独立的,串口并没有默认连接到芯片。
翻看下芯片的数据手册还发现我手上这个封装的型号没有uart1,例程默认使用的uart1,把程序全部替换成uart2,之后下载编译
f8f693f62d928c59e6048374074f7b35
打开串口助手,可以看到例程信息就打印出来了
a0b2dcefcacc969cdbdf98e443e0ba72
例程跑通后就可以开始今天的正题了。
先实现DS18B20的驱动。网上随便找个模板,然后移植一下
1e66d991d8fcf22aece84720bb24e9cf
很简单实现几个宏定义就可以了。这里延时需要用到us级的延时。
我看cw的库里提供了好几个不同长度的延时函数
cdb1c5cf63e23a2f9c121a63e76d8ee2
不得不说确实方便。
  1. #ifndef _DS18B20_H_
  2. #define _DS18B20_H_

  3. #include "main.h"
  4. #include "cw32f030_gpio.h"

  5. /*  DS18B20时钟端口、引脚定义 */
  6. #define DS18B20_PORT                         CW_GPIOA  
  7. #define DS18B20_PIN                         (GPIO_PIN_9)
  8. #define DS18B20_PORT_RCC                RCC_AHB_PERIPH_GPIOA

  9. #define DS18B20_DQ_OUT_HIGHT()                         GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_Pin_SET)
  10. #define DS18B20_DQ_OUT_LOW()                                 GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_Pin_RESET)

  11. #define        DS18B20_DQ_IN  GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN)

  12. #define        DS18B20_Delay_us(xus)  FirmwareDelay(xus)
  13.             
  14.            
  15. uint8_t DS18B20_Init(void);                        //初始化DS18B20
  16. float DS18B20_GetTemperture(void);        //获取温度
  17. void DS18B20_Start(void);                //开始温度转换
  18. void DS18B20_Write_Byte(uint8_t dat);//写入一个字节
  19. uint8_t DS18B20_Read_Byte(void);                //读出一个字节
  20. uint8_t DS18B20_Read_Bit(void);                //读出一个位
  21. uint8_t DS18B20_Check(void);                        //检测是否存在DS18B20
  22. void DS18B20_Reset(void);                        //复位DS18B20   

  23. #endif
DS18B20.h

  1. #include "ds18b20.h"

  2. /*******************************************************************************
  3. * 函 数 名         : DS18B20_IO_IN
  4. * 函数功能                   : DS18B20_IO输入配置           
  5. * 输    入         : 无
  6. * 输    出         : 无
  7. *******************************************************************************/
  8. void DS18B20_IO_IN(void)
  9. {
  10.         GPIO_InitTypeDef GPIO_InitStruct;
  11.         
  12.         GPIO_InitStruct.Pins = DS18B20_PIN;
  13.         GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  14.         GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);
  15. }

  16. /*******************************************************************************
  17. * 函 数 名         : DS18B20_IO_OUT
  18. * 函数功能                   : DS18B20_IO输出配置           
  19. * 输    入         : 无
  20. * 输    出         : 无
  21. *******************************************************************************/
  22. void DS18B20_IO_OUT(void)
  23. {
  24.         GPIO_InitTypeDef GPIO_InitStructure;

  25.     GPIO_InitStructure.Pins = DS18B20_PIN;
  26.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  27.     GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  28.     GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
  29. }

  30. /*******************************************************************************
  31. * 函 数 名         : DS18B20_Reset
  32. * 函数功能                   : 复位DS18B20  
  33. * 输    入         : 无
  34. * 输    出         : 无
  35. *******************************************************************************/
  36. void DS18B20_Reset(void)           
  37. {                 
  38.         DS18B20_IO_OUT(); //SET PG11 OUTPUT
  39.         DS18B20_DQ_OUT_LOW(); //拉低DQ
  40.         DS18B20_Delay_us(750);    //拉低750us
  41.         DS18B20_DQ_OUT_HIGHT(); //DQ=1
  42.         DS18B20_Delay_us(15);     //15US
  43. }

  44. /*******************************************************************************
  45. * 函 数 名         : DS18B20_Check
  46. * 函数功能                   : 检测DS18B20是否存在
  47. * 输    入         : 无
  48. * 输    出         : 1:未检测到DS18B20的存在,0:存在
  49. *******************************************************************************/
  50. uint8_t DS18B20_Check(void)            
  51. {   
  52.         uint8_t retry=0;
  53.         DS18B20_IO_IN();//SET PG11 INPUT         
  54.         
  55.         while (DS18B20_DQ_IN&&retry<200)
  56.         {
  57.                 retry++;
  58.                 DS18B20_Delay_us(1);
  59.         };
  60.         
  61.         if(retry>=200)
  62.                 return 1;
  63.         else
  64.                 retry=0;
  65.         
  66.         while (!DS18B20_DQ_IN&&retry<240)
  67.         {
  68.                 retry++;
  69.                 DS18B20_Delay_us(1);
  70.         };
  71.         if(retry>=240)
  72.                 return 1;         
  73.         
  74.         return 0;
  75. }

  76. /*******************************************************************************
  77. * 函 数 名         : DS18B20_Read_Bit
  78. * 函数功能                   : 从DS18B20读取一个位
  79. * 输    入         : 无
  80. * 输    出         : 1/0
  81. *******************************************************************************/
  82. uint8_t DS18B20_Read_Bit(void)                          // read one bit
  83. {
  84.         uint8_t data;
  85.         DS18B20_IO_OUT();//SET PG11 OUTPUT
  86.         DS18B20_DQ_OUT_LOW();
  87.         DS18B20_Delay_us(2);
  88.         DS18B20_DQ_OUT_HIGHT();
  89.         DS18B20_IO_IN();//SET PG11 INPUT
  90.         DS18B20_Delay_us(12);
  91.         
  92.         if(DS18B20_DQ_IN)
  93.                 data=1;
  94.         else
  95.                 data=0;         
  96.         
  97.         DS18B20_Delay_us(50);  
  98.         
  99.         return data;
  100. }

  101. /*******************************************************************************
  102. * 函 数 名         : DS18B20_Read_Byte
  103. * 函数功能                   : 从DS18B20读取一个字节
  104. * 输    入         : 无
  105. * 输    出         : 一个字节数据
  106. *******************************************************************************/
  107. uint8_t DS18B20_Read_Byte(void)    // read one byte
  108. {        
  109.         uint8_t i,j,dat;
  110.         dat=0;
  111.         for (i=1;i<=8;i++)
  112.         {
  113.                 j=DS18B20_Read_Bit();
  114.                 dat=(j<<7)|(dat>>1);
  115.         }                                                   
  116.         return dat;
  117. }

  118. /*******************************************************************************
  119. * 函 数 名         : DS18B20_Write_Byte
  120. * 函数功能                   : 写一个字节到DS18B20
  121. * 输    入         : dat:要写入的字节
  122. * 输    出         : 无
  123. *******************************************************************************/
  124. void DS18B20_Write_Byte(uint8_t dat)     
  125. {            
  126.         uint8_t j;
  127.         uint8_t testb;
  128.         DS18B20_IO_OUT();//SET PG11 OUTPUT;
  129.         for (j=1;j<=8;j++)
  130.         {
  131.                 testb=dat&0x01;
  132.                 dat=dat>>1;
  133.                 if (testb)
  134.                 {
  135.                         DS18B20_DQ_OUT_LOW();// Write 1
  136.                         DS18B20_Delay_us(2);                           
  137.                         DS18B20_DQ_OUT_HIGHT();
  138.                         DS18B20_Delay_us(60);            
  139.                 }
  140.                 else
  141.                 {
  142.                         DS18B20_DQ_OUT_LOW();// Write 0
  143.                         DS18B20_Delay_us(60);            
  144.                         DS18B20_DQ_OUT_HIGHT();
  145.                         DS18B20_Delay_us(2);                          
  146.                 }
  147.         }
  148. }

  149. /*******************************************************************************
  150. * 函 数 名         : DS18B20_Start
  151. * 函数功能                   : 开始温度转换
  152. * 输    入         : 无
  153. * 输    出         : 无
  154. *******************************************************************************/
  155. void DS18B20_Start(void)// ds1820 start convert
  156. {                                                                  
  157.         DS18B20_Reset();           
  158.         DS18B20_Check();         
  159.         DS18B20_Write_Byte(0xcc);// skip rom
  160.         DS18B20_Write_Byte(0x44);// convert
  161. }

  162. /*******************************************************************************
  163. * 函 数 名         : DS18B20_Init
  164. * 函数功能                   : 初始化DS18B20的IO口 DQ 同时检测DS的存在
  165. * 输    入         : 无
  166. * 输    出         : 1:不存在,0:存在
  167. *******************************************************************************/            
  168. uint8_t DS18B20_Init(void)
  169. {
  170.         GPIO_InitTypeDef  GPIO_InitStructure;

  171.         RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA, ENABLE);
  172.         
  173.         //GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
  174.         
  175.         GPIO_InitStructure.Pins=DS18B20_PIN;
  176.         GPIO_InitStructure.Speed=GPIO_SPEED_HIGH;
  177.         GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP;
  178.         GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);

  179.          DS18B20_Reset();
  180.         return DS18B20_Check();
  181. }  

  182. /*******************************************************************************
  183. * 函 数 名         : DS18B20_GetTemperture
  184. * 函数功能                   : 从ds18b20得到温度值
  185. * 输    入         : 无
  186. * 输    出         : 温度数据
  187. *******************************************************************************/
  188. float DS18B20_GetTemperture(void)
  189. {
  190.         uint16_t temp;
  191.         uint8_t a,b;
  192.         float value;
  193.         
  194.         DS18B20_Start();                    // ds1820 start convert
  195.         DS18B20_Reset();
  196.         DS18B20_Check();         
  197.         DS18B20_Write_Byte(0xcc);// skip rom
  198.         DS18B20_Write_Byte(0xbe);// convert            
  199.         a=DS18B20_Read_Byte(); // LSB   
  200.         b=DS18B20_Read_Byte(); // MSB   
  201.         temp=b;
  202.         temp=(temp<<8)+a;
  203.         
  204.         if((temp&0xf800)==0xf800)
  205.         {
  206.                 temp=(~temp)+1;
  207.                 value=temp*(-0.0625);
  208.         }
  209.         else
  210.         {
  211.                 value=temp*0.0625;        
  212.         }
  213.         return value;   
  214. }
DS18B20.c


主函数这边写的就非常简单了
7b41cfa45dd76c6ced6ee3bf05f99026
这里发送浮点数的方法有好多种实现。
最开始用的共用体,然后把float当成四个char,然后再依次发送出去。
后来感觉那样代码就多好多行,看着不爽就改成用sprintf构造字符串再发送。
a5b517657056cf6fbddd362e07df6dd3
共用体就这样实现的,因为用的确实不多。相比之下sprintf就常见多了。
连上串口看一下打印数据
874f8839616f240d36d3fb84eede6d3c
串口助手正常输出温度
至此下位机部分基本就差不多了,然后就是上位机制作过程了。
这里参考的是github上一个开源的QT上位机
先把上位机代码克隆下来,原工程用的是QT5,我这里是最新的QT6.7.1,年轻人嘛就是喜欢追求新东西。
因为新版本舍弃了很多东西,所以整个工程会报非常多错误。
剩下的就是一点点改错的过程了。
先用设计师查看下界面
2d00f3836a655958e1b5b16fe69af08e 7e9efd7a04325cd95a77b6f3574dc506
UI设计是真的麻烦,不过基本该有的功能都有了。
然后代码部分,在pro文件里添加serialport和charts两个模块。初次使用需要先在Qt Maintenance Tool里下载相应模块。
编译看下现象,连接串口
aaa.png




程序.zip

29.78 KB, 下载次数: 9

huquanz711 发表于 2024-6-17 20:54 来自手机 | 显示全部楼层
现在用QT开发上位机软件的越来越多了,支持跨平台。
小夏天的大西瓜 发表于 2024-6-17 22:05 | 显示全部楼层
串口调试助手还有曲线?非常实用
OKAKAKO 发表于 2024-6-21 21:17 | 显示全部楼层
QT现在也是经典IDE
中国龙芯CDX 发表于 2024-6-26 16:38 | 显示全部楼层
DS18B20可以直接通过串口与QT上位机连接的
jf101 发表于 2024-6-27 16:54 | 显示全部楼层
DS18B20是模拟的通讯方式?
 楼主| 新曲难觅旧知音 发表于 2024-6-27 17:53 | 显示全部楼层
jf101 发表于 2024-6-27 16:54
DS18B20是模拟的通讯方式?

单总线
 楼主| 新曲难觅旧知音 发表于 2024-6-27 17:54 | 显示全部楼层
中国龙芯CDX 发表于 2024-6-26 16:38
DS18B20可以直接通过串口与QT上位机连接的

有机会试一下,只是听说过可以
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

144

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部