(一)任务概述
本次主要是以自我提升的态度来参加本次TI的活动,自己在学校上课也在学习MSPM0系列单片机,感谢EEPW提供的这次机会,让我能够巩固拓展自己的知识。这次作业的主要是接着上节课数码管的基础之上,利用温度采集模块进行温度的采集,并将其显示在数码管上,同时利用蜂鸣器,让其温度在高于一定程度时能够实现报警的功能。本次使用的开发板是MSPM0系列的L1306,使用的软件是CCS THEIA.
(二)原理介绍
1.数码管简单回顾
2.温度采集模块介绍
DS18B20是一种数字式温度传感器,由Maxim Integrated公司生产。它可以测量环境温度,精度为±0.5°C,在-10°C到+85°C的范围内有效。DS18B20采用一根单根的连接线,通过一线控制总线进行数据传输。它具有低功耗特性和4-pin封装,适用于各种应用场合,如电子设备、工业控制系统和汽车领域等。DS18B20可以通过ROM中的唯一64位序列号进行地址编程,用于多个传感器在同一总线上运行,方便使用和管理。
3.蜂鸣器介绍
1. 有源蜂鸣器:有源蜂鸣器需要外部电源来驱动,一般通过接通电源使内部的震荡器产生声音。有源蜂鸣器通常可以产生声音的频率范围更广,声音更响亮,但也需要较高的电压和电流。
2. 无源蜂鸣器:无源蜂鸣器是一种内部集成振荡器的器件,不需要外部电源驱动。当电压施加到蜂鸣器上时,内部振荡器会自动振动产生声音。无源蜂鸣器一般功耗低,但声音较小且频率范围较窄。
4.硬件接线图
(三)syscfg配置
syscfg是一个系统配置工具,用于配置和管理嵌入式系统的各种参数和设置。syscfg工具可以帮助开发人员在CCS中轻松地配置系统的各种参数,包括时钟设置、引脚配置、外设功能等。通过syscfg工具,开发人员可以直观地查看和调整系统的配置信息,以满足不同的应用需求。这次我使用的软件是CCS THEIA系列,接下来我将来简单介绍引脚的配置教程与工作。
1.数码管引脚配置及定时器配置
2.温度采集模块配置
3.蜂鸣器配置
(四)核心代码展示
变量及宏定义
#include "ti/driverlib/dl_gpio.h" #include "ti/driverlib/m0p/dl_core.h" #include "ti_msp_dl_config.h" #include <stdint.h> //dio -- PA27 : 串行数据输入 //SCLK-- PA26 :移位时钟 //RCLK-- PA13 :并行寄存器锁存时钟 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(BEEP_PORT, BEEP_BEEP_PIN_PIN); #define BeepOFF DL_GPIO_setPins(BEEP_PORT, BEEP_BEEP_PIN_PIN); #define DS18B20_DQ_OUTH DL_GPIO_setPins(DS18B20_PORT, DS18B20_DQ_PIN) #define DS18B20_DQ_OUTL DL_GPIO_clearPins(DS18B20_PORT, DS18B20_DQ_PIN) #define DS18B20_DQ_READ DL_GPIO_readPins(DS18B20_PORT, DS18B20_DQ_PIN) #define DS18B20_DQ_IN DL_GPIO_initDigitalInput(DS18B20_DQ_IOMUX);DL_GPIO_disableOutput(DS18B20_PORT, DS18B20_DQ_PIN) #define DS18B20_DQ_OUT DL_GPIO_initDigitalOutput(DS18B20_DQ_IOMUX);DL_GPIO_enableOutput(DS18B20_PORT, DS18B20_DQ_PIN) #define delay_us_cycle 32 uint8_t TimerCnt = 0; uint16_t TmpVal = 999; float realTemp = 0.0; uint16_t testData = 0;
2.DS18B20代码(部分参考于网络)
/* 延时函数 */ 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) { 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) { 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; delay_us(2); DS18B20_DQ_OUTH; delay_us(60); } else { DS18B20_DQ_OUTL; delay_us(60); DS18B20_DQ_OUTH; delay_us(12); } } } /* 启动芯片 */ void DS18B20_Start(void) { DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0x44); } float DS18B20_Get_Temp(void) { uint8_t temp; uint8_t TL, TH; int16_t tem; float fValue = 0.0; DS18B20_Start(); DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0xbe); TL = DS18B20_Read_Byte(); TH = DS18B20_Read_Byte(); 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(); }
3.主函数
int main(void) { SYSCFG_DL_init(); DL_GPIO_setPins(BEEP_PORT, BEEP_BEEP_PIN_PIN); NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); while (1) { Disp_Temp(realTemp); } } 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; } }
(五)总结
通过这个项目,我学会了如何使用DS18B20温度传感器进行数据采集,并且将数据显示在数码管上,同时实现了高温报警功能。这为我积累了更多的嵌入式系统开发经验。这个项目不仅帮助我提升了技术水平,还具有很高的实用性。将所学到的知识应用到实际的环境温度监测中,通过数码管和蜂鸣器实时监控和报警,体现了创造性和实用性,以后会更加努力学习单片机知识。