通过数码管显示温度数据,并设置蜂鸣器报警
进入syscfg进行初始化GPIO管脚和定时器,分别配置
PA27==>HC595_DAT,
PA26==>HC595_SLK,
PA13==>HC595_RLK,
PA1 ==>DS18B20_DQ
PA15==>GPIO_BEEP
在代码中编写HC595驱动函数:
uint16_t tempval =456; uint8_t TimerCnt = 0 ; unsigned char Disp_DX[16] ={ 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x8C, 0xBF, 0xC6, 0xA1, 0x86, 0xFF }; unsigned char Disp_PX[8] = {1,2,3,4,5,6,7,8}; #define HC595_DAT(x) ((x)?(DL_GPIO_setPins(GPIOA_HC595_PORT,GPIOA_HC595_HC595_DAT_PIN)) : (DL_GPIO_clearPins(GPIOA_HC595_PORT,GPIOA_HC595_HC595_DAT_PIN))) #define HC595_CLK(x) ((x)?(DL_GPIO_setPins(GPIOA_HC595_PORT,GPIOA_HC595_HC595_SLK_PIN)) : (DL_GPIO_clearPins(GPIOA_HC595_PORT,GPIOA_HC595_HC595_SLK_PIN))) #define HC595_RCK(x) ((x)?(DL_GPIO_setPins(GPIOA_HC595_PORT,GPIOA_HC595_HC595_RLK_PIN)) : (DL_GPIO_clearPins(GPIOA_HC595_PORT,GPIOA_HC595_HC595_RLK_PIN))) void Display_0ut() { HC595_RCK(0); delay_cycles(32); HC595_RCK(1); delay_cycles(32); } void HC595_WriteData(unsigned char data) { unsigned char i; for(i=0;i<8;i++) { if(data & 0x80) { HC595_DAT(1); } else { HC595_DAT(0); } data <<= 1; HC595_CLK(0); delay_cycles(32); HC595_CLK(1); delay_cycles(32); } } void HC595_Send_Data(uint8_t dis_num,uint8_t dis_bit) { HC595_WriteData(dis_num); HC595_WriteData(1<<dis_bit); Display_0ut(); } void Disp_Data(uint16_t u16DataH) { uint16_t templ,tempH; uint8_t num_q,num_b,num_s,num_g; tempH = u16DataH; num_q = tempH/1000; num_b = tempH/100%10; num_s = tempH/10%10; num_g = tempH%10; HC595_Send_Data(Disp_DX[num_q],7); HC595_Send_Data(Disp_DX[num_b],6); HC595_Send_Data(Disp_DX[num_s],5); HC595_Send_Data(Disp_DX[num_g],4); }
设置蜂鸣器驱动宏定义:
#define BeepON DL_GPIO_clearPins(GPIOA_HC595_PORT, GPIOA_HC595_GPIO_BEEP_PIN); #define BeepOFF DL_GPIO_setPins(GPIOA_HC595_PORT, GPIOA_HC595_GPIO_BEEP_PIN);
新建.c文件和.h文件编写DS18B20驱动函数:
ds18b20.c文件内容
#define DS18B20_DQ_OUTH DL_GPIO_setPins(GPIOA_HC595_PORT, GPIOA_HC595_DS18B20_DQ_PIN) #define DS18B20_DQ_OUTL DL_GPIO_clearPins(GPIOA_HC595_PORT, GPIOA_HC595_DS18B20_DQ_PIN) #define DS18B20_DQ_READ DL_GPIO_readPins(GPIOA_HC595_PORT, GPIOA_HC595_DS18B20_DQ_PIN) #define DS18B20_DQ_IN DL_GPIO_initDigitalInput(GPIOA_HC595_DS18B20_DQ_IOMUX);DL_GPIO_disableOutput(GPIOA_HC595_PORT, GPIOA_HC595_DS18B20_DQ_PIN) #define DS18B20_DQ_OUT DL_GPIO_initDigitalOutput(GPIOA_HC595_DS18B20_DQ_IOMUX);DL_GPIO_enableOutput(GPIOA_HC595_PORT, GPIOA_HC595_DS18B20_DQ_PIN) #define delay_us_cycle 32 /* 延时函数 */ 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; }
在中断函数中调用温度读取,并进行温度判断:
void TIMER_0_INST_IRQHandler(void) { switch(DL_TimerG_getPendingInterrupt(TIMER_0_INST)) { case DL_TIMER_IIDX_ZERO: TimerCnt++; if(TimerCnt >=100) { TimerCnt=0; tempval = DS18B20_Get_Temp();//温度数据一秒读取一次 if(tempval > 30) { BeepON; } else { BeepOFF; } } break; default: break; } }
在主函数中调用温度显示函数:
extern uint16_t tempval; int main(void) { SYSCFG_DL_init(); NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); while (1) { Disp_Data(tempval); } }
由于传入的参数是无符号整型,所以没有小数,实际效果: