MSP430开发笔记之五:硬件IO中断与IR红外接收

1、MSP430F149中断系统

本次使用MSP430F149这款芯片,因为最近正在用。
中断向量地址表
MSP430中断向量地址使用16位地址,其中GPIO中断只有P1口和P2口有中断功能,并且P1口中断和P2口中断是多中断源公用一个中断入口,如果使用了P1口或者P2口的多个引脚作为中断输入,需要在中断服务函数中判断具体的中断引脚。

2、GPIO中断方式使用

P1口和P2口使用中断方式,比较简单。

  • 第一步:PxDIR 寄存器对应的引脚位清零,作为输入使用;
  • 第二步:PxIES 寄存器对应的引脚位选择:1:下降沿中断;0:上升沿中断;
  • 第三步:PxIE 寄存器对应的引脚位置1,使能IO中断;
  • 第四步:(必要的话)PxIFG 寄存器对应的引脚位清零,清除不必要的中断事件;

3、 某红外遥控器发射红外信号波形分析

红外波形
以上波形是一体化红外接收头1838接收后,逻辑分析仪捕获到的5个按键的波形。红外信号无效时,1838输出高电平,当有按键按下时,会发射红外编码信号,根据图中可以看到比较有规则的脉冲波形,有12个周期。“0”和“1”的周期是一样的,大概1.27ms,区别是代表“0”和代表“1”的高电平和低电平持续时间正好相反。根据这个特性,再结合MSP430 gpio的下降沿中断作为接收开始信号,就可以得到最后的结果,从而判断遥控器按下的是哪个按键。

4、程序编写

4.1 初始化:

#define CPU_F ((double)8000000)
#define delay_us(x)  __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x)  __delay_cycles((long)(CPU_F*(double)x/1000.0))

#define IR_PIN 2  //这里使用P1.2
#define  bit(X)  (1<<X)
#define READ_P1_GPIO_PIN_INVERT(GPIO_PIN)  ( (P1IN & bit(GPIO_PIN)) ^ bit(GPIO_PIN) ) //低电平有效转换成高电平有效
#define READ_P1_GPIO_PIN(GPIO_PIN)  (P1IN & bit(GPIO_PIN))
#define READ_IR() READ_P1_GPIO_PIN_INVERT(IR_PIN)
/**
 * @description:开中断
 * @return {none}
 */
void ir_irq_enable()
{
    P1IE |= (bit(IR_PIN)); // 1:ENABLE
    P1IFG &= ~(bit(IR_PIN));
}
/**
 * @description:关中断
 * @return {none}
 */
void ir_irq_disable()
{
    P1IE &= ~(bit(IR_PIN)); // 0:DISABLE
}
/**
 * @description:红外接收头初始化
 * @return {none}
 */
void ir_init(void)
{
    P1DIR &= ~(bit(IR_PIN)); // 0:INPUT
    P1IES |= (bit(IR_PIN));  // FALLING EDGE
    ir_irq_enable();
}

4.2 中断服务函数

volatile static uint8_t ir_cnt; 
volatile uint16_t ir_code;//保存红外遥控器键值
/**
 * @description:红外接收中断服务函数
 * @return {none}
 */
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = PORT1_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(PORT1_VECTOR)))
#endif
void exti_ISR(void)
{
    uint16_t t = 0;
    //红外中断
    if (P1IFG & bit(IR_PIN))
    {
        P1IFG &= ~(bit(IR_PIN));
        ir_irq_disable();
        ir_cnt = 0;
        ir_code = 0;
        while(ir_cnt <=12)
        {
            delay_us(600);
            if(READ_IR())
            {
                ir_code |= (1<<ir_cnt);
                while(READ_IR());
            }
            if(ir_cnt == 12)
            {break;}
            else
            {
                ir_cnt++;
                while (READ_IR() == 0)
                {
                    delay_us(5);
                    if(t++ >500)
                    {
                        ir_cnt = 13;
                        break;
                    }
                }
                t = 0;
            }
        }
        delay_ms(10);
        LED_OFF();
        ir_irq_enable();
    }
}
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值