2023.3.24
使用定时器定时显示DHT11温湿度,发现定时器无法运作。经室友提醒后发现,中断函数中没有清除中断挂起标志位。
2023.3.25
定时器加入c8t6工程中,发现程序无法正常运行。
2023.3.26
为了找bug,使用stlink v2仿真器逐条检查bug,发现DHT11初始化函数延时一段时间后,后续程序才能运行(50ms)。猜测是定时器中断和DHT11冲突(网上查到是DHT11上电有1s不稳定时间,期间不可发送指令。但如果不用定时器,不需要延时,程序也能运行)。
main.c
int main(void){
CLOCK_INIT();
OLED_Init();
DHT11_INIT();
Delay_ms(50);
TIMER_INIT();
GPIO_SetBits(GPIOC,GPIO_Pin_14);
while(1)
{
}
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
DHT11_RST();
DHT11_CHECK();
DHT11_GET_DATA(&TempH,&TempL,&HumiH,&HumiL);
OLED_ShowNum(1,1,TempH,2);
OLED_ShowChar(1,3,'.');
OLED_ShowNum(1,4,TempL,1);
OLED_ShowNum(2,1,HumiH,2);
OLED_ShowChar(2,3,'.');
OLED_ShowNum(2,4,HumiL,1);
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
TIMER.c
void TIMER_INIT(void) //ZigBee发送数据定时器初始化
{
TIM_InternalClockConfig(TIM2); //TIMx作为内部时钟
//配置时基单元
TIM_TimeBaseInitTypeDef ZIGBEE_TIMER_STRUCT;
ZIGBEE_TIMER_STRUCT.TIM_ClockDivision=TIM_CKD_DIV1;
ZIGBEE_TIMER_STRUCT.TIM_CounterMode=TIM_CounterMode_Up;
//配置定时时间,(TIM_Period+1)*(TIM_Prescaler+1)/CLK两者取值为0~65535
//分配后为0.1s
ZIGBEE_TIMER_STRUCT.TIM_Period=5000-1;
ZIGBEE_TIMER_STRUCT.TIM_Prescaler=1440-1;
ZIGBEE_TIMER_STRUCT.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2,&ZIGBEE_TIMER_STRUCT);
//开启TIMx中断
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
//NVIC INIT
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef TIM_NVIC_STRUCT;
TIM_NVIC_STRUCT.NVIC_IRQChannel=TIM2_IRQn;//无法使用TIMx宏定义,注意修改
TIM_NVIC_STRUCT.NVIC_IRQChannelCmd=ENABLE;
TIM_NVIC_STRUCT.NVIC_IRQChannelPreemptionPriority=1;
TIM_NVIC_STRUCT.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&TIM_NVIC_STRUCT);
//启动定时器
TIM_Cmd(TIM2,ENABLE);
}
DHT11.c
#define GPIO_OUT(n) (n==1)?GPIO_SetBits(DHT11_DAT_x,DHT11_DAT_Pinx):GPIO_ResetBits(DHT11_DAT_x,DHT11_DAT_Pinx)
#define GPIO_IN_DATA GPIO_ReadInputDataBit(DHT11_DAT_x,DHT11_DAT_Pinx)
//DHT11复位函数
void DHT11_RST(void)
{
GPIO_DHT11_OUT();
GPIO_OUT(0);
Delay_ms(20);
GPIO_OUT(1);
Delay_us(30);
}
//检测DHT11是否存在,存在返回1,否则返回0
u8 DHT11_CHECK(void)
{
GPIO_DHT11_IN();
u8 count=0;
while((count<100)&&(GPIO_IN_DATA))
{
count++;
Delay_us(1);
}
if(count>=90)
return 0;
else
count=0;
while(!(GPIO_IN_DATA));//等待高电平
return 1;
}
u8 DHT11_READ_BIT(void)
{
GPIO_DHT11_IN();
u8 num;
while(GPIO_IN_DATA);//等待低电平
while(!(GPIO_IN_DATA));//等待高电平
Delay_us(45);
if(GPIO_IN_DATA)
{
num=1;
while(GPIO_IN_DATA);
}
else
num=0;
return num;
}
u8 DHT11_READ_BYTE(void)
{
u8 i;
u8 num=0;
for(i=0;i<8;i++)
{
num<<=1;
num|=DHT11_READ_BIT();
}
return num;
}
u8 DHT11_GET_DATA(u8 *TempH,u8 *TempL,u8 *HumiH,u8 *HumiL)
{
u8 Humi_Temp[5];
u8 i;
for(i=0;i<5;i++)
{
Humi_Temp[i]=DHT11_READ_BYTE();
}
if((Humi_Temp[0]+Humi_Temp[1]+Humi_Temp[2]+Humi_Temp[3])==Humi_Temp[4])
{
*HumiH=Humi_Temp[0];
*HumiL=Humi_Temp[1];
*TempH=Humi_Temp[2];
*TempL=Humi_Temp[3];
return 1;
}else
return 0;
}
void DHT11_INIT(void)
{
GPIO_DHT11_OUT();
GPIO_SetBits(DHT11_DAT_x,DHT11_DAT_Pinx);
DHT11_RST();
DHT11_CHECK();
}