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

共2条 1/1 1 跳转至

课程3+"任务1"+"利用DS18B20实现温度报警功能"

菜鸟
2024-05-13 10:42:25     打赏

玩转TI MSPM0L1306课程 任务 利用DS18B20实现温度报警功能

前言 :这里我使用的是keil5.39keil版本必须在5.38A以上),编译器使用的是6.21版本,安装教程官网上面有详细的介绍,这里就不过多的说明了,如果说在使用keil版本出现问题的话,还是建议大家学习一下ccs编译环境,真的很好用。

一:任务目标:

1:蜂鸣器发声实现按键音效

2:数码管实现温度显示

3:温度报警器的实现

4:课后练习 :用DS18B20实现环境温度的采样

用数码管显示,并实现高温蜂鸣器报警

二:使用工具:

1LP-MSPM0L1306开发板;

2Mic USB线

374HC595数码管模块

4:杜邦线 5

三:硬件介绍:

1:按键检测电路

S2按键:PA14 默认外部下拉,检测高电平有效,配置IO时需要内部下拉或悬空。这个功能我们之前使用过,这里就不作重复介绍了。

2:蜂鸣器驱动电路

本次使用蜂鸣器为低电平触发方式,IO使用PA16 口,配置IO时需要内部上拉或悬空,

(这里我在学习时候发现与ADC检测的冲突了,IO引脚就顺延了一下)

实物图片:

DS18B20.jpg

原理图:

1.png 

实物图片:

蜂鸣器.png 

软件配置,利用SYSCONFIG配置一下,配置如下:

IO口配置.png 

基本的配置操作和之前教程中的控制LED灯的闪烁一致。

软件操作如下:

需要注意的是:在使用按键检测和蜂鸣器的IO引脚时,需要初始化引脚,否则不能正常使用。

主程序代码如下:

    while (1)

{

if(Function == 0)

{

KeyValue = DL_GPIO_readPins(Blinky_PORT,GPIO_LEDS_USER_KEY_01_PIN);   // Read the state of key input

if(KeyValue == 0)

{

DL_GPIO_clearPins(Blinky_PORT, GPIO_LEDS_USER_Twinkle_LED_PIN); //PA0= 0;turn on led    

DL_GPIO_clearPins(Blinky_PORT, GPIO_BEEP_OUT_01_PIN); //PA0= 0;turn on led

KeyCount++;

if(KeyCount >= 999)

{

KeyCount = 0 ;

KeyCount_S++ ;

}    

if( KeyCount_S >=10) KeyCount_S = 0 ;    

}

else

{

DL_GPIO_setPins(Blinky_PORT, GPIO_LEDS_USER_Twinkle_LED_PIN);   //PA0= 1;turn off led

DL_GPIO_setPins(Blinky_PORT, GPIO_BEEP_OUT_01_PIN);   //PA0= 1;turn off led

}    

}

Disp_Data(KeyCount_S,KeyCount);

    }

实物效果如下:

  KEY_BEEP 00_00_00-00_00_30.gif

2:数码管实现温度显示

硬件资源:利用板载的NTC温度传感器进行温度采集

原理图:

NTC.png 

实物图片如下:

NTC 硬件连接.png 

NTC的工作原理:NTC阻值随着温度的升高而降低,通过原理图得知会引起电压的变换,通过ADC采样得到采样值,再通过查表法得到电阻值;

1NTC接法:3.3V供电,电阻10K/ NTC(10K)

2ADC电压关系为:Uadc = 3.3*RT/(10000+RT)

3ADC(12bit)采样AD值为:AD = Uadc*4096/3.3 = 4096*RT/(10000+RT)(由于单片机是12位的AD,满点采样值为2^12=4096)

4:最后通过AD/RTRT/℃的对应关系,可通过查表方式得到AD 值对应温度。

软件代码如下:首先利用sysconfig 配置一下ADC功能:

ADC1.png 

ADC2.png 

以上配置参考视频中的进行配置,然后自动生产底层代码:

/* ADC12_0 Initialization */

static const DL_ADC12_ClockConfig gADC12_0ClockConfig = {

    .clockSel       = DL_ADC12_CLOCK_ULPCLK,

    .divideRatio    = DL_ADC12_CLOCK_DIVIDE_8,

    .freqRange      = DL_ADC12_CLOCK_FREQ_RANGE_24_TO_32,

};

SYSCONFIG_WEAK void SYSCFG_DL_ADC12_0_init(void)

{

    DL_ADC12_setClockConfig(ADC12_0_INST, (DL_ADC12_ClockConfig *) &gADC12_0ClockConfig);

    DL_ADC12_initSingleSample(ADC12_0_INST,

        DL_ADC12_REPEAT_MODE_ENABLED, DL_ADC12_SAMPLING_SOURCE_AUTO, DL_ADC12_TRIG_SRC_SOFTWARE,

        DL_ADC12_SAMP_CONV_RES_12_BIT, DL_ADC12_SAMP_CONV_DATA_FORMAT_UNSIGNED);

    DL_ADC12_configConversionMem(ADC12_0_INST, ADC12_0_ADCMEM_0,

        DL_ADC12_INPUT_CHAN_9, DL_ADC12_REFERENCE_VOLTAGE_VDDA, DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP0, DL_ADC12_AVERAGING_MODE_DISABLED,

        DL_ADC12_BURN_OUT_SOURCE_DISABLED, DL_ADC12_TRIGGER_MODE_AUTO_NEXT, DL_ADC12_WINDOWS_COMP_MODE_DISABLED);

    DL_ADC12_setSampleTime0(ADC12_0_INST,500);

    /* Enable ADC12 interrupt */

    DL_ADC12_clearInterruptStatus(ADC12_0_INST,(DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED));

    DL_ADC12_enableInterrupt(ADC12_0_INST,(DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED));

    DL_ADC12_enableConversions(ADC12_0_INST);

}

因为我是在keil5中进行编译,下载的所以大家在移植代码的时候,需要注意要调用ADC0的初始化函数,SYSCFG_DL_ADC12_0_init();,并且使能ADC中断函数;   DL_ADC12_enablePower(ADC12_0_INST);

实物效果如下:

 adc 00_00_00-00_00_30.gif

3:温度报警器的实现

课程目标:PTC采样环境温度,数码管显示温度(),蜂鸣器实现超温报警

通过上两节课程的学习,我学会了控制蜂鸣器的功能和利用ADC采集温度,这节课我只需在原基础上进行修改,设置一下温度的上限值,超过上限值时候,开始温度报警,并且可以通过按键取消蜂鸣器的报警,具体代码如下:

ADC_Temprature = ReadTemprature();  

ADC_Temprature_DEAL = NTC_AD_Search(ADC_Temprature) ;  

if((ADC_Temprature_DEAL >= High_TEMP) && (Cancel_OUT == true ))

{  

DL_GPIO_clearPins(Blinky_PORT, GPIO_LEDS_USER_Twinkle_LED_PIN); //PA0= 0;turn on led  

DL_GPIO_clearPins(Blinky_PORT, GPIO_BEEP_OUT_01_PIN);      //PA16= 0;turn on BEEP    

}

if((ADC_Temprature_DEAL < High_TEMP))  //当温度低于设定温度时后,再次超过设定值时,才允许报警

{

 Cancel_OUT = true ;

}  

/*读取按键功能*/    

KeyValue = DL_GPIO_readPins(Blinky_PORT,GPIO_LEDS_USER_KEY_01_PIN);   // Read the state of key input

if(KeyValue == 0)

{

DL_GPIO_setPins(Blinky_PORT, GPIO_LEDS_USER_Twinkle_LED_PIN); //PA0= 0;turn on led

//     DL_GPIO_setPins(Blinky_PORT, GPIO_BEEP_OUT_01_PIN); //PA0= 0;turn on beep       

Cancel_OUT = false ;

}

Disp_Data_work2(ADC_Temprature_DEAL,ADC_Temprature);

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

DS18B20介绍:

、 独特的单总线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实

        现微处理器与DS18B20的双向通讯。大大提高了系统的抗干扰性。

、测温范围 -55℃+125℃,精度为±05℃

、支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,

        实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的

        不稳定。

、 工作电源: 3.0~5.5V/DC (可以数据线寄生电源)。

、在使用中不需要任何外围元件。

、 测量结果以9~12位数字量方式串行传送。

软件介绍:

单总线是一种半双工通信方式

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

边讲信号类型,边讲代码配置的方式,让大家了解STM32驱动18B20过程。

一:复位脉冲

单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480 us,,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时1560 us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240 us,以产生低电平应答脉冲。

//========================================================================

// 函数: DS18B20_Rst(void)

// 描述: 复位 DS18B20

// 参数: None.

// 返回: None.

// 版本: V1.0, 2024-05-09

//========================================================================

void DS18B20_Rst(void)    

{                 

DL_GPIO_initDigitalOutput(GPIO_GRP_0_PIN_3_RC_IOMUX);

DS18B20_DAT(0);

delay_us(750) ;

DS18B20_DAT(1);

delay_us(15) ;

}

二:应答信号:

//========================================================================

// 函数: DS18B20_Rst(void)

// 描述: 等待DS18B20的回应

// 返回1:未检测到DS18B20的存在

// 返回0:存在

// 参数: None.

// 返回: None.

// 版本: V1.0, 2024-05-09

//========================================================================

char DS18B20_Check(void)    

{   

int retry=0;

DL_GPIO_initDigitalInput(GPIO_GRP_0_PIN_3_RC_IOMUX); //SET PG11 INPUT  

while (DL_GPIO_readPins(HC595_PORT, GPIO_GRP_0_PIN_3_RC_PIN)&&retry<200)

{

retry++;

delay_us(1);

};  

if(retry>=200)return 1;

else retry=0;

while ((!DL_GPIO_readPins(HC595_PORT, GPIO_GRP_0_PIN_3_RC_PIN))&&retry<240)

{

retry++;

delay_us(1);

};

if(retry>=240)return 1;     

return 0;

}

3:写时序:

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

//========================================================================

// 函数: void DS18B20_Write_Byte(char dat)  

// 描述: 写一个字节到DS18B20

// dat:要写入的字节

// 参数: None.

// 返回: None.

// 版本: V1.0, 2024-05-09

//========================================================================

void DS18B20_Write_Byte(char dat)     

 {             

  unsigned  char j;

  unsigned  char testb;

    DL_GPIO_initDigitalOutput(GPIO_GRP_0_PIN_3_RC_IOMUX);; //SET PG11 OUTPUT

    for (j=1;j<=8;j++)

{

        testb=dat&0x01;

        dat=dat>>1;

        if (testb)

        {    

DS18B20_DAT(0);

delay_us(2) ;

DS18B20_DAT(1);

delay_us(60) ;           

        }

        else

        {

 

DS18B20_DAT(0);

delay_us(60) ;

DS18B20_DAT(1);

delay_us(2) ;      

        }

    }

}

 

1时序:主机输出低电平,延时2us,然后释放总线,延时60us

 

0时序:主机输出低电平,延时60us,然后释放总线,延时2us

四: 读时序

单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。

所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。

//========================================================================

// 函数: int DS18B20_Read_Bit(void)

// 描述: 等待DS18B20的回应

// 从DS18B20读取一个位

// 返回值:1/0

// 参数: None.

// 返回: None.

// 版本: V1.0, 2024-05-09

//========================================================================

int DS18B20_Read_Bit(void)  

{

  unsigned  char data;

DL_GPIO_initDigitalOutput(GPIO_GRP_0_PIN_3_RC_IOMUX);; //SET PG11 OUTPUT

DS18B20_DAT(0);

delay_us(2) ;

DS18B20_DAT(1);

DL_GPIO_initDigitalInput(GPIO_GRP_0_PIN_3_RC_IOMUX);

delay_us(12);

if(DL_GPIO_readPins(HC595_PORT, GPIO_GRP_0_PIN_3_RC_PIN) ) data=1;

    else data=0;  

    delay_us(50);           

    return data;

}

五:读取一个字节数据

//========================================================================

// 函数: char DS18B20_Read_Byte(void)

// 描述: DS18B20读取一个字节

// 返回值:读到的数据

// 参数: None.

// 返回: None.

// 版本: V1.0, 2024-05-09

//========================================================================

char DS18B20_Read_Byte(void)     

{        

  unsigned  char i,j,dat;

    dat=0;

for (i=1;i<=8;i++)

{

        j=DS18B20_Read_Bit();

        dat=(j<<7)|(dat>>1);

    }          

    return dat;

}

总结步骤:

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

//========================================================================

// 函数: short DS18B20_Get_Temp(void)  

// 说明:从ds18b20得到温度值

// 精度:0.1C

// 返回值:温度值 (-550~1250

// 版本: V1.0, 2024-05-09

//========================================================================

short DS18B20_Get_Temp(void)

{

  unsigned  char temp;

  unsigned  char TL,TH;

short tem;

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;     //获得底八位

tem=(float)tem*0.625;  //转换

if(temp)return tem;  //返回温度值

else return -tem;    

}

以上为DS13B20驱动函数:

按键检测代码如下:

/*读取用户按键1 ---S2 功能*/    

work3_keyValue1 = DL_GPIO_readPins(Blinky_PORT,GPIO_LEDS_USER_KEY_01_PIN);   // Read the state of key input

if((work3_keyValue1 == 0) && ( work3_key1Up == true ))

{

DL_GPIO_setPins(Blinky_PORT, GPIO_LEDS_USER_Twinkle_LED_PIN); //PA0= 0;turn on led

DL_GPIO_setPins(Blinky_PORT, GPIO_BEEP_OUT_01_PIN); //PA0= 0;turn on beep      

work3_key1Up = false ;

DisMode++ ;

if(DisMode  >3)

{

DisMode = 1  ;

}

}

if(work3_keyValue1 == 0x4000)

{

 work3_key1Up = true ;

}

/*读取用户按键2 ---S1  功能*/    

work3_keyValue2 = DL_GPIO_readPins(Blinky_PORT,GPIO_LEDS_USER_KEY_02_PIN);   // Read the state of key input

if((work3_keyValue2 == 0) && ( work3_key2Up == true ))

{

DL_GPIO_setPins(Blinky_PORT, GPIO_LEDS_USER_Twinkle_LED_PIN); //PA0= 0;turn on led

DL_GPIO_setPins(Blinky_PORT, GPIO_BEEP_OUT_01_PIN); //PA0= 0;turn on beep      

work3_key2Up = false ;

/*只有在配置界面下,才对温度阈值进行设置*/    

if(DisMode == 1)

{

Value_Max  = Value_Max + 5 ;

if( Value_Max  >= 350)

Value_Max =25 ;

}

}

if(work3_keyValue2 == 0x40000)

{

 work3_key2Up = true ;  

}

温度报警检测:

/*报警检测功能*/      

if(DS18B20_TEMP  > Value_Max )

{

  DisMode = 2 ;        

DL_GPIO_clearPins(Blinky_PORT, GPIO_BEEP_OUT_01_PIN);      //PA16= 0;turn on BEEP

}

修改温度阈值函数:

/*只有在配置界面下,才对温度阈值进行设置*/    

if(DisMode == 1)

{

Value_Max  = Value_Max + 5 ;

if( Value_Max  >= 350)

Value_Max =25 ;

}

主程序如下:

/*读取板载的NTC温度值,*/  

ADC_Temprature = ReadTemprature();  

ADC_Temprature_DEAL = NTC_AD_Search(ADC_Temprature) ;

keyDeal();

/*读取DS18B20数据*/  

/*界面显示函数*/  

if(DisMode == 1)

 Disp_Data_work4(Value_Max);

else if(DisMode == 2)      

 Disp_Data_work5(DS18B20_TEMP);    

else    

 Disp_Data_work3(ADC_Temprature_DEAL,DS18B20_TEMP);

其中温度读取在定时器内调用,每50MS 读取一次。。

这里我增加了设置温度设定值功能和按键取消报警的功能,这个在视频中有所体现。

实物效果如下:

202405131021 00_00_00-00_00_30.gif





关键词: MSPM0L1306    

工程师
2024-05-13 20:21:12     打赏
2楼

666


共2条 1/1 1 跳转至

回复

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