首 页文档资料下载资料维修视频包年699元
请登录  |  免费注册
当前位置:精通维修下载 > 文档资料 > 家电技术 > 单元电路介绍 > 其它电路
MSP430单片机按键中断程序
来源:本站整理  作者:佚名  2011-08-04 10:14:13




#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);

关键词:

·上一文章:c8051F040液晶显示程序
·下一文章:MSP430单片机按键程序

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分)
Copyright © 2007-2017 down.gzweix.Com. All Rights Reserved .
页面执行时间:26,335.94000 毫秒