学习型通用红外遥控设备(二)

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内核的逻辑紧密耦合、相互交融,共同完成对中断的控制。

STM32有两个优先级概念—抢占式优先级和响应优先级,响应优先级又被称为亚优先级或副优先级,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窗口查看数组中数据是否在协议规定范围内。然后把该数据调制后发送给接收设备,看它和原始红外设备发送码数据是否一致。接收到的脉宽数据如下图所示:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值