MSP430单片机按键中断程序

发布者:EnigmaticSoul最新更新时间:2018-01-29 来源: eefocus关键字:MSP430  单片机  按键中断 手机看文章 扫描二维码
随时随地手机看文章

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


关键字:MSP430  单片机  按键中断 引用地址:MSP430单片机按键中断程序

上一篇:基于MSP430F435的国内血糖仪
下一篇:MSP430单片机按键程序

推荐阅读最新更新时间:2024-03-16 15:53

英飞凌推出全新MCU系列产品 进军摩托车引擎控制应用领域
英飞凌科技股份公司(FSE/NYSE: IFX)近日推出了全新微控制器系列,瞄准不断增长的全球摩托车引擎控制市场。 具有32位性能的XC2700系列微控制器以其卓越的性能将助力全球系统制造商打造经济高效的摩托车电子引擎装置,并满足即将颁布的排放标准要求。中国和印度是世界上最大的摩托车市场,将在明年推出更加严格的排放控制标准,这进一步推动了市场对经济高效的电子引擎管理系统的需求。 预计到2010年,印度的摩托车产量将达到1500万辆,远高于2005年的670万辆。中国到2010年的摩托车产量更将高达2100万辆,而2005年则为1700万辆。尽管当前对摩托车的油耗和排放方面的要求越来越高,但是这些地区的消费者要求摩托车的销售价格
[单片机]
51单片机学习之路 —— 1.8 矩阵键盘
1 什么是矩阵键盘?     这里补一个键盘的定义                            大家看原理图,这就是矩阵键盘(4*4)     四行 分别连到P3.0 P3.1 P3.2(INT0) P3.3(INT1) (从上到下)     四列 分别连到P3.4(LCDEN) P3.5(RS) P3.6(WR) P3.7(RD)(左到右) 2         独立键盘一端固定位低电平! 检验较为方便     但矩阵键盘不一样,他两边都与单片机的I/O相连接。所以检测方法有些不同     要人为送出低电平,我们采取以下的检测方法:     1.  先送一列为低电平,其余几列都为高电平(用此来确定列数
[单片机]
51<font color='red'>单片机</font>学习之路 —— 1.8 矩阵键盘
一种简单实用的STC89C52RC编程器设计方案
1 引言 STC(宏晶科技)公司推出的STC 89C/S 51XX/52XX 等系列单片机,具有价格便宜、无法解密、低功耗、高速、高可靠、强抗静电、强抗干扰等优点,其指令代码完全兼容传统8051 单片机,片内资源非常丰富,且均内置可反复擦写的Flash 存储器,并提供了ISP(In-System Programming)编程模式。STC89C52RC 作为STC 89C/S51XX/52XX 系列单品机的一个典型代表,其特征主要有,8K 字节可编程闪烁存储器、1000 次写/ 擦循环寿命、10 年的数据保留时间、三级程序存储器锁定、512 内部RAM、32 可编程I/O 线、两个16 位定时器/ 计数器、5 个中断源、可编程串行
[单片机]
一种简单实用的STC89C52RC编程器设计方案
基于MSP430自动胀管控制器的研制
胀管机是针对冷凝器、冷油器、加热器、换热器中各类管材与管板胀接需要而设计开发的一种专用设备。其控制器的基本原理是用驱动电机(又称驱动马达、胀管机头)的工作电流来标定所加载的负荷,即驱动电机在一定的工作电流值下,提供相当数量的扭矩,而与之相当数量的扭矩可以通过旋转胀管器产生一定的膨胀量(胀力),它是可以被测量的。因此,通过精确测量并控制驱动马达的工作电流值,就可获得并控制所需要的膨胀量(胀力)。 目前,市场上大多数的胀管机采用51单片机,但其缺点比较突出。如内部无存储器,必需外接Flash或EPROM存储设置信息,这就导致电路比较复杂,不利于扩展,且工作电压范围较窄,抗干扰能力较差。而采用 MSP430F149 单片机的胀管机
[工业控制]
基于<font color='red'>MSP430</font>自动胀管控制器的研制
51单片机中断的实现过程
我们首先需要了解什么是中断? 中断是指cpu在执行某一过程中由于外界原因必须暂停现在的事情,处理别的事情,处理完了再回去执行暂停的事情。 中断的优点? 1.分时操作。 2.实时响应 3.可靠性高 中断中用到的寄存器: IE寄存器: 1.单路开关:EX0 ET0 EX1 ET1 ES EX0:外部中断0允许位 ET0:定时/计数器T0中断允许位 EX1:外部中断1允许位 ET1:定时/计数器T1中断允许位 ES:串行口中断允许位 2.总开关 EA:CPU中断允许位 EA=1打开 IP寄存器: 作用是选择优先级的,解决中断优先级问题。 IT0寄存器:选择低电平有效还是下降沿有效,上电默认电平触发方式,IT0=1是下降沿有效
[单片机]
第18节:把74HC595驱动程序翻译成类似单片机IO口直接驱动的方
开场白: 上一节讲了74HC595的驱动程序。为了更加方便操作74HC595输出的每个IO状态,这节讲如何把74HC595驱动程序翻译成类似单片机IO口直接驱动的方式。要教会大家两个知识点: 第一点:如何灵活运用与和非的运算符来实现位的操作。 第二点:如何灵活运用一个更新变量来实现静态刷新输出或者静态刷新显示的功能。 具体内容,请看源代码讲解。 (1)硬件平台:基于朱兆祺51单片机学习板。 (2)实现功能:两片联级的74HC595驱动的16个LED灯交叉闪烁。比如,先是第1,3,5,7,9,11,13,15八个灯亮,其它的灯都灭。然后再反过来,原来亮的就灭,原来灭的就亮。交替闪烁。 (3)源代码讲解如下:
[单片机]
avr单片机的数码管显示时钟设计
//数码管数据P0口,数码管控制P2口 #include #include #includePACe.h》 #include #include #definecodePROGMEM #defineucharunsignedchar #defineuintunsignedint codeconstucharLED_7[16]={0x28,0x7E,0xA2,0x62,0x74,0x61,0x21,0x7A,0x20,0x60,0xff};//commonof+ codeconstucharposi ti on[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; uchar TI me[
[单片机]
avr<font color='red'>单片机</font>的数码管显示时钟设计
凌阳单片机SPCE061A实现语音电压表
SPCE061A简介 工作电压 :DC 3.6~5.0V 工作电流 := 50mA 开发板资源 : (1)CPU:SPCE061A (SUNPLUS unSP),外部时钟为 32768Hz,内部倍频最高可至49MHz (2)Flash ROM:64Kbyte的 16bit Flash (3)RAM:4KByte的16bit SRAM (4)I/O:32位IO口 (5)ADC:8路10位ADC. 最高转换速率为96KHz。留有外接AD参考电压接口 (6)DAC:2路10位DAC,最高转换速率为100KHz (7)麦克风:1路MIC音频输入 (8)喇叭接口:开发板配备喇叭 (9)音量调节电位器:用于调整音量的大小 (10)端口电平
[电源管理]
凌阳<font color='red'>单片机</font>SPCE061A实现语音电压表
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved