这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » TI » 【MSP焕新大作战】+课程3+18B20温度采集和显示

共4条 1/1 1 跳转至

【MSP焕新大作战】+课程3+18B20温度采集和显示

高工
2024-08-06 23:19:03     打赏

本节实现通过18B20温度传感器模块采集温度,通过数码管模块显示,超限通过蜂鸣器报警。

image.png

这次的蜂鸣器是有源蜂鸣器,低电平触发。

配置IO口状态

image.png

DS18B20是一种具有高精度、数字输出和单总线通信数字温度传感器,可以提供9位温度读  数。数字输出:DS18B20以数字形式输出温度数据,使得温度测量更为准确和方便。

image.png

高精度:DS18B20具有较高的温度测量精度,通常为±0.5°C单总线通信:DS18B20采用1-Wire总线协议进行通信,只需要一条数据线就可以完成通信和供电,简化了连接方式。

多种封装形式:DS18B20可提供不同的封装形式,包括TO-92TO-220SMD等,以适应不同的应用场景。

低功耗:DS18B20在工作时的功耗较低,适合于一些对电源要求较为严格的应用。


数字校准:DS18B20内置了温度校准寄存器,可以通过软件进行校准,提高了温度测量的准确性。

DS18B20使用的是1-Wire协议进行通讯,1-Wire是一种串行通信协议,用于在单一数据线上进行通信和供电。它由独特的通信方式和协议约定组成,广泛应用于各种数字设备和传感器之间的通信。具体协议坛友已经写了很多,就不在这里重复了。

将模块连接到开发板

image.png

使用CCS进行编程,参考坛友的编写DS18B20驱动函数

温度超限比对,蜂鸣器驱动程序


  1. #include "ti_msp_dl_config.h"  

  2. #include <math.h>  

  3. #define DS18B20_DQ_IN_Read() DL_GPIO_readPins(PORT_TempSensor_PORT,PORT_TempSensor_PIN_TempSensor_PIN)  

  4. #define delay_us 32  

  5. #define NUM_MAXLENGTH 8  

  6. uint8_t Num_List[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf};//数码管数字  

  7. volatile float temp=0.0;  

  8. uint8_t Reserved_points=4;   //默认保留4位小数  

  9. uint8_t temp_level[]={28,29};//三档温度报警  

  10.   

  11. /** 

  12.  *  @brief      DS18B20时钟上升沿配置 

  13.  * 

  14.  *  @param[in]  外设端口PORTx、延时t1、延时t2 

  15.  * 

  16.  */  

  17. void DS18B20_OneWireRisingEdge_Config(GPIO_Regs* PORTx,uint32_t PINx,uint32_t t1,uint32_t t2){  

  18.         DL_GPIO_clearPins(PORTx, PINx);  

  19.         delay_cycles(delay_us*t1);  

  20.         DL_GPIO_setPins(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);  

  21.         delay_cycles(delay_us*t2);  

  22. }  

  23. /** 

  24.  *  @brief      单总线配置为输入模式 

  25.  * 

  26.  *  @param[in]  None 

  27.  * 

  28.  */  

  29. void DS18B20_DQ_IN(){           //配置通信引脚为输入模式  

  30.         DL_GPIO_disableOutput(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);  

  31.         DL_GPIO_initDigitalInput(PORT_TempSensor_PIN_TempSensor_IOMUX);  

  32.         DL_GPIO_setPins(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);  

  33.         DL_GPIO_enableOutput(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);  

  34. }  

  35. /** 

  36.  *  @brief      单总线配置为输出模式 

  37.  * 

  38.  *  @param[in]  None 

  39.  * 

  40.  */  

  41. void DS18B20_DQ_OUT(){          //配置通信引脚为输出模式  

  42.         DL_GPIO_disableOutput(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);  

  43.         DL_GPIO_initDigitalOutput(PORT_TempSensor_PIN_TempSensor_IOMUX);  

  44.         DL_GPIO_setPins(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);  

  45.         DL_GPIO_enableOutput(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);  

  46. }  

  47. /** 

  48.  *  @brief      复位DS18B20 

  49.  * 

  50.  *  @param[in]  None 

  51.  * 

  52.  */  

  53. void DS18B20_RESET(){  

  54.         DS18B20_DQ_OUT();  

  55.         DS18B20_OneWireRisingEdge_Config(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN,750,60);  

  56. }  

  57. /** 

  58.  *  @brief      判断DS18B20是否存在 

  59.  * 

  60.  *  @param[in]  None 

  61.  * 

  62.  */  

  63. uint8_t DS18B20_CHECK(){  

  64.         uint8_t counters=0;  

  65.         DS18B20_DQ_IN();  

  66.         while(DS18B20_DQ_IN_Read()&&counters<200){  

  67.             counters++;  

  68.             delay_cycles(delay_us*1);  

  69.         }  

  70.         if(counters>100)        //超时未检测到器件,返回1  

  71.             return 1;  

  72.         else  

  73.             counters=0;  

  74.         while(!(DS18B20_DQ_IN_Read())&&counters<240){  

  75.             counters++;  

  76.             delay_cycles(delay_us*1);  

  77.         }  

  78.   

  79.         if(counters>240)        //检测到器件但总线电平持续拉低,返回2  

  80.             return 2;  

  81.         else  

  82.     //        DL_UART_transmitData(UART_0_INST,counters);  

  83.             return 0;           //检测到器件且总线电平有效,返回0  

  84. }  

  85. /** 

  86.  *  @brief      向DS18B20写入字节数据 

  87.  * 

  88.  *  @param[in]  data字节数据 

  89.  * 

  90.  */  

  91. void DS18B20_WRITE_Byte(uint8_t data){  

  92.         uint8_t byte=data;  

  93.         DS18B20_DQ_OUT();  

  94.         for(uint8_t i=1;i<=8;i++){  

  95.             if(byte&0x01){  

  96.                 DS18B20_OneWireRisingEdge_Config(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN,2,60);  

  97.             }  

  98.             else{  

  99.                 DS18B20_OneWireRisingEdge_Config(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN,60,2);  

  100.             }  

  101.             byte=byte>>1;  

  102.         }  

  103. }  

  104. /** 

  105.  *  @brief      从DS18B20读取比特数据 

  106.  * 

  107.  *  @param[in]  None 

  108.  * 

  109.  */  

  110. uint8_t DS18B20_READ_Bit(){  

  111.         uint8_t bit;  

  112.         DS18B20_DQ_OUT();  

  113.         DS18B20_OneWireRisingEdge_Config(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN,2,5);  

  114.         DS18B20_DQ_IN();  

  115.         delay_cycles(delay_us*12);  

  116.         if(DS18B20_DQ_IN_Read())  

  117.             bit=1;  

  118.         else  

  119.             bit=0;  

  120.         delay_cycles(delay_us*50);  

  121.         return bit;  

  122. }  

  123. /** 

  124.  *  @brief      从DS18B20读取字节数据 

  125.  * 

  126.  *  @param[in]  None 

  127.  * 

  128.  */  

  129. uint8_t DS18B20_READ_Byte(){  

  130.         uint8_t bit=0;  

  131.         uint8_t byte=0;  

  132.         for(uint8_t i=1;i<=8;i++){  

  133.             bit=DS18B20_READ_Bit();  

  134.             byte|=bit<<(i-1);  

  135.         }  

  136.         return byte;  

  137. }  

  138. /** 

  139.  *  @brief      启用DS18B20 

  140.  * 

  141.  *  @param[in]  None 

  142.  * 

  143.  */  

  144. void DS18B20_START(void){  

  145.         DS18B20_RESET();  

  146.         DS18B20_CHECK();  

  147.         DS18B20_WRITE_Byte(0xcc);  

  148.         DS18B20_WRITE_Byte(0x44);  

  149.         DS18B20_RESET();  

  150.         DS18B20_CHECK();  

  151.         DS18B20_WRITE_Byte(0xcc);  

  152.         DS18B20_WRITE_Byte(0xbe);  

  153. }  

  154. /** 

  155.  *  @brief      初始化DS18B20 

  156.  * 

  157.  *  @param[in]  None 

  158.  * 

  159.  */  

  160. uint8_t DS18B20_INIT(void){  

  161.         DS18B20_RESET();  

  162.         return DS18B20_CHECK();  

  163. }  

  164. /** 

  165.  *  @brief      获取DS18B20温度数据(小数点数据) 

  166.  * 

  167.  *  @param[in]  None 

  168.  * 

  169.  */  

  170. float DS18B20_GetTemp(void){  

  171.         float temp_value=0.0;  

  172.         uint8_t temp_msb,temp_lsb=0;  

  173.         uint16_t temp=0;  

  174.   

  175.         DS18B20_START();                //采样温度值  

  176.         temp_lsb=DS18B20_READ_Byte();  

  177.         temp_msb=DS18B20_READ_Byte();  

  178.         temp=(temp_msb<<8)+temp_lsb;  

  179.         if((temp&0xF800)==0xF800){      //高5位为1表示负温度  

  180.             temp=(~temp)+1;             //将补码取反运算+1得到负温值  

  181.             temp_value=temp*(-0.0625);  

  182.         }  

  183.         else  

  184.             temp_value=temp*0.0625;  

  185.         return temp_value;  

  186. }  

  187. /** 

  188.  *  @brief      HC595时钟上升沿配置 

  189.  * 

  190.  *  @param[in]  外设端口PORTx、延时t1、延时t2 

  191.  * 

  192.  */  

  193. void HC595_CLKRisingEdge_Config(GPIO_Regs* PORTx,uint32_t PINx,uint32_t t1,uint32_t t2){  

  194.         DL_GPIO_clearPins(PORTx, PINx);  

  195.         delay_cycles(delay_us*t1);  

  196.         DL_GPIO_setPins(PORTx, PINx);  

  197.         delay_cycles(delay_us*t2);  

  198. }  

  199. /** 

  200.  *  @brief      HC595写入字节数据 

  201.  * 

  202.  *  @param[in]  byte字节数据 

  203.  * 

  204.  */  

  205. void LED_Segment_WriteByte(uint8_t byte){  

  206.     for(uint8_t i=1;i<=8;i++){  

  207.         if(byte&0x80){  

  208.             DL_GPIO_setPins(PORT_HC595_PORT,PORT_HC595_PIN_HC595_DIO_PIN);  

  209.         }  

  210.         else  

  211.         {  

  212.             DL_GPIO_clearPins(PORT_HC595_PORT,PORT_HC595_PIN_HC595_DIO_PIN);  

  213.         }  

  214.         HC595_CLKRisingEdge_Config(PORT_HC595_PORT,PORT_HC595_PIN_HC595_SCLK_PIN,2,2);  

  215.         byte<<=1;  

  216.     }  

  217. }  

  218. /** 

  219.  *  @brief      数码管显示1位数字 

  220.  * 

  221.  *  @param[in]  Num_one数字,index显示位置 

  222.  * 

  223.  */  

  224. void LED_Segment_Display_Num_One(uint8_t Num_one,uint8_t index){  

  225.   

  226.     LED_Segment_WriteByte(Num_List[Num_one]);  

  227.     LED_Segment_WriteByte(1<<index);  

  228.     HC595_CLKRisingEdge_Config(PORT_HC595_PORT,PORT_HC595_PIN_HC595_RCLK_PIN,2,2);  

  229. }  

  230. /** 

  231.  *  @brief      数码管显示数字处理 

  232.  * 

  233.  *  @param[in]  Num数字 

  234.  * 

  235.  */  

  236. void Num_LED_Segment_Process(uint32_t Num){  

  237.     uint8_t num_lsb=0;  

  238.     uint8_t i;  

  239.     for(i=0;i<NUM_MAXLENGTH;i++)  

  240.     {  

  241.         num_lsb=Num%10;  

  242.         Num/=10;  

  243.         LED_Segment_Display_Num_One(num_lsb,i);  

  244.         if(Num==0)break;  

  245.     }  

  246. }  

  247. /** 

  248.  *  @brief      数码管显示浮点数处理 

  249.  * 

  250.  *  @param[in]  Num数字,Reserved_points保留小数点位数 

  251.  * 

  252.  */  

  253. void Num_LED_Segment_Process_Float(float Num,uint8_t Reserved_points){//处理数码管显示浮点数,Reserved_points为保留小数点后几位  

  254.         int Num_int=Num*pow(10,Reserved_points+1);  

  255.   

  256.         if(Num_int%10>=5)//四舍五入  

  257.             Num_int=Num_int/10+1;  

  258.         else  

  259.             Num_int=Num_int/10;  

  260.         if(Reserved_points==0)  

  261.             Num_LED_Segment_Process(Num_int);  

  262.         else  

  263.         {  

  264.             Num_LED_Segment_Process(Num_int);  

  265.             LED_Segment_Display_point(0x7f,Reserved_points);  

  266.             LED_Segment_Display_point(0xff,Reserved_points);  

  267.             LED_Segment_Display_point(0xff,Reserved_points);  

  268.         }  

  269. }  

  270. int main(void)  

  271. {  

  272.         SYSCFG_DL_init();  

  273.   

  274.         NVIC_SetPriority(TIMER_0_INST_INT_IRQN, 2);  

  275.         NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);  

  276.         DL_TimerG_startCounter(TIMER_0_INST);//定时刷新数码管显示  

  277.   

  278.         NVIC_SetPriority(TIMER_1_INST_INT_IRQN, 0);  

  279.         NVIC_EnableIRQ(TIMER_1_INST_INT_IRQN);  

  280.         DL_TimerG_startCounter(TIMER_1_INST);  

  281.   

  282.         while (1) {  

  283. //            Num_LED_Segment_Process_Float(temp,Reserved_points);  

  284.             delay_cycles(delay_us*500);  

  285.         }  

  286. }  

  287. /** 

  288.  *  @brief      定时器0中断回调函数 

  289.  * 

  290.  *  @param[in]  None 

  291.  * 

  292.  */  

  293. void TIMER_0_INST_IRQHandler(void)  

  294. {  

  295.     Num_LED_Segment_Process_Float(temp,Reserved_points);  

  296.     Num_LED_Segment_Process_Float(temp,Reserved_points);  

  297.     Num_LED_Segment_Process_Float(temp,Reserved_points);  

  298.     Num_LED_Segment_Process_Float(temp,Reserved_points);  

  299. //    switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) {  

  300. //        case DL_TIMER_IIDX_ZERO:  

  301. //            Num_LED_Segment_Process_Float(temp,Reserved_points);  

  302. //            break;  

  303. //        default:  

  304. //            break;  

  305. //    }  

  306. }  

  307. /** 

  308.  *  @brief      定时器1中断回调函数 

  309.  * 

  310.  *  @param[in]  None 

  311.  * 

  312.  */  

  313. void TIMER_1_INST_IRQHandler(void)  

  314. {  

  315.     if(DS18B20_INIT()==0){  

  316.         temp=DS18B20_GetTemp();  

  317.         if(temp<temp_level[0]){  

  318.             DL_GPIO_setPins(PORT_BEEP_PORT,PORT_BEEP_PIN__BEEP_PIN);  

  319.         }  

  320.         else if(temp>=temp_level[0]&&temp<temp_level[1]){  

  321.             DL_GPIO_togglePins(PORT_BEEP_PORT,PORT_BEEP_PIN__BEEP_PIN);  

  322.         }  

  323.         else {  

  324.             DL_GPIO_clearPins(PORT_BEEP_PORT,PORT_BEEP_PIN__BEEP_PIN);  

  325.         }  

  326.     }  

  327.     else{  

  328.         temp=0.1000;  

  329.         DL_GPIO_setPins(PORT_BEEP_PORT,PORT_BEEP_PIN__BEEP_PIN);  

  330.         delay_cycles(delay_us*1000);//温度传感器不存在、异常,LED_Red不断闪烁  

  331.         DL_GPIO_togglePins(PORT_LED_Red_PORT,PORT_LED_Red_PIN_LED_Red_PIN);  

  332.     }  

  333.   

  334. //    switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) {  

  335. //        case DL_TIMER_IIDX_ZERO:  

  336. //            Num_LED_Segment_Process_Float(temp,Reserved_points);  

  337. //            break;  

  338. //        default:  

  339. //            break;  

  340. //    }  

  341. }  


运行结果如图

image.png


工程师
2024-08-07 00:25:08     打赏
2楼
温度采集和显示



高工
2024-08-07 10:34:54     打赏
3楼

这小图片,是从哪里截图过来啊?!


菜鸟
2024-08-11 16:15:18     打赏
4楼

谢谢分享,学习了。


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]