项目概述-任务目标
1.采集DS18B20芯片温湿度数据
2.数码管显示实际温度数值(PS 我手里的数码管器件坏掉了 所以显示我用串口中断去显示温度)
3.温度超过阈值,通过蜂鸣器报警
io口配置
串口配置
代码如下:
#include "ti_msp_dl_config.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) uint8_t gWelcomeMsg[] = "\r\n==== MSPM0 Console Test ====\r\n"; uint8_t gTestingMsg[] = "> Testing...0\r\n"; uint8_t TimerCnt = 0; uint16_t TmpVal = 999; float realTemp = 0.0; uint16_t testData = 0; uint8_t str[100]; uint8_t lens=0; uint8_t i; #define delay_us_cycle 32 /* 温湿度芯片相关功能函数 */ #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) /* 延时函数 */ 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; } volatile bool gConsoleTxTransmitted, gConsoleTxDMATransmitted, gTransmitReady; void UART_Console_write(const uint8_t *data, uint16_t size) { DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(data)); DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(&UART_0_INST->TXDATA)); DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, size); DL_SYSCTL_disableSleepOnExit(); DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID); while (false == gConsoleTxDMATransmitted) { __WFE(); } while (false == gConsoleTxTransmitted) { __WFE(); } gConsoleTxTransmitted = false; gConsoleTxDMATransmitted = false; } int main(void) { gTransmitReady = false; gConsoleTxTransmitted = false; gConsoleTxDMATransmitted = false; uint32_t increment = 0; DS18B20_Start(); SYSCFG_DL_init(); NVIC_EnableIRQ(UART_0_INST_INT_IRQN); NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); /* Write welcome message */ UART_Console_write(&gWelcomeMsg[0], sizeof(gWelcomeMsg)); DL_GPIO_setPins(GPIO_BEEP_PORT, GPIO_BEEP_PIN_BEEP_PIN); while (1) { if (gTransmitReady == true) { /* Will output "Testing...0", "Testing...1", etc. and loop after 9 */ gTransmitReady = false; realTemp = DS18B20_Get_Temp(); // 将浮点数转换为字符串 sprintf(str, "temp=%.2f\n", realTemp); lens = strlen(str); UART_Console_write(&str[0], sizeof(str)); if(realTemp > 40){ BeepON; delay_cycles(100); BeepOFF; } } else { __WFI(); } } } void UART_0_INST_IRQHandler(void) { switch (DL_UART_Main_getPendingInterrupt(UART_0_INST)) { case DL_UART_MAIN_IIDX_EOT_DONE: gConsoleTxTransmitted = true; break; case DL_UART_MAIN_IIDX_DMA_DONE_TX: gConsoleTxDMATransmitted = true; break; default: break; } } void TIMER_0_INST_IRQHandler(void) { switch (DL_Timer_getPendingInterrupt(TIMER_0_INST)) { case DL_TIMER_IIDX_ZERO: gTransmitReady = true; DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN); break; default: break; } }
运行截图
实物图