#include "IRRemote.h"
void main(void)
{
//初始化
Initialize();
//死循环
while(1)
{
unsigned int transmit;
//初始化变量
transmit = ENDTRANSMIT;
//等待按键按下
SetForPress();
//进入LPM4模式
LPM4;
Debounce();
//扫描键盘
KeySCAN();
//键盘处理
KeyLookup();
if (Error_Flags == 0)
{
//有键按下的情况
SetupForRelease();
do
{
//传输数据(RC5码)
Transmit();
transmit = TestRetransmit();
//延时
DelayToNextTransmit();
} while (transmit == RETRANSMIT);
}
}
}
void Initialize(void)
{
//停止看门狗
WDTCTL = WDTPW+WDTHOLD;
//P2口为输出
P2DIR = 0xFF;
//P2.3为TA1功能管脚
P2SEL = 0x08;
//清除P2口的输出
P2OUT = 0;
//设置DCO频率为1MHz
DCOCTL = CALDCO_1MHZ;
BCSCTL1 = CALBC1_1MHZ;
//使能中断
_EINT();
}
void SetForPress(void)
{
//P1.0和P1.1为输入
P1DIR = 0xFC;
//清除P1口的输出,下拉
P1OUT = 0;
//使能P1.0和P1.1的电阻
P1REN |= 0x03;
//使能键盘
P2OUT |= 0x07;
//低到高中断方式
P1IES &= ~0x03;
//清除中断标志
P1IFG = 0;
//使能中断
P1IE |= 0x03;
//清除错误标志
Error_Flags = 0;
//清除传输标志
Trans_Flags = 0;
}
void Debounce(void)
{
//SMCLK/8,清除TA
TACTL = TASSEL1+TACLR+ID0+ID1;
//使能CCR0中断
TACCTL0 = CCIE;
//设置延时的值
TACCR0 = 5000 - 1;
//开始UP模式
TACTL |= MC0;
//进入LPM0模式
LPM0;
//停止并清除TA
TACTL = TACLR;
//清除CCTL0寄存器
TACCTL0 = 0;
}
void KeyScan(void)
{
unsigned int i;
//初始化行
RowMask = 0x01;
KeyHex = 0;
//清除行的值
P1OUT &= ~0x03;
for (i=0; i < 3; i++)
{
P2OUT &= ~0x07;
P1DIR |= 0x03;
P1OUT &= ~0x03;
P1DIR &= ~0x03;
P2OUT = RowMask;
if (P1IN & 0x03)
{
//是否有键按下
KeyHex |= RowMask;
//处理值
KeyHex |= (P1IN & 0x03) << 4;
}
//下一行
RowMask = RowMask << 1;
}
if (KeyHex == 0)
{
//设置标志
Error_Flags |= noKey;
}
P2OUT |= 0x07;
}
void KeyLookup(void)
{
unsigned int i;
//初始化值
KeyPressed = 99;
for (i = 0; i < 6; i++)
{
//查表
if (KeyTab[i] == KeyHex)
{
KeyPressed = i;
}
}
if (KeyPressed == 99)
{
//没有找到值
//设置标志
Error_Flags |= noMatch;
}
}
void SetupForRelease(void)
{
//设置方向
P1DIR |= 0x03;
P1OUT |= 0x03;
//键被按下
Trans_Flags |= hELDDown;
}
void DetermineRelease(void)
{
//设置输入下拉
P1OUT &= ~0x03;
P1DIR &= ~0x03;
if (P1IN & 0x03)
{
SetupForRelease();
}
else
{
Trans_Flags &= ~heldDown;
}
}
void Transmit(void)
{
unsigned int i;
//得到命令码
Command = FuncTab[KeyPressed];
//增加两个位的起始位
Command = Command + 0x3000;
if (Trans_Flags & toggle)
{
// 切换位
Command = Command + 0x0800;
}
//左移
Command = Command << 2;
//CCR1 PWM参数
TACCR1 = 7;
//使能CCR0中断
TACCTL0 = CCIE;
for (i=0; i < 14; i++)
{
//判断是1还是0
if (Command & 0x8000)
{
//先发送780us的低
OutputLow(780);
//然后高,记数32个中断
OutputHigh(32);
}
else
{
//先高,记数35个中断
OutputHigh(35);
OutputLow(765);
}
//下一个位
Command = Command << 1;
}
//停止并清除TA
TACTL = TACLR;
}
unsigned int TestRetransmit(void)
{
//P1是否有输入
if (P1IFG == 0)
{
//没有输入的情况下
return RETRANSMIT;
}
else
{
//有输入的情况下
//是否有按键按下
DetermineRelease();
if (Trans_Flags & heldDown)
{
//有的情况下
return RETRANSMIT;
}
else
{
// 没有的情况下,返回主程序
//清除CCTL0寄存器
TACCTL0 = 0;
//清除CCTL1寄存器
TACCTL1 = 0;
//清除切换位
Trans_Flags &= ~toggle;
return ENDTRANSMIT;
}
}
}
void DelayToNextTransmit(void)
{
//SMCLK/8 清除TA
TACTL = TASSEL1+TACLR+ID0+ID1;
//89ms的中断
TACCR0 = 11125 - 1;
//使能CCR0中断
TACCTL0 = CCIE;
//TA开始UP模式
TACTL |= MC0;
//延时
LPM0;
//停止并清除TA
TACTL = TACLR;
//切换切换位
Trans_Flags ^= toggle;
}
void OutputHigh(unsigned int val)
{
unsigned int j;
//CCR1 RESET/SET
TACCTL1 = OUTMOD_7;
//PWM周期(40kHz)
TACCR0 = 25 - 1;
//清除TA
TACTL = TASSEL1+TACLR;
//TA开始UP模式
TACTL |= MC0;
for (j = val; j > 0; j--)
{
// 中断记数
//周期40kHz时,每个中断的时间为25us
LPM0;
}
}
void OutputLow(unsigned int val)
{
// 设置CC1的输出为0
TACCTL1 = OUTMOD_0;
//清TA
TACTL = TASSEL1+TACLR;
//延时
TACCR0 = val;
//设置TA为UP模式
TACTL |= MC0;
//进入LPM0模式,等待CCR0中断
LPM0;
}
// P1.x 中断服务程序
#if __VER__ < 200
interrupt [PORT1_VECTOR] void P1_ISR(void)
#else
#pragma vector=PORT1_VECTOR
__interrupt void P1_ISR(void)
#endif
{
//退出LPM4低功耗模式
LPM4_EXIT;
//清除中断标志
P1IFG = 0;
//中断不使能
P1IE = 0;
}
// CCR0 中断服务程序
#if __VER__ < 200
interrupt [TIMERA0_VECTOR] void CCR0_ISR(void)
#else
#pragma vector=TIMERA0_VECTOR
__interrupt void CCR0_ISR(void)
#endif
{
//退出LPM0低功耗模式
LPM0_EXIT;
}
IRRemote.h
#include "MSP430x21x1.h"
#define noKey 0x001
#define noMatch 0x002
#define heldDown 0x001
#define toggle 0x002
#define RETRANSMIT 1
#define ENDTRANSMIT 0
// 按键查询表
const char KeyTab[6] = {
0x11, // 按键 0
0x21, // 按键 1
0x12, // 按键 2
0x22, // 按键 3
0x14, // 按键 4
0x24 // 按键 5
};
// 函数查询表
const char FuncTab[6] = {
0x0C, // 按键 0 - 电源
0x0D, // 按键 1 - 静音
0x20, // 按键 2 - 频道+
0x10, // 按键 3 - 音量+
0x21, // 按键 4 - 频道-
0x11 // 按键 5 - 音量-
};
unsigned int RowMask;
unsigned int KeyHex;
unsigned int KeyVal;
unsigned int KeyPressed;
unsigned int Command;
unsigned int Trans_Flags;
unsigned int Error_Flags;
void Initialize(void);
void SetForPress(void);
void Debounce(void);
void KeyScan(void);
void KeyLookup(void);
void SetupForRelease(void);
void DetermineRelease(void);
void Transmit(void);
unsigned int TestRetransmit(void);
void DelayToNextTransmit(void);
void OutputHigh(unsigned int);
void OutputLow(unsigned int);