基于STM32的学习型通用红外遥控设备的设计实现(二)


2.1 38KHz载波产生
常用的38KHz载波的产生方法有455KHz晶振分频法、时基电路搭建法、微控制器PWM模块产生法。为减少硬件规模、缩减成本,故由STM32的定时器输出PWM波,得到占空比1:3的红外载波。
STM32的定时器分为高级定时器(TIMER1、TIMER2)、基本定时器(TIMER6、TIMER7) 和通用定时器(TIMER2~ TIMER5),具有非常强大的功能。其中通用定时器可以用于输入捕获、输出比较和PWM等,通过定时器的预分频器和RCC时钟控制预分频器,脉冲长度和波形周期能够在几个微秒到毫秒间进行调整。此外,每个通用定时器都是完全独立,不曾共享任何资源。
本模块使用定时器TIM2的通道CH1输出占空比1:3的载波信号。操作流程图如下图所示:
程序代码如下:
/********************************************************************
* Function Name  : TIM2_PWM_Init(u16 arr,u16 psc)
* Function       : TIM2的通道CH1的PWM模式初始化
* parameter      : arr - 自动重装值
				   psc - 时钟预分频数	
* Description    : 频率f = 72M/[(psc+1)*(arr+1)]               
* Return         : void
*********************************************************************/
void TIM2_PWM_Init(u16 arr,u16 psc)
{
	/* 初始化结构体定义 */
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef	TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef 	TIM_OCInitStructure;
	/* 使能相应端口的时钟 */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	//使能定时器2时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   //使能GPIO外设时钟
	
	/* GPIOA.0初始化 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				// TIM2 CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 		// PA.0 复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_SetBits(GPIOA,GPIO_Pin_0);
	/* TIM2 初始化*/
	TIM_TimeBaseInitStructure.TIM_Period = arr;	 			//下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;			//作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;  		//时钟分割:TDTS = Tck_tim
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	/* 定时器TIM2 Ch1 PWM模式初始化 */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  		//选择定时器模式:TIM PWM1
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//比较输出使能
	//TIM_OCInitStructure.TIM_Pulse = (arr+1)/2;	  		//占空比 50%
	TIM_OCInitStructure.TIM_Pulse = (arr+1)/3;	  			//占空比1:3
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出极性:TIM输出比较极性高
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);

	/* 使能TIM2在CCR1上的预装载寄存器 */
	TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); 
	/* 使能定时器 */
	TIM_Cmd(TIM2, ENABLE); 			
}
示波器(RIGOL DG1102E)查看38KHz载波信号的波形,如下图所示:
 
2.2 按键设计
设置STM32的GPIO口为输入模式,通过读取IO口状态,判断是否有按键按下。为避免干扰产生一些误操作,在检测到电平变化后延时一段时间,再重新读取IO口状态。
本模块设置了5个独立按键的接口,实现流程图如下图所示:
程序代码如下:
/********************************************************************
* Function Name  : KEY_Init(void)
* Function       : 按键端口初始化
* parameter      : void
* Description    : void                 
* Return         : void
*********************************************************************/
void KEY_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	// Enable PORTA clock
	/* 初始化KEY1-->KEY5 上拉输入 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 |GPIO_Pin_4 |GPIO_Pin_5 |
								  GPIO_Pin_6 |GPIO_Pin_7;   // Config port
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU; 		    // Input pull-up
 	GPIO_Init(GPIOA, &GPIO_InitStructure);					// Init GPIOA3~7
}

/********************************************************************
* Function Name  : KEY_Scan(u8 mode)
* Function       : 按键扫描
* parameter      : mode - 0,不支持连续按;1,支持连续按               
* Return         : 0 - 没有任何按键按下
				   1 - KEY0按下
				   2 - KEY1按下	
*********************************************************************/
u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up = 1;
	if(mode)  key_up=1;  
	if(key_up&&(KEY1==0||KEY2==0|KEY3==0|KEY4==0|KEY5==0)){  // key down
		delay_ms(10);	// eliminate debouncing
		key_up = 0;
		if(KEY1==0) 	 return VOL_UP;
		else if(KEY2==0) return VOL_DOWN;
		else if(KEY3==0) return CH_UP;
		else if(KEY4==0) return CH_DOWN;
		else if(KEY5==0) return PWR_ON;
	
	}
	else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1&&KEY5==1){
		key_up = 1; 	
	}
 	return 0;// 无按键按下
}
2.3 STM32接收红外信号并测其脉宽
向量中断控制器(NVIC)与Cortex-M3内核的逻辑紧密耦合、相互交融,共同完成对中断的控制。
S TM32有两个优先级概念—抢占式优先级和响应优先级,响应优先级又被称为亚优先级或副优先级,STM32的每个中断源都需要指定这两种优先级。
高抢占式优先级的中断可以在具有低抢占式优先级的中断处理中被响应,即所谓的中断嵌套。当两个中断源的抢占式优先级相同时,两者间就没有嵌套关系,后到来的中断就需要等待前一个中断处理完后才能被响应;若两个中断同时到达,中断控制器会根据它们响应优先级的高低决定优先处理哪一个;若两个中断的抢占式优先级和响应优先级都相同,则根据它们在中断表中的排列顺序决定两者的处理先后。
每个中断源都需要指定抢占式优先级和响应优先级,这就需要相应的寄存器记录每个中断的优先级。Cortex-M3中定义8比特来设置中断优先级,故有8中分配方式,优先级分组如下:
1) 所有8位都用来指定响应优先级;
2) 最高1位指定抢占式优先级,最低7位指定响应优先级;
3) 最高2位指定抢占式优先级,最低6位指定响应优先级;
4) 最高3位指定抢占式优先级,最低5位指定响应优先级;
5) 最高4位指定抢占式优先级,最低4位指定响应优先级;
6) 最高5位指定抢占式优先级,最低3位指定响应优先级;
7) 最高6位指定抢占式优先级,最低2位指定响应优先级;
8) 最高7位指定抢占式优先级,最低1位指定响应优先级;
在STM32中指定中断优先级的寄存器减少到4位,可以通过固件库函数
NVIC_PriorityGroupConfig()进行选择,该函数的参数有5个,如下:
1) NVIC_PriorityGroup_0: 选择第0组;
2) NVIC_PriorityGroup_1: 选择第1组;
3) NVIC_PriorityGroup_2: 选择第2组;
4) NVIC_PriorityGroup_3: 选择第3组;
5) NVIC_PriorityGroup_4: 选择第4组。
EXTI,即外部中断/事件控制器,由19个产生事件/中断要求的边沿检测器组成, 每个输入线可以被独立的配置为脉冲或挂起和对应的触发事件(上升沿、下降沿、双边沿),每个输入线都能够被独立的屏蔽掉。EXTI控制器主要特点如下:
1) 支持多达19个中断/事请求
2) 每个中断/事件都有独立的触发和屏蔽;
3) 每个中断线都有专用的状态位;
STM32外部中断实现红外脉宽测量的原理为:检测到红外脉冲下降沿后,进入中断处理函数,然后分别对红外信号的高和低电平进行测量,并把测量的结果的暂存到一个临时数组中。软件流程图如下图所示:
程序代码如下:
在硬件仿真下点全速运行的按钮,然后用红外设备对着红外一体接收管按下按键,在Watch1窗口查看数组中数据是否在协议规定范围内。然后把该数据调制后发送给接收设备,看它和原始红外设备发送码数据是否一致。接收到的脉宽数据如下图所示:
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据设计内容要求可知: 1)用STAR ES598PCI单板开发机设计一个应用接口芯片作为八个七段LED数码管的段选与位选。接口可以使用8255A或8279(本实验用了8255A)。 2)编写程序实现红外装置发送的编码代表的动作(左移LEFT和右移RIGHT)显示再七段数码管上,并实现LEFT的左循环移动,RIGHT的右循环移动。 3)用按键控制接口控制所要进行的操作,用一个按键控制左移用另一个按键控制右移,按住按键不放则为左循环或右循环。 2.解决问题方法及思路 1)硬件部分 (1)由于8251A和红外之间的数据传输涉及到要协调一致,所以本实验另外还要选用8253A作为频率发生器,输出一定的方波到8251A。 (2)本次设计要求通过按键来进行操作,本来想用小键盘使得程序更加高级一些,但考虑到所需功能不多,只需两个按键即可,所以采用了按键控制接口。 (3)输出设备选用的是LED七段数码管。本实验只是要将LED上的内容左移右移,左循环和右循环,LED即可满足要求。 (4)8255A的可编程并行接口,本实验通过8255A将按键的信息送入,并且使用8255A对LED进行段选和位选,而且8255A具有传输速度快效率高等优点,此既可以节约芯片的使用,还具有较好的性能,因此选用。 (5)由于红外装置接收和发送的都是串行数据,所以本实验选用8251A作为CPU和红外装置之间数据的串并转换,8251A将CPU的并行数据转换为串行数据送至红外,将红外的串行数据转换为并行数据送至CPU。 至此,我们可以确定本次课程设计用到的部件有:2个按键作为遥控器按钮,LED作为显示,8253用作频率发生器,8255用来作为输入输出接口,8251A用来传送数据。 2)软件部分 (1)对8253进行初始化。8253作为频率发生器,选用计数器0,控制字为35H,工作在方式2,并且将计数初值设为26,因为2000000/26=16*4800。这样发送和接受数据的时钟频率就是数据传输频率即波特率的16倍,这样可以提高收发数据的正确性,再将输出频率送至8251的RXC和TXC,一定程度上保证了数据传输的正确性。 (2)对8255进行初始化。PC口作为输入口,本实验中只用了PC0和PC7与按键控制接口相连,接收按键要控制的相关状态。开始时,通过置为/复位控制字,将1和8按键置为1,即置为控制字是01H和0FH,之所以设为1因为按键按下时是0信号,松开时1信号,程序运行时,检查C口读入的按键,若为1按键,即为左移,若为8按键,则为右移。PA口与PB口均作为输出口,其中PA口作为位选,用来选择发光的LED管,在控制时,我们是将要亮的管子位置数为0,其它位置为1,PB口作为段选,用来控制输出的值。 (3)对8251A进行初始化。8251A作为本实验中最重要的芯片,就是起了传送并转换数据的作用,8251A将CPU的并行数据转换为串行数据送至红外,将红外的串行数据转换为并行数据送至CPU。将8251A的方式控制字设为5EH, ;波特率系数为16,8个数据位,1个停止位,奇校验,命令控制字设为17H,允许接受和发送数据,清错误标志。程序运行后,检查状态寄存器,若为01H,则是允许发送,则将左移或右移信息码发送至红外,否则持续读状态寄存器。接收时,读状态寄存器,若为02H,则是接收准备好,则从红外接收数据。 (4)CPU在发送数据时,先比较C口读入的数据,若是1按键,则将左移信息码40H写至8251A,若是8按键,则将右移信息码41H写至8251A;在接收数据时,若收到的是左移信息码,则左移1位位选,写入8255A,使LED上的数据左移一位,若收到的是右移信息码,则右移1位位选,写入8255A,使LED上的数据右移一位。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值