求助,红外遥控灯的开关,代码基本无错,但是无法实现

2019-03-24 11:35发布

在CCS平台上实现的,单片机是 MSP430 ,F5529
用红外遥控控制等的开关,思路很简单,但是不知错在哪里。


//******************************************************************************
//   MSP430F552x Demo - Software Toggle P1.0
//
//   Description: Toggle P1.0 by xor'ing P1.0 inside of a software loop.
//   ACLK = 32.768kHz, MCLK = SMCLK = default DCO~1MHz
//
//                MSP430F552x
//             -----------------
//         /||                 |
//          | |                 |
//          --|RST              |
//            |                 |
//            |             P1.0|-->LED
//
//   Bhargavi Nisarga
//   Texas Instruments Inc.
//   April 2009
//   Built with CCSv4 and IAR Embedded Workbench Version: 4.21
//******************************************************************************
#include <msp430f5529.h>
#include "control.h"

/*------------------------------------------------
                全局变量声明
------------------------------------------------*/
#define CPU_F ((double)1000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/8000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define IRIN        (P2IN&BIT0)   // 红外接收头输入值P2.0
unsigned char data[4]={0x00,0xff,0x45,0x3d};                          //        保存地址码,地址反码,数据码,数据反码
unsigned char data_ready=0;    //  数据采集完成标志位

/*------------------------------------------------
                系统初始化
------------------------------------------------*/
void InitSystem()
{
        P2DIR&=~BIT0 ;               //红外接收头P2.0设置为输入
        P2REN|=BIT0;                        //设置上拉电阻
        P2IES|=BIT0;            //P2.0下降沿触发中断
        P2IFG&=~BIT0;                //中断标志寄存器清零
        P2IE|=BIT0;              //P2.0中断功能打开
        _EINT();                //打开全局中断控制
}

/*------------------------------------------------
                  键值处理
------------------------------------------------*/

void Ir_work(void)//实现程序
{
        if(data_ready==1)
                        {
                                data_ready=0;          //进入后标志位复位
                                _DINT();                //关闭中断,以免此时再收到红外信号干扰
                          switch(data[2])//判断第三个数码前两个是用户码,最后一个是反码,第三个才是真正的数据码。
                                                 {
                                                         case 0x16:
                                                                 P2REN &= ~BIT1;
                                                                 P2OUT &= ~BIT1;
                                                                 P2IES &= ~BIT1;
                                                                 P2IFG |=  ~BIT1;
                                                                 P2IE &= ~BIT1;
                                                                 __bis_SR_register(LPM4_bits+GIE);
                                                                 break;//0 按下遥控器上面0-9的按键,数码管显示相应的按键值
                                                         case 0x0c:
                                                                 P2REN |=BIT1;
                                                                 P2OUT|=BIT1;
                                                                 P2IES|=BIT1;
                                                                 P2IFG &= ~BIT1;
                                                                 P2IE|=BIT1;
                                                                 __bis_SR_register(LPM4_bits+GIE);
                                                                 break;//1
                                             default:break;
                                                         }
                                _EINT();                //再次打开全局中断,进行下一次红外信号接收
                        }

}

/************端口2中断函数*************/
#pragma vector=PORT2_VECTOR   //
__interrupt void Port_2(void)
{
        unsigned char i,j,k=0,flag=1,n=0;
        if((P2IFG&BIT0) == BIT0) //判断中断标志位 是否由P2.0 引起
        {
                P2IFG &= ~BIT0;         //清除P2.0中断标志
                P2IE &=~BIT0;           //关闭P2.0中断功能
                for (i=0;i<8;i++)        //等待9mS前导码  低电平
                {
                        delay_ms(1);
                        if (IRIN==1) flag=0;        //在9ms内出现高电平则退出解码,不进行数据采集
                }
                while(!IRIN);        //等 IR 变为高电平
                delay_ms(4);         //等待4.5ms前导码 高电平
                if(flag==1)    //进行数据采集的条件
                {
                        while (IRIN);       //等 IR 变为低电平
                        for(k=0;k<4;k++)                //4组数据  4个字节  一共32位   低字节在前
                        {
                                for (j=0;j<8;j++)
                                {
                                        n=0;
                                        delay_us(500);      //等待560us低电平
                                        while (!IRIN);     //等 IR 变为高电平
                                        while (IRIN)       //计算IR高电平时长
                                                {
                                                delay_us(140);
                                                n++;
                                                }
                                        data[k]=data[k]>>1;                //        低位在前接收到 所以右移
                                        if (n<7)
                                                        data[k]&=0x7f;  //        高电平时间小于140us*7则是数据 0
                                        else if(n>=7&&n<13)
                                                        data[k]|=0x80;        //        高电平时间大于140*7小于140*13则是数据 1
                                        else if (n>=13)
                                                        P2IE|=BIT0;    //        无效数据
                                }
                        }
                data_ready=1;          //        数据采集完成标志位
                }
        }
        P2IFG=0;         //        退出中断前再次开启中断使能

}

/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main(void)
{
        WDTCTL = WDTPW + WDTHOLD;         //关闭看门狗
        InitSystem();
while(1)//主循环
   {
         Ir_work();
   }
} 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
2条回答
QQ浩
2019-03-24 13:38
< :TI_MSP430_内容页_SA7 -->
kemasz 发表于 2014-5-7 14:30
那为什么实现不了呢???应该还差点啥吧~~~

那么究竟是差了什么呢?

一周热门 更多>

相关问题

    相关文章