这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » TI » 课程3+任务1+使用数码管展示DS18B20温度数据并实现高温告警功能

共6条 1/1 1 跳转至

课程3+任务1+使用数码管展示DS18B20温度数据并实现高温告警功能

菜鸟
2024-06-06 23:26:59     打赏

项目概述-任务目标

        1.采集DS18B20芯片温湿度数据

        2.数码管显示实际温度数值

        3.温度超过阈值,通过蜂鸣器报警

先上硬件框图

    

image.png

软件原理

        1.DS18B20属于单总线协议,这里有一些简要描述(来源芯片数据手册)

            作为电子工程师一定要熟练查看芯片的datasheet,原厂的资料一般比较全面

    image.png

            DS18B20采用单总线协议,通过一个单线端口通信。当全部器件经由一个三态端口或者开漏端口与总线连接的时 候,控制线需要连接一个弱上拉电阻。在这个总线系统中,微处理器(主器件)依靠每个器件独有的64位片序列号辨 认总线上的器件和记录总线上的器件地址。由于每个装置有一个唯一的片序列号,总线可以连接的器件数量实际上是 无限的。单总线协议,包括指令的详细解释和“时序”见单总线系统节。 DS18B20的另一个功能是可以在没有外部电源供电的情况下工作。当总线处于高电平状态,DQ与上拉电阻连接 通过单总线对器件供电。同时处于高电平状态的总线信号对内部电容(Cpp)充电,在总线处于低电平状态时,该电 容提供能量给器件,该提供能量的方式成为“寄生电源”。当然DS18B20可以通过VDD管脚连接外部电源供电。

企业微信截图_17175950402763.png

            DS18B20的核心功能是它的直接数字温度传感器。温度传感器的精度为用户可编程的9,10,11或12位。温度分 辨率分别为0.5℃、0.25℃、0.125℃和0.0625℃。芯片在上电状态下默认的精度为12位。DS18B20启动后保持低功耗 等待状态;当需要执行温度测量和AD转换时,总线控制器必须发出[44h]命令。在那之后,产生的温度数据以两个字节的形式被存储到温度寄存器中,DS18B20继续保持等待状态。DS18B20由外部电源供电时,总线控制器在温度转换 指令之后发起“读时序”,DS18B20正在温度转换中返回0,转换结束返回1。如果DS18B20由 寄生电源供电,除非在进入温度转换时总线被一个强上拉拉高,否则将不会有返回值。

企业微信截图_17175950903884.png

        DS18B20工作步骤

        DS18B20的工作步骤可以分为三步:

            1.初始化DS18B20
            2.执行ROM指令
            3.执行DS18B20功能指令

            其中第二步执行ROM指令,也就是访问每个DS18B20,搜索64位序列号,读取匹配的序列号值,然后匹配对应的DS18B20,如果我们仅仅使用单个DS18B20,可以直接跳过ROM指令。而跳过ROM指令的字节是0xCC。

            下图为相关功能流程图

16.jpg

       2.数码管原理

        数码管原理在课程2相关帖子中已经详细介绍,这里就不过多提及了

        3.蜂鸣器原理

        蜂鸣器分有源和无源两种

        企业微信截图_17175956251707.png

        我们手里的始于有源蜂鸣器,只需低电平就能驱动发声

            !!!蜂鸣器电源接3.3V,不要接5V,接5V会一直响,这里要注意!!!

        image.png

软件配置

    DS18B20配置

    企业微信截图_1717626920838.png

        数码管配置

企业微信截图_1717627022390.png

        蜂鸣器配置

企业微信截图_17176270738040.png

关键软件代码

 

#include "ti/driverlib/dl_gpio.h"
#include "ti/driverlib/m0p/dl_core.h"
#include "ti_msp_dl_config.h"
#include <stdint.h>

#define DS18B20_DQ_OUTH DL_GPIO_setPins(GPIO_TEMP_PORT, GPIO_TEMP_PIN_DQ_PIN)  
#define DS18B20_DQ_OUTL DL_GPIO_clearPins(GPIO_TEMP_PORT, GPIO_TEMP_PIN_DQ_PIN)  
#define DS18B20_DQ_READ DL_GPIO_readPins(GPIO_TEMP_PORT, GPIO_TEMP_PIN_DQ_PIN)  
 
#define DS18B20_DQ_IN DL_GPIO_initDigitalInput(GPIO_TEMP_PIN_DQ_IOMUX);DL_GPIO_disableOutput(GPIO_TEMP_PORT, GPIO_TEMP_PIN_DQ_PIN)  
#define DS18B20_DQ_OUT DL_GPIO_initDigitalOutput(GPIO_TEMP_PIN_DQ_IOMUX);DL_GPIO_enableOutput(GPIO_TEMP_PORT, GPIO_TEMP_PIN_DQ_PIN) 

/* 数码管相关宏定义 */
#define HC595_PORT                  (GPIO_HC595_PORT)
#define HC595_DIO_PIN               (GPIO_HC595_HC595_DIO_PIN)
#define HC595_SCLK_PIN              (GPIO_HC595_HC595_SCLK_PIN)
#define HC595_RCLK_PIN              (GPIO_HC595_HC595_RCLK_PIN)

uint8_t Disp_DX[ 16 ]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //段显
uint8_t Disp_PX[  8 ]={1,2,3,4,5,6,7,8};   //片选
#define DigitPoint 0x7F //小数点

#define HC595_DAT(x)  ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_DIO_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_DIO_PIN)))
#define HC595_CLK(x)  ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_SCLK_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_SCLK_PIN)))
#define HC595_RCK(x)  ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_RCLK_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_RCLK_PIN)))

/* 蜂鸣器相关宏定义 */
#define BeepON  DL_GPIO_clearPins(GPIO_BEEP_PORT, GPIO_BEEP_PIN_BEEP_PIN);
#define BeepOFF DL_GPIO_setPins(GPIO_BEEP_PORT, GPIO_BEEP_PIN_BEEP_PIN);

#define delay_us_cycle   32 

uint8_t  TimerCnt = 0;
uint16_t TmpVal = 999;
float realTemp = 0.0;

uint16_t testData = 0;

/* 温湿度芯片相关功能函数 */

/* 延时函数 */
void inline delay_us(uint16_t us)
{
    do{
        delay_cycles(delay_us_cycle);
    }while (us --);
}

/* 复位芯片 */
static void DS18B20_Rst(void)      
{      
    DS18B20_DQ_OUT;      
    DS18B20_DQ_OUTL;    /* 拉低DQ,复位 */      
    delay_us(750);      /* 拉低750us */      
    DS18B20_DQ_OUTH;    /* DQ=1, 释放复位 */      
    delay_us(15);       /* 延迟15US */      
}
/* 检查总线上是否存在温度芯片 */
uint8_t DS18B20_Check(void)  
{  
  uint8_t retry = 0;  
  DS18B20_DQ_IN;  
  while (DS18B20_DQ_READ && retry < 200)  
  {  
    retry++;  
    delay_us(1);  
  };  
  if (retry >= 200)  
    return 1;  
  else  
    retry = 0;  
  while (!DS18B20_DQ_READ && retry < 240)  
  {  
    retry++;  
    delay_us(1);  
  };  
  if (retry >= 240)  
    return 1;  
  return 0;  
}  
/* 芯片初始化 */
uint8_t DS18B20_Init(void)  
{  
  DS18B20_Rst();  
  return DS18B20_Check();  
}  
/* 读取单bit数据 */
uint8_t DS18B20_Read_Bit(void) // read one bit  
{  
  DS18B20_DQ_OUT;  
  uint8_t data;  
  DS18B20_DQ_OUTL;  
  delay_cycles(2 * 32);
  DS18B20_DQ_OUTH;  
  delay_cycles(12 * 32);
  DS18B20_DQ_IN;  
  if (DS18B20_DQ_READ)  
    data = 1;  
  else  
    data = 0;  
  delay_cycles(50 * 32);  
  return data;  
}  
/* 读取一字节数据 */
uint8_t DS18B20_Read_Byte(void) // read one byte  
{  
  uint8_t i, j, dat;  
  dat = 0;  
  for (i = 1; i <= 8; i++)  
  {  
    j = DS18B20_Read_Bit();  
    dat = (j << 7) | (dat >> 1);  
  }  
  return dat;  
}
/* 写入一字节数据 */
void DS18B20_Write_Byte(uint8_t dat)  
{  
  uint8_t j;  
  uint8_t testb;  
  DS18B20_DQ_OUT;  
  for (j = 1; j <= 8; j++)  
  {  
    testb = dat & 0x01;  
    dat = dat >> 1;  
    if (testb)  
    {  
      DS18B20_DQ_OUTL; // Write 1  
    //   delay_cycles(2 * 32);  
      delay_us(2);
      DS18B20_DQ_OUTH;  
    //   delay_cycles(60 * 32);  
      delay_us(60);
    }  
    else  
    {  
      DS18B20_DQ_OUTL; // Write 0  
    //   delay_cycles(60 * 32);  
      delay_us(60);
      DS18B20_DQ_OUTH;  
    //   delay_cycles(2 * 32);  
      delay_us(12);
    }  
  }  
}
/* 启动芯片 */
void DS18B20_Start(void) // ds1820 start convert  
{  
  DS18B20_Rst();  
  DS18B20_Check();  
  DS18B20_Write_Byte(0xcc); // skip rom  
  DS18B20_Write_Byte(0x44); // convert  
}

float DS18B20_Get_Temp(void)  
{  
  uint8_t temp;  
  uint8_t TL, TH;  
  int16_t tem;  
  float fValue = 0.0;
  DS18B20_Start(); // ds1820 start convert  
  DS18B20_Rst();  
  DS18B20_Check();  
  DS18B20_Write_Byte(0xcc); // skip rom  
  DS18B20_Write_Byte(0xbe); // convert  
  TL = DS18B20_Read_Byte(); // LSB  
  TH = DS18B20_Read_Byte(); // MSB  
 
  if (TH > 7)  
  {  
    TH = ~TH;  
    TL = ~TL;  
    temp = 0; // 温度为负  
  }  
  else  
    temp = 1; // 温度为正  
  tem = TH;   // 获得高八位  
  tem <<= 8;  
  tem += TL;                // 获得底八位  
  fValue = (float)tem * 0.0625; // 转换  
  if (temp)  
    return fValue; // 返回温度值  
  else  
    return -fValue;  
}


/* 数码管相关功能函数 */
/* 开启数码管输出 */
void Display_Out()
{
    HC595_RCK(0);
    delay_cycles(100);
    HC595_RCK(1);
    delay_cycles(100);
}

/* 串行数据写入 */
void HC595_WriteData(uint8_t data)
{
    uint8_t i;
    for(i = 0; i < 8; i++)
    {
        if(data&0x80)
        {
            HC595_DAT(1);
        }
        else
        {
            HC595_DAT(0);
        }
        data <<=1;
        delay_cycles(100);
        HC595_CLK(0);
        delay_cycles(100);
        HC595_CLK(1);
        delay_cycles(100);
    }
}

/* 按位点亮数码管 */
void HC595_SEND_DATA(uint8_t disp_num, uint8_t disp_bit)
{
    HC595_WriteData(disp_num);
    HC595_WriteData(1<<disp_bit);
    Display_Out();
}

void Disp_Temp(float tempValue)
{
    uint16_t tempShow;
    uint8_t num_q, num_b, num_s,num_g;

    tempShow = tempValue;
    num_q = tempShow/1000%10;
    num_b = tempShow/100%10;
    num_s = tempShow/10%10;
    num_g = tempShow%10;

    if (num_q) {
        HC595_SEND_DATA(Disp_DX[num_q],7);
    }
    if (num_q || num_b) {
        HC595_SEND_DATA(Disp_DX[num_b],6);
    }
    if (num_q || num_b || num_s) {
        HC595_SEND_DATA(Disp_DX[num_s],5);
    }
    uint8_t disData = Disp_DX[num_g] & 0x7F; //添加小数点
    HC595_SEND_DATA(disData,4);

    tempShow = (tempValue - (float)tempShow) * 10000.0;
    num_q = tempShow/1000%10;
    num_b = tempShow/100%10;
    num_s = tempShow/10%10;
    num_g = tempShow%10;

    if (tempValue) {
        HC595_SEND_DATA(Disp_DX[num_q],3);
    }
    if (tempValue || num_b) {
        HC595_SEND_DATA(Disp_DX[num_b],2);
    }
    if (tempValue || num_b || num_s) {
        HC595_SEND_DATA(Disp_DX[num_s],1);
    }
    HC595_SEND_DATA(Disp_DX[num_g],0);
}

void TIMER_0_INST_IRQHandler(void)
{
    switch(DL_Timer_getPendingInterrupt(TIMER_0_INST)){
        case DL_TIMER_IIDX_ZERO:
        TimerCnt ++;
        if(TimerCnt >= 25)
        {
            TimerCnt = 0;
            realTemp = DS18B20_Get_Temp();//温度数据一秒读取一次

            /* 温度判断 超过30读告警 */
            if (realTemp > 30.0) {
                BeepON;
            }
            else {
                BeepOFF;
            }
        }
        break;

        default:
            break;
    }
}

int main(void)
{
    /* Power on GPIO, initialize pins as digital outputs */
    SYSCFG_DL_init();

    DL_GPIO_setPins(GPIO_BEEP_PORT, GPIO_BEEP_PIN_BEEP_PIN);

    NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);

    while (1) {
        Disp_Temp(realTemp);
    }
}

    运行效果图:

47998b30180daca81d6f31d6194ea2c3.jpg

77b560f6af5704630e6173a50e11963e.jpg


专家
2024-06-07 01:22:53     打赏
2楼

感谢楼主分享


高工
2024-06-07 07:42:46     打赏
3楼

感谢楼主分享


专家
2024-06-07 07:58:45     打赏
4楼

感谢分享


高工
2024-06-07 09:26:07     打赏
5楼

感谢楼主分享


专家
2024-06-10 16:38:21     打赏
6楼

感谢分享


共6条 1/1 1 跳转至

回复

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