ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-12-13 17:31:46  阅读:212  来源: 互联网

标签:IRQHandler 定时器 co 波形 STM32 计数 遥控器 TIM6 array


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有