毕业设计历程

在STM32项目中,作者遇到DHT11温湿度传感器与定时器协同工作的问题。初始因未清除中断挂起标志导致定时器失效。之后发现DHT11初始化后的50ms延迟可能与定时器中断冲突,且了解到DHT11上电后有1s不稳定期。通过逐行调试,确认了问题并提出了解决方案。
摘要由CSDN通过智能技术生成

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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值