在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();
}
}
kqian0327:
你好,
关于红外,我想问一下你是做发送端还是接收端。
如果你发现接收不到数据,你可以把示波器的波形截取出来吗?
你红外管用的是哪家的?
建议你把波形截图出来,和红外编解码芯片的波形一一对比,多少情况是你解码的时序和红外芯片的规定不一样造成解码数据不成功。