其他分享
首页 > 其他分享> > STM32基本定时器做万能遥控器

STM32基本定时器做万能遥控器

作者:互联网

STM32基本定时器做万能遥控器

使用资源介绍

1:基本定时器:定时计数的功能
2:外部中断:下降沿上升沿触发方式,进入中断服务函数
3:滴答时钟:输出38khz载波

基本思路

制作万能遥控器,也就是对输入的NEC波形进行存储,按键键入后,把存储的波形输出出来
定义:GPIO_PE3为红外接受头的输入脚,GPIO_PA0为红外发射头的输出脚。使用TIM6,TIM7 基本定时器
定义 array[300][2] 存储波段和每段波的波长 int cnt=0;int count=0;co_1=0;

捕获NEC输入波形

输入捕获波形:
1:使能GPIO_PE3外部中断,设置触发方式为上升/下降沿都触发,
中断服务函数:EXTI3_IRQHandler 每进入一次中断函数,cnt++,当一次NEC波形接受完后,cnt就表示这段波形的波段数-1
2:使能tim6定时器,设置成每隔1us计数一次,设置最大计数为0xffff。
在每次进入EXTI3_IRQHandler函数时,把count赋值给array[cnt][0]=count;count=0;然后又开始计数,所以count表示一个波段持续的时间计数,把count1us就可以得到
这段波的持续时间。
3:因为计数最大也只能到65.536ms如果大于了这个计数计数器又重新从0开始,如果不做处理,大于65.5ms的波段的count就会又错误。所以还得计数它进行了多少次轮循。
中断服务函数:TIM6_IRQHandler在这个函数中,co_1++;然后在EXTI3_IRQHandler函数中array[cnt][1]=co_1;
至此,就捕获到了NEC的波形了,
array[300][2]:该数组表示:一次NEC最多能捕获到300个波段,array[x][0]第0列表示,每段波形的时间计数,array[x][1]第1列表示每段波形经过几次轮循,
例如array[10][0]=600
array[10][1]=1
表示nec波形的第10段波形的脉冲时间长度为(600+65535
1)*1us

输出存储的NEC波形

输出存储的NEC波形:
在主循环中通过一个标志去判断发载波还是不发载波
if(pxz==1)
{
Mapp_pwm_start_end(TRUE);
}
else
{
Mapp_pwm_start_end(FALSE);
}
然后在tim7的中断服务中去改变pxz的状态,每个记录的波段时长改变一次pxz的状态,就可以完好无损的发射nec波形了。

部分代码

通过uart命令发射红外按键

void USART1_IRQHandler(void)
{	
	char p;
	if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE))
		{
			p=USART_ReceiveData(USART1);
			if(p=='a')
			{
			TIM6->DIER|=0<<6; //关掉触发中断
			array[0][0]=0;
			TIM7->ARR=array[f][1];
			TIM7->CNT=0;
			power=TRUE;
			}
		}
}

EXTI3_IRQHandler函数实现

void EXTI3_IRQHandler(void)
{	
	if(EXTI_GetFlagStatus(EXTI_Line3))
		{			
			array[co][1]=TIM6->CNT;
			array[co][0]=co_1;
			co++;
			TIM6->CNT=0;
			co_1=0;
		}
	EXTI_ClearFlag(EXTI_Line3);
}

TIM6_IRQHandler函数实现

void TIM6_IRQHandler(void)
{ 
	if(TIM6->SR&0X0001)//捕获时候,看波段是否大于最大计数
	{
		co_1++;
	}
	TIM6->SR&=~(1<<0); //清除中断标志位 

}

TIM7_IRQHandler函数实现

void TIM7_IRQHandler(void)
{ 
	if(power==TRUE)
	{
		if(TIM7->SR&0X0001) //溢出中断
		{
			if(f<=co)//第几行
			{
				if(array[f][0]==0)//判断这一行有没有超过最大计数的
					{

					if(pxz==0)
					pxz=1;
					else
					pxz=0;
					f++;
					TIM7->ARR=array[f][1];
						
					}
				else//如果这一行有查过计数的。
					{
						array[f][0]=array[f][0]-1;
						TIM7->ARR=0xffff;
					}
				if (f == co)
					{	
						power=FALSE;
						TIM7->DIER|=0<<6; //允许触发中断
						printf("ERROR STATE  1\n");
					}
			}
			else
			{
				power=FALSE;
				printf("ERROR STATE  0\n");
			}
		} 
	}
	TIM7->SR&=~(1<<0); //清除中断标志位 
}

总结

总结:此方法,并不是好方法,可以用通用定时器的功能去简化流程,因为我还没学到通用定时器,所以,以现学的知识写了个这个,用于巩固定时器相关寄存器和一些之前学到的东西。
功能不完善,但是测试能用。如要完整源码,或者一起学习的qq:219735610

标签:IRQHandler,定时器,co,波形,STM32,计数,遥控器,TIM6,array
来源: https://blog.csdn.net/qq_38251859/article/details/121909442