官方示例代码
官方视频教程里面的代码如下,我做了些许的调整,但是是一样的。只需要看while(1)中的内容。
#define CPU_F ((double)1000000) #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)) #define Key_ON 0 #define Key_OFF 1 /** * main.c */ void main() { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer /****配置LED****/ //P1.0和P4.7为输出 P1DIR |= BIT0; P4DIR |= BIT7; /****配置按键****/ //P2.1和P1.1为输入 P2DIR &=~ BIT1; P1DIR &=~ BIT1; //开启P2.1和P1.1的上下拉 P2REN |= BIT1; P1REN |= BIT1; //P2.1和P1.1都为上拉输入 P2OUT |= BIT1; P1OUT |= BIT1; while(1) { if((P2IN & BIT1) == Key_ON) //判断P2.1是否被按下 { delay_ms(20); //延时20ms if((P2IN & BIT1) == Key_ON) //再次判断按键是否被按下 P1OUT ^= BIT0; while((P2IN & BIT1) == Key_ON); //等待按键松开 } if((P1IN & BIT1) == Key_ON) { delay_ms(20); //延时20ms if((P1IN & BIT1) == Key_ON) //再次判断按键是否被按下 P4OUT ^= BIT7; while((P1IN & BIT1) == Key_ON); //等待按键松开 } } }
内容解析
BIT0的含义
因为代码里面突然出现了一个BIT0,很多人不是很理解BIT0是什么意思,我们鼠标靠近BIT0——>右键——>点击Open Deciaration。
然后我们就能够弹出这个界面,发现BIT0就是0x0001。
^=解析
很多人C语言都学了^=,但是因为长期不使用,已经忘记了,我简单复习一下。^就说进行按位异或,相同取0,不同取1。
注意%x意思的以16进制进行打印,为了让我们更加直观的知道不同位的变化,所以我采用%x
#include <stdio.h> int main() { int a = 0xf1, b = 0x01, c; //a 1000 0001 //b 0000 0001 //c 1000 0000 c = a^b; printf("c=0x%x",c); //打印结果位c=0xf0 return 0; }
而a^=b。就是a = a ^ b
#include <stdio.h> int main() { int a = 0xf1, b = 0x01; //a 1000 0001 //b 0000 0001 //a 1000 0000 a ^= b; printf("a=0x%x",a); //打印结果位a=0xf0 return 0; }
因为我们知道了BIT0就是0x01。所以 P1OUT ^= BIT0;只会改变第一个位的大小。其他位如果是0,0与0相等,所以还是0。如果其他位为1,1与0不相等,所以结果为1,此位大小依旧不变。
按键消抖
按键按下的瞬间是会有抖动的, 导致我们明明是按了1下,但是系统认为我们按了多下。所以我们采用延时的方法,消除按下瞬间的抖动。
因为按键消抖的延时只有20ms,我们不能做到按下按键20ms后,马上松开按键。这样会导致,明明我们只按了一次,但是系统依旧认为我们按了多次。比如说,我按键按下了100ms,之后松开,系统就会认为我们按下按键了5次。(假设系统的程序运行是不消耗时间)所以我们增加了一个while判断,只有当按键松开才会进行下一步操作。这样就做到了按一次,系统就知道是一次。
增加的宏定义
为了方便编程和阅读,我增加了两个宏定义,如下。
#define Key_ON 0 #define Key_OFF 1
问题
这个代码有一个问题,就是假如我按下s1,LED1会有相应的变化。但是我此时不松开s1,继续按s2,我们会发现LED2没有变化。
这是因为我们采用了while,如果s1不松开,程序就不会进入下一步。那么我们即使按下了s2,LED2也不会有反应。