这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » TI » 一起玩转TIMSPM0系列MCU:课程3/任务1温度报警器

共1条 1/1 1 跳转至

一起玩转TIMSPM0系列MCU:课程3/任务1温度报警器

高工
2024-04-27 22:31:28     打赏

课程3的任务目标是实现温度报警器,采集DS18B20的温度数据并实时显示。我们通过课程三的学习掌握了ADC采集的相关配置以及应用,不过课后的习题所使用的DS18B20是数字型温度传感器,在实际的任务实现过程中并没有用到ADC的相关知识。

这一次我们使用的的器件有数码管模块、有源扬声器模块、DS18B20温度传感器模块。我们先了解一下新模块。

有源扬声器模块:

image1.png

本模块通过一个三极管进行驱动,并且是低电平触发,实际这块的控制只要通过一个引脚技能实现;

DS18B20温度传感器模块:

这个是这次任务比较难得一部分,DS18B20是通过单总线的方式进行通信的,这种通信协议对于时序的要求是非常严格的,我们需要根据时序图去编写起始、数据传输、结束等通信阶段。

我们在找到了一个DS18B20的驱动文件以及数据手册进行驱动的快速设计,单总线也就是所有通信都是通过这一根线实现的,我们需要根据时序切换输入输出状态,为了方便创建如下程序:

void delay_us(uint32_t Data)
{
    delay_cycles(Data*32);
}

void ConfigDQ_IN(void)//配置为输入
{
    DL_GPIO_disableOutput(GPIO_18B20_PORT, GPIO_18B20_PIN_Tem_PIN);
    DL_GPIO_initDigitalInput(GPIO_18B20_PIN_Tem_IOMUX);
    DL_GPIO_setPins(GPIO_18B20_PORT, GPIO_18B20_PIN_Tem_PIN);
    DL_GPIO_enableOutput(GPIO_18B20_PORT, GPIO_18B20_PIN_Tem_PIN);
}

void ConfigDQ_OUT(void)//配置为输出入
{
    DL_GPIO_disableOutput(GPIO_18B20_PORT, GPIO_18B20_PIN_Tem_PIN);
    DL_GPIO_initDigitalOutput(GPIO_18B20_PIN_Tem_IOMUX);
    DL_GPIO_setPins(GPIO_18B20_PORT, GPIO_18B20_PIN_Tem_PIN);
    DL_GPIO_enableOutput(GPIO_18B20_PORT, GPIO_18B20_PIN_Tem_PIN);
}

配置初始状态:

uint8_t DS18B20_Rst(void)
{
    uint8_t Time=0;
    ConfigDQ_OUT();   //设置为输出
    DQReset;                //拉低DQ
    delay_us(750);          //拉480us
    DQSet;                  //DQ=1
    delay_us(60);           //60US

    ConfigDQ_IN();    //设置为输入
    //等待ds18b20回应
    while (ReadDQ==1 && Time<200)
    {
        Time++;
        delay_us(1);
    }

    if(Time>200)
        return 1;
    else
        Time=0;

    while (ReadDQ == 0 && Time<240)
    {
        Time++;
        delay_us(1);
    }

    if(Time>240)
        return 1;
    else
        return 0;

}

写数据:

image2.png

void Write_Byte(uint8_t data)
 {
    uint8_t i;
    uint8_t bit;
    ConfigDQ_OUT();     //设置为输出
    for (i=1;i<=8;i++)
    {
        bit=data&0x01;
        data=data>>1;
        if(bit)       // 写1
        {
            DQReset;
            delay_us(2);
            DQSet;
            delay_us(60);
        }
        else            //写0
        {
            DQReset;
            delay_us(60);
            DQSet;
            delay_us(2);
        }
    }
}

读数据:

image3.png

uint8_t Read_Byte(void)
{
    uint8_t i,bit,data;
    data=0;
    for (i=1;i<=8;i++)
    {
        ConfigDQ_OUT();   //设置为输出
        DQReset;
        delay_us(2);
        ConfigDQ_IN();    //设置为输入
        delay_us(10);
        if(ReadDQ)
            bit=1;
        else
            bit=0;
        delay_us(48);
        //将获得的dt放在最前面,然后再右移一下空出最前面的位置
    data=(bit<<7)|(data>>1);
   }
    return data;
}

接下来就是数据的读取了:

uint16_t GetTemp(void)
{
    uint16_t tem;
    uint8_t temp,TH,TL;
    DS18B20_Rst();
    Write_Byte(0xcc);
    Write_Byte(0x44);
    DS18B20_Rst();
    Write_Byte(0xcc);
    Write_Byte(0xbe);
    TL=Read_Byte();
    TH=Read_Byte();

    if(TH>7)
    {
        TH=~TH;
        TL=~TL;
        temp=0;//温度为负
    }
    else    temp=1;//温度为正
    tem=TH;//获取高八位数据
    tem<<=8;
    tem+=TL;//获取低八位数据
    tem=(float)tem*0.625;
    if(temp)    return  tem;//温度为正
    else        return -tem;//温度为负
}

在定时器中调用GetTemp(void)获取温度,为什么要放到定时器里呢,因为中断发生会影响单总线的时序正确性,导致数据错误。暂定和之前课程的频率,每500ms采集一次,同时采集后判断温度是否大于280(温度是扩大十倍的值),大于限制就打开蜂鸣器,小于就关闭蜂鸣器。温度报警器功能同样通过按键去开启和关闭。

效果如下:

课程3效果展示.gif









关键词: MSPM0     课程3     任务1    

共1条 1/1 1 跳转至

回复

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