刚学单片机(msp430f149 DM430-A),试了试红外接头(1838),读取红外遥控器的键值,并以十进制显示在数码管上,如果以后准备将这个遥控器作为其他用途还可以把数码管上的键值化成16进制使用如(74——0x4A)。
如果有哪里不正确,期待大家给我改正,共同进步!
(部分代码摘自网络)
#include
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#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))
uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//红外接收头H1838控制脚,单脚控制
#define RED_IN P1DIR &= ~BIT3 //设置输入,红外接收头接单片机P13口
#define RED_OUT P1DIR |= BIT3 //设置输出
#define RED_L P1OUT &= ~BIT3 //置低电平
#define RED_H P1OUT |= BIT3 //置高电平
#define RED_R (P1IN & BIT3) //读电平
#define LED8PORT P2OUT //P2接8个LED灯
#define LED8SEL P2SEL //P2接8个LED灯
#define LED8DIR P2DIR //P2接8个LED灯
#define DATAPORT P4OUT //数据口所在端口P4
#define DATASEL P4SEL //数据口功能寄存器,控制功能模式
#define DATADIR P4DIR //数据口方向寄存器
#define CTRPORT P6OUT //控制线所在的端口P6
#define CTRSEL P6SEL //控制口功能寄存器,控制功能模式
#define CTRDIR P6DIR //控制口方向寄存器
#define DCTR0 P6OUT &= ~BIT4 //数码管段控制位信号置低
#define DCTR1 P6OUT |= BIT4 //数码管段控制位信号置高
#define WCTR0 P6OUT &= ~BIT3 //数码管位控制位信号置低
#define WCTR1 P6OUT |= BIT3 //数码管位控制位信号置高
//***********************************************************************
// 系统时钟初始化
//***********************************************************************
void Clock_Init()
{
uchar i;
BCSCTL1&=~XT2OFF; //打开XT2振荡器
BCSCTL2|=SELM1+SELS; //MCLK为8MHZ,SMCLK为8MHZ
do{
IFG1&=~OFIFG; //清楚振荡器错误标志
for(i=0;i<100;i++)
_NOP();
}
while((IFG1&OFIFG)!=0); //如果标志位1,则继续循环等待
IFG1&=~OFIFG;
}
//***********************************************************************
// MSP430内部看门狗初始化
//***********************************************************************
void WDT_Init()
{
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
}
uchar KEY_VAL=0;
uchar code_value=0;
uchar key_code[4],code='_';
//红外接收头H1838控制脚,单脚控制
//***********************************************************************
// MSP430IO口初始化
//***********************************************************************
void Port_Init()
{
LED8SEL = 0x00; //设置IO口为普通I/O模式,此句可省
LED8DIR = 0xFF; //设置IO口方向为输出
LED8PORT = 0xFF; //P2口初始设置为FF
DATASEL = 0x00; //设置IO口为普通I/O模式,此句可省
DATADIR = 0xFF; //设置IO口方向为输出
DATAPORT = 0xFF; //P4口初始设置为FF
CTRSEL = 0x00; //设置IO口为普通I/O模式,此句可省
CTRDIR |= BIT3 + BIT4; //设置IO口方向为输出,控制口在P63,P64
CTRPORT = 0xFF; //P6口初始设置为FF
RED_L;
RED_IN;
}
//*************************************************************************
// 显示采集到的数据到LED灯
//*************************************************************************
void Display_Time(uchar Time)
{
uchar i,j;
j=0x01; //此数据用来控制位选
for(i=0;i<5;i++) //用后2位数码管来显示
{
DCTR1;
WCTR1;
DATAPORT=~j;
WCTR0;
j=(j<<1);
DATAPORT=0x00; //前6位都不显示,送数据00即可
DCTR0;
delay_ms(2);
}
DCTR1; //开始显示100位
WCTR1;
DATAPORT=~j;
WCTR0;
j=(j<<1);
DATAPORT=table[Time/100]+0x80;
DCTR0;
delay_ms(1);
DCTR1; //开始显示10位
WCTR1;
DATAPORT=~j;
WCTR0;
j=(j<<1);
DATAPORT=table[Time/10]+0x80;
DCTR0;
delay_ms(1);
DCTR1; //开始显示个位
WCTR1;
DATAPORT=~j;
WCTR0;
j=(j<<1);
DATAPORT=table[Time%10]+0x80;
DCTR0;
delay_ms(1);
DCTR1;
WCTR1;
DATAPORT=0xff;
WCTR0;
}
//*************************************************************************
// 遥控器解码子程序
//*************************************************************************
void Red_Code()
{
uchar i,j,k = 0;
for(i = 0;i < 19;i++)
{
delay_us(400); //延时400us
if(RED_R) //9ms内有高电平,则判断为干扰,退出处理程序
{
return;
}
}
while(!RED_R); //等待9ms低电平过去
for(i=0;i<5;i++) //是否连发码
{
delay_us(500);
if(!RED_R)
{
return;
}
}
while(RED_R); //等待4.5ms高电平过去
for(i = 0;i < 4;i++) //接收4个字节的数据
{
for(j = 0;j 22) //高电平时间过长,则退出处理程序
{
return;
}
}
code_value>>=1; //接受一位数据
if(k >= 7)
{
code_value|=0x80; //高电平时间大于0.56,则为数据1
}
k = 0; //计时清零
}
key_code[i]=code_value; //四个字节的数据
}
Display_Time(key_code[2]);
delay_ms(50);
}
//***********************************************************************
// 主程序
//***********************************************************************
void main(void)
{
WDT_Init(); //看门狗初始化
Clock_Init(); //时钟初始化
Port_Init(); //端口初始化,用于控制IO口输入或输出
while(1)
{
Red_Code(); //调用遥控器解码子程序
}
}