按键的下降沿和低电平的问题

2019-03-24 09:40发布

请教各位,按键原来是下降沿有效,但我想把按键改为低电平有效,应该怎么改呢,是把原来的下降沿中断去掉吗?
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
16条回答
crysislove
1楼-- · 2019-03-26 11:26
本帖最后由 crysislove 于 2015-11-19 00:12 编辑
qiushenghua 发表于 2015-11-18 16:59
过了两天不见楼主重写程序,看样子楼主已经没有在做这个项目了,那么就不上参考代码了。

首先感谢版主大大上心啊,非常抱歉啊,这两天我一直在忙其他事,所以没有上论坛回复。然后下面是我对低功耗的认识和了解以及用定时器中断改写的代码请版主指导指导。下面这段代码我想要实现的是:当P1.3按键按下不放的时候,P1.0 和P1.6保持亮的状态,当按键松开的时候两个的是灭的状态。代码编译没错,但是下载之后,没有实现上面的功能。

低功耗模式也叫休眠模式是一种间歇式工作方式。通过间歇性的方式来启动和停止系统时钟,就可以开启低功耗模式。
MSP430G2553的CPU有5种工作模式: AM(Active Mode)、LPM0(Low Power Mode 0)、LPM1、LPM2、LPM3。后四种为低功耗模式。有些程序中的CPUOFF也是休眠模式。
LMP0模式:CPU、MCLK停用,SMCLK,ACLK激活。
LMP1模式:CPU、MCLK、如果DCO(数控振荡器)不作为SMCLK源的时候停用,ACLK激活。
LMP2模式;CPU、MCLK、SMCLK、DCO停用。ACLK激活。
LMP3模式:CPU、MCLK、SMCLK、DCO停用。ACLK激活。(与LMP2模式不同的是LMP3模式SR寄存器的SCG0置1了)
LMP4模式:CPU、MCLK、SMCLK、DCO、ACLK停用。
常用的模式是LPM0、LPM3。如果想用LMP3模式,在主程序的最后调用内函数_bis_SR_register(LPM3_bits),如果是退出LMP3模式则调用内部函数_bic_SR_register_on_exit(LPM3_bits)。
代码如下:
#include "MSP430G2553.h"
void WDT_init();
void P1_IODect();
void P13_Onclick();

void main(void)
{
        WDTCTL = WDTPW + WDTHOLD;
        P1DIR |= BIT0+BIT6;
        P1OUT |= BIT0;
        P1OUT |= BIT6;

        P1REN |= BIT3;
        P1OUT |= BIT3;
        WDTCTL = WDT_ADLY_16;
        IE1 |= WDTIE;
        _enable_interrupts();
        _bis_SR_register(LPM3_bits);
                }

#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR(void)
{
P1_IODect();
}

void P1_IODect()
{
    unsigned char KEY_1=0;
        if(P1IN&BIT3) //如果BIT3的值为1,
                KEY_1=1;
        else KEY_1=0;
        while(KEY_1==0)
        P13_Onclick();
}

void P13_Onclick() //P1.3的事件处理函数
{
        P1OUT ^= BIT0;
        P1OUT ^= BIT6;
}

qiushenghua
2楼-- · 2019-03-26 11:39
本帖最后由 qiushenghua 于 2015-11-19 02:01 编辑

下面这个是刚刚在楼主程序基础上修改后的结果,读懂这段程序,大概就能理解MSP430的低功耗模式是怎么回事了。

  1. #include "MSP430G2553.h"
  2. void WDT_init();
  3. void P1_IODect();
  4. void P13_Short_Click();
  5. void P13_Long_Click();

  6. char count=0;                                      //用来统计按键按下的时间占据了多少个定时中断周期
  7. unsigned char KEY_STATE=0;                //定义一个变量储存按键状态
  8. unsigned char KEY_LAST_STATE=0;       //再定义一个变量储存上次检测到的按键状态


  9. void main(void)
  10. {
  11.         /*下面这几句是配置时钟源的,自己看着改*/
  12.         BCSCTL3 |= LFXT1S_2;                // 将VLO作为ACLK时钟源
  13.         WDTCTL = WDT_ADLY_16;          // 使用内部的16ms看门狗中断,不过这个时间是用32768晶振算出来的,实际中断周期为                                                                                // 16ms/12k*32k=44ms
  14.         IE1 |= WDTIE;                            // 使能看门狗周期性中断
  15.         BCSCTL1 = CALBC1_8MHZ;              // 配置CPU工作时钟MCLK=DCO_8MHZ
  16.         DCOCTL = CALDCO_8MHZ;


  17.         P1DIR |= BIT0+BIT6;
  18.         P1OUT |= BIT0;
  19.         P1OUT |= BIT6;

  20.         P1REN |= BIT3;
  21.         P1OUT |= BIT3;
  22.         
  23.         _enable_interrupts();        //使能总中断
  24.         while(1)                          //想想为什么要循环起来,和你之前的程序有什么不同
  25.         {
  26.                 P1_IODect();          //检测按键
  27.                 LPM3;                    //进入LPM3模式,相当方便的语句
  28.         }
  29. }

  30. #pragma vector=WDT_VECTOR
  31. __interrupt void WDT_ISR(void)
  32. {
  33.         LPM3_EXIT;                                //定时中断到来的时候唤醒CPU,退出LPM3也就是一条语句的事情
  34. }

  35. void P1_IODect()
  36. {
  37.         KEY_LAST_STATE=KEY_STATE;        //将键值存入上一状态laststate
  38.         KEY_STATE=!(P1IN&BIT3);              //读取按键键值,高为未按下,低为按下,因此对其取逻辑反,便于理解。
  39.                                                              //现在KEY_STATE为true表示按键按下,KEY_STATE为false表示按键未按下
  40.                                                              //实际上按键按下的时候KEY_STATE=BIT3,按键未按下为0。

  41.         if((!KEY_STATE)&&KEY_LAST_STATE)//如果当前状态为按键未按下,但是上一状态按键是按下的
  42.                                                              //说明按键弹起了。
  43.         {
  44.                 if(count<30)                           //如果按下到弹起小于30个周期也就是44ms*30=1.3s
  45.                         P13_Short_Click();           //处理短按程序
  46.                 count=0;
  47.         }

  48.         if(KEY_STATE)                       //当前按键如果是按下的
  49.         {
  50.                 count++;                      //不管那么多计数先加一

  51.                 if(count>100)
  52.                         count=100;           //避免count溢出,给其设置一个上限100
  53.         }
  54.         if(count==60)                        //如果按键按下44ms*60=2.6s
  55.                 P13_Long_Click();          //处理长按程序
  56.                                                     //注意这个长按的时钟是不准确的,具体怎么算长按怎么算短按自己调整

  57. }

  58. void P13_Short_Click()//短按翻转BIT0
  59. {
  60.         P1OUT ^= BIT0;
  61. //        P1OUT ^= BIT6;
  62. }

  63. void P13_Long_Click()//长按翻转BIT6
  64. {
  65. //        P1OUT ^= BIT0;
  66.         P1OUT ^= BIT6;
  67. }
复制代码
qiushenghua
3楼-- · 2019-03-26 16:55
 精彩回答 2  元偷偷看……
crysislove
4楼-- · 2019-03-26 22:05
qiushenghua 发表于 2015-11-28 10:10
又过了近两周,想问问楼主还有下文么?

一定有下文,楼主上两周忙着应付期末考试了这周才继续

一周热门 更多>

相关问题

    相关文章