拓展板除了比较多路方便的PWM和ADC,还有几个传感器。比如温度传感器DS18B20和温湿度传感器DHT11。好像往年赛点都提供(听说第十届需要自己写),直接初始化以后调用函数就可以。
复制到自己的工程下在工程内也添加即可。
跳线帽:P3的TDQ连接P4的对应引脚
如果只是想把这个模块用起来其实初始化结束以后调用即可。如下:
float temp_f;
ds18b20_init_x();
while(1)
{
while(1)
{
temp_f = ds18b20_read() * 0.0625; //默认精度为12位
sprintf((char*)str, " Temperatrue:%2.2f ", temp_f);
LCD_DisplayStringLine(Line4,str);
}
但是这里有一个问题
仔细看读取函数会发现,它每次都会有一次750ms的延时。如果只是要上面的代码运行起来可以忽略,但是和其他模块综合起来用会导致其他部分出问题。因为每读一次就要卡在那里750ms,后面DHT11其实也有同样的问题。
最后会说利用滴答定时器的非阻塞式方法
这个原理也超级简单,它会把温度和湿度同时读出来存在32的变量里,高十六位是湿度,低十六位存着温度。
详细请参考:
https://blog.csdn.net/qq_43605009/article/details/105033018
u32 DHT_VAL;
dht11_init();
while(1)
{
DHT_VAL = dht11_read();
sprintf((char*)str, " Humid:%2d ", DHT_VAL>>24);
LCD_DisplayStringLine(Line6,str);
sprintf((char*)str, " Temper:%2d ", (DHT_VAL>>8)&0xff);
LCD_DisplayStringLine(Line8,str);
delay_ms(2000);
}
**注意:DHT11最后一定要加2S左右的延时才会显示正常,好像是它采样需要时间不然采集数据不稳定 **
这其实又引出了上面那个情况,和其他模块结合使用时候如果每次都需要卡在这里2S可能会导致其他代码执行出错。
其实就是把两个函数分别设置标志位和计数变量,然后在滴答定时器内执行。通过1ms进一次中断实现延迟。
变量定义
float temp_f;
u8 temp_i;
u8 str[20];
u32 DHT_VAL,DHT_SysTick,DS18_SysTick;
u8 DHT_SysFlag=1;
u8 DS18_SysFlag;
主函数
int main(void)
{
u32 z;
SysTick_Config1(SystemCoreClock/1000);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
STM3210B_LCD_Init();
ds18b20_init_x();
Seg_Init();
LED_Init();
dht11_init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
LCD_DisplayStringLine(Line2 ,(unsigned char *)" Hello,world. ");
while(1)
{
if(DS18_SysFlag==1)
{
temp_f = ds18b20_read() * 0.0625; //默认精度为12位
temp_i = temp_f; //将浮点型转换为整型
sprintf((char*)str, " Temperatrue:%2.2f ", temp_f);
LCD_DisplayStringLine(Line4,str);
Seg_Write((u8)temp_i/10, (u8)temp_i%10,12);
DS18_SysTick=0;
DS18_SysFlag=0;
}
if(DHT_SysFlag==1)
{
DHT_VAL = dht11_read();
sprintf((char*)str, " Humid:%2d ", DHT_VAL>>24);
LCD_DisplayStringLine(Line6,str);
sprintf((char*)str, " Temper:%2d ", (DHT_VAL>>8)&0xff);
LCD_DisplayStringLine(Line8,str);
DHT_SysTick=0;
DHT_SysFlag=0;
}
}
}
滴答定时器中断
extern u32 DHT_SysTick,DS18_SysTick;
extern u8 DHT_SysFlag,DS18_SysFlag;
u8 state,state1;
void SysTick_Handler(void)
{
TimingDelay--;
if(DHT_SysFlag==0)
{
DHT_SysTick++;
if(DHT_SysTick==2000)
{
DHT_SysFlag=1;
state = !state;
LED_Show(led1,state);
}
}
if(DS18_SysFlag==0)
{
DS18_SysTick++;
if(DS18_SysTick==750)
{
DS18_SysFlag=1;
state1 = !state1;
LED_Show(led8,state1);
}
}
}