这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » TI » 【MSP焕新大作战】课程3+任务1+温度报警器

共2条 1/1 1 跳转至

【MSP焕新大作战】课程3+任务1+温度报警器

工程师
2024-05-30 11:36:34     打赏

0.任务目标

DS18B20实现环境温度的采样,用数码管显示,并实现高温蜂鸣器报警

1. 硬件原理  

用到数码管,蜂鸣器,和DS18B20 数字温度传感器。  

原理图.png

蜂鸣器工作原理  

蜂鸣器分为有源和无源。这里的“源”不是指电源,而是指震荡源。也就是说,有源蜂鸣器内部带震荡源,所以只要一通电就会叫。而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。必须用2K~5K的方波去驱动它。有源蜂鸣器往往比无源的贵,就是因为里面多个震荡电路。  

beep.png

DS18B20 工作原理  

单总线接口:只需要一条数据线即可完成数据的发送和接收,外加一条接地线和电源线。  

温度范围:测量范围通常是-55°C 到 +125°C,具有较高的精度,在-10°C到+85°C范围内误差为±0.5°C。分辨率:可设置为9位到12位,对应的温度分辨率从0.5°C到0.0625°C。自带ROM:每个DS18B20都有一个独一无二的64位序列号,便于在单总线上挂接多个设备。  

所有的单总线器件要求采用严格的信号时序,以保证数据的完整性。DS18B20 共有 6 种信  

号类型:复位脉冲、应答脉冲、写 0、写 1、读 0 和读 1。所有这些信号,除了应答脉冲以外, 都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。  

这里我们简单介绍 这几个信号的时序。  

1)复位脉冲和应答脉冲  

单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少 480  

us,,以产生复位脉冲。接着主机释放总线,4.7K 的上拉电阻将单总线拉高,延时 15~60 us,并进入接收模式(Rx)。接着 DS18B20 拉低总线 60~240 us,以产生低电平应答脉冲,  

若为低电平,再延时 480 us。  

2)写时序  

写时序包括写 0 时序和写 1 时序。所有写时序至少需要 60us,且在 2 次独立的写时序之间 至少需要 1us 的恢复时间,两种写时序均起始于主机拉低总线。写 1 时序:主机输出低电平, 延时 2us,然后释放总线,延时 60us。写 0 时序:主机输出低电平,延时 60us,然后释放总线,延时 2us。  

3)读时序  

单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,  

必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要 60us,且在 2 次独立的读时序之间至少需要 1us 的恢复时间。每个读时序都由主机发起,至少拉低总线 1us。主机在读 时序期间必须释放总线,并且在时序起始后的 15us 之内采样总线状态。典型的读时序过程为:  

主机输出低电平延时 2us,然后主机转入输入模式延时 12us,然后读取单总线当前的电平,然后延时 50us。  

在了解了单总线时序之后,我们来看看 DS18B20 的典型温度读取过程,DS18B20 的典型  

温度读取过程为:复位à发 SKIP ROM 命令(0XCC)à发开始转换命令(0X44)à延时à复位à发送 SKIP ROM 命令(0XCC)à发读存储器命令(0XBE)à连续读出两个字节数据(即温度)à结束。  

2. 软件关键代码  

软件配置:  

  
#define PORT_TempSensor_PORT  (GPIOA)
 
#define PORT_TempSensor_PIN_TempSensor_PIN (DL_GPIO_PIN_17)
 
#define PORT_TempSensor_PIN_TempSensor_IOMUX (IOMUX_PINCM18)
 
#define PORT_BEEP_PORT       (GPIOA)
#define PORT_BEEP_PIN__BEEP_PIN (DL_GPIO_PIN_15)
 
#define PORT_LED_Red_PORT    (GPIOA)
#define PORT_LED_Red_PIN_LED_Red_PIN   (DL_GPIO_PIN_0)
#define DS18B20_DQ_IN_Read()  DL_GPIO_readPins(PORT_TempSensor_PORT,PORT_TempSensor_PIN_TempSensor_PIN)
 
#define delay_us   32
 
 
 
/**
 *  @brief      单总线配置为输入模式
 *
 *  @param[in]  None
 *
 */
void DS18B20_DQ_IN(){           //配置通信引脚为输入模式
        DL_GPIO_disableOutput(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);
        DL_GPIO_initDigitalInput(PORT_TempSensor_PIN_TempSensor_IOMUX);
        DL_GPIO_setPins(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);
        DL_GPIO_enableOutput(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);
}
 
/**
 *  @brief      单总线配置为输出模式
 *
 *  @param[in]  None
 *
 */
void DS18B20_DQ_OUT(){          //配置通信引脚为输出模式
        DL_GPIO_disableOutput(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);
        DL_GPIO_initDigitalOutput(PORT_TempSensor_PIN_TempSensor_IOMUX);
        DL_GPIO_setPins(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);
        DL_GPIO_enableOutput(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);
}
 
void DS18B20_OneWireRisingEdge_Config(GPIO_Regs* PORTx,uint32_t PINx,uint32_t t1,uint32_t t2){
        DL_GPIO_clearPins(PORTx, PINx);
        delay_cycles(delay_us*t1);
        DL_GPIO_setPins(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN);
        delay_cycles(delay_us*t2);
}
 
/**
 *  @brief      向DS18B20写入字节数据
 *
 *  @param[in]  data字节数据
 *
 */
void DS18B20_WRITE_Byte(uint8_t data){
        uint8_t byte=data;
        DS18B20_DQ_OUT();
        for(uint8_t i=1;i<=8;i++){
            if(byte&0x01){
                DS18B20_OneWireRisingEdge_Config(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN,2,60);
            }
            else{
                DS18B20_OneWireRisingEdge_Config(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN,60,2);
            }
            byte=byte>>1;
        }
}
/**
 *  @brief      从DS18B20读取比特数据
 *
 *  @param[in]  None
 *
 */
uint8_t DS18B20_READ_Bit(){
        uint8_t bit;
        DS18B20_DQ_OUT();
        DS18B20_OneWireRisingEdge_Config(PORT_TempSensor_PORT, PORT_TempSensor_PIN_TempSensor_PIN,2,5);
        DS18B20_DQ_IN();
        delay_cycles(delay_us*12);
        if(DS18B20_DQ_IN_Read())
            bit=1;
        else
            bit=0;
        delay_cycles(delay_us*50);
        return bit;
}
/**
 *  @brief      从DS18B20读取字节数据
 *
 *  @param[in]  None
 *
 */
uint8_t DS18B20_READ_Byte(){
        uint8_t bit=0;
        uint8_t byte=0;
        for(uint8_t i=1;i<=8;i++){
            bit=DS18B20_READ_Bit();
            byte|=bit<<(i-1);
        }
        return byte;
}
/**
 *  @brief      判断DS18B20是否存在
 *
 *  @param[in]  None
 *
 */
uint8_t DS18B20_CHECK(){
        uint8_t counters=0;
        DS18B20_DQ_IN();
        while(DS18B20_DQ_IN_Read()&&counters<200){
            counters++;
            delay_cycles(delay_us*1);
        }
        if(counters>100)        //超时未检测到器件,返回1
            return 1;
        else
            counters=0;
        while(!(DS18B20_DQ_IN_Read())&&counters<240){
            counters++;
            delay_cycles(delay_us*1);
        }
 
        if(counters>240)        //检测到器件但总线电平持续拉低,返回2
            return 2;
        else
    //        DL_UART_transmitData(UART_0_INST,counters);
            return 0;           //检测到器件且总线电平有效,返回0
}
 
/**
 *  @brief      启用DS18B20
 *
 *  @param[in]  None
 *
 */
void DS18B20_START(void){
        DS18B20_RESET();
        DS18B20_CHECK();
        DS18B20_WRITE_Byte(0xcc);
        DS18B20_WRITE_Byte(0x44);
        DS18B20_RESET();
        DS18B20_CHECK();
        DS18B20_WRITE_Byte(0xcc);
        DS18B20_WRITE_Byte(0xbe);
}
 
/**
 *  @brief      初始化DS18B20
 *
 *  @param[in]  None
 *
 */
uint8_t DS18B20_INIT(void){
        DS18B20_RESET();
        return DS18B20_CHECK();
}
 
 
/**
 *  @brief      获取DS18B20温度数据(小数点数据)
 *
 *  @param[in]  None
 *
 */
float DS18B20_GetTemp(void){
        float temp_value=0.0;
        uint8_t temp_msb,temp_lsb=0;
        uint16_t temp=0;
 
        DS18B20_START();                //采样温度值
        temp_lsb=DS18B20_READ_Byte();
        temp_msb=DS18B20_READ_Byte();
        temp=(temp_msb<<8)+temp_lsb;
        if((temp&0xF800)==0xF800){      //高5位为1表示负温度
            temp=(~temp)+1;             //将补码取反运算+1得到负温值
            temp_value=temp*(-0.0625);
        }
        else
            temp_value=temp*0.0625;
        return temp_value;
}
void tempwarning(void)
{
    float temp = 0;
    int temp_level[2] = {10,100};
    if(DS18B20_INIT()==0){
           temp=DS18B20_GetTemp();
           if(temp<temp_level[0]){
               DL_GPIO_setPins(PORT_BEEP_PORT,PORT_BEEP_PIN__BEEP_PIN);
           }
           else if(temp>=temp_level[0]&&temp<temp_level[1]){
               DL_GPIO_togglePins(PORT_BEEP_PORT,PORT_BEEP_PIN__BEEP_PIN);
           }
           else {
               DL_GPIO_clearPins(PORT_BEEP_PORT,PORT_BEEP_PIN__BEEP_PIN);
           }
       }
       else{
           temp=0.1000;
           DL_GPIO_setPins(PORT_BEEP_PORT,PORT_BEEP_PIN__BEEP_PIN);
           delay_cycles(delay_us*1000);//温度传感器不存在、异常,LED_Red不断闪烁
           DL_GPIO_togglePins(PORT_LED_Red_PORT,PORT_LED_Red_PIN_LED_Red_PIN);
       }
}

 

3. 实现效果

 1717083985166.jpg

4. 注意事项



高工
2024-05-30 11:51:26     打赏
2楼

谢谢分享


共2条 1/1 1 跳转至

回复

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