多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
* 导师视频讲解:[**去听课**](https://www.bilibili.com/video/BV1k34y1D7Vz?p=8) >[success] **技术支持说明:** >**1**.一般以自主学习为主 > **2**.可到官方问答社区中提问:[**去提问**](https://bbs.csdn.net/forums/zigbee) > **3**.工程师**会尽快**解答社区问题,但他们是一线开发,【**难以保证**】解答时效,解答辛苦,感谢理解! <br/> 接着上节课的内容,切换到按键的工程,如图所示。 ![](https://img.kancloud.cn/34/8f/348f54bae51d61f9ad384ef7e7598c65_456x438.png =200x) <br/> ## **按钮原理简介** 配套的ZigBee开发板均配备有按键,其原理图如图所示。 ![](https://img.kancloud.cn/a2/1b/a21b31bbb8ef80a9a6499718b90c876e_512x582.png =250x) >[danger] 如您缺少硬件原理相关知识导致未能看懂本图,需先补充相关知识 图中K5是一个按钮,R11是一枚100KΩ的上拉电阻,P0_1是CC2530的一个IO口,相关原理如下: (1)当按钮没有按下时,P0_1通过上拉电阻R11接到3v3,所以P0_1的输入电平为高电平。 (2)当按键按下时,P0_1接地,所以P0_1的输入电平为低电平。 由以上分析可知,可以检测P0_1的输入电平状态来检测按钮是否被按下。 <br/> ## **P0\_1相关寄存器** 与LED实验类似,要检测P0\_1的输入电平状态,就必须要先配置一下相关寄存器。P0\_1的相关寄存器建下表。 ### | 寄存器 | 说明 | | --- | --- | | P0 | 8位寄存器,8个位分别与P0\_0~P0\_7一一对应,分别用于设置或读取这8个IO口的电平状态 | | P0SEL | 8位寄存器,8个位分别与P0\_0~P0\_7一一对应,分别配置这8个IO口的功能。如果IO口对应的位为0,表示该IO口用于通用输入/输出;如果为1,表示用于特定的功能 | | P0DIR | 8位寄存器,8个位分别与P0\_0~P0\_7一一对应,分别配置这8个IO口的通信方向。如果IO口对应的位为0,表示该IO口处于输入信号模式;如果为1,表示处于输出信号模式 | | P0INP | 8位寄存器,8个位分别与P0\_0~P0\_7一一对应,分别配置这8个IO口的输入模式。如果IO口对应的位为0,表示该IO口为上拉/下拉输入模式;如果为1,表示三态模式 | | P2INP\[7:5\] | P2INP寄存器的第5、6和7位分别用于配置端0、1和2的上拉或下拉模式,如果为0,表示上拉模式;如果为1,表示下拉模式 | <br/> #### **上拉与下拉输入** 相关寄存器中涉及到上拉和下拉输入,对其简单讲解一下。通俗地讲,上拉是指在默认的状态下给IO口输入高电平,与之相反,下拉就是低电平。根据上文的按键原理图可知,这是一个上拉输入模式。按键原理示意图如图所示。 ![](https://img.kancloud.cn/8a/fe/8afe532dbcb328f8e3de0ee743b48905_704x468.png =600x) ### 当按键没有被按下时,CC2530与3.3v电源连接,其引脚的输入电平为高电平(对应信号1)。当按钮被按下时,CC2530与GND连接,其引脚的输入电平为低电平(对应信号0)。 <br/> #### **寄存器配置** 通过以上分析,相关寄存器的配置代码如下: ### ``` P0SEL &= ~(1<<1);//把P0SEL寄存器的第1位设置为0,即让P0_1用作通用IO口 P0DIR &= ~(1<<1);//把P0DIR寄存器的第1位设置为0,即让让P0_1处于输入信号模式 P0INP &= ~(1<<1);//把P0INP寄存器的第1位设置为0,即让P0_1处于上拉/下拉输入模式 P2INP &= ~(1<<5);//把P2INP寄存器的第5位设置为0,即让端口0处于上拉输入模式 ``` <br/> ## **编写按键代码** 编写代码实现每按一下按键就翻转一下LED的开关状态,打开Key文件夹中的key.c文件,可以看到如下示例代码: ### ``` //2. 51单片机入门/2. GPIO实验/Workspace/code/key/key.c #include "ioCC2530.h" #include <stdio.h> #include <stdint.h> #define DEBUG //#define xDEBUG #ifdef DEBUG #define DEBUG_LOG(...) printf(__VA_ARGS__) #else #define DEBUG_LOG(...) #endif #define LED P0_4 #define LED_ON 1 #define LED_OFF 0 /** * @brief 按钮及其状态的定义。其中,P0_1是在头文件ioCC2530.h,可以检测其值来判断P0_1引脚的电平状态 */ #define BUTTON P0_1 #define BUTTON_NORMAL 1//按钮的默认状态 #define BUTTON_DOWN 0//按钮被按下 static void delayMs(uint16_t nMs); static void initLed(void); static void initButton(void); void main()  {   initLed();//初始化LED     initButton();//初始化按键       while(1) {         if (BUTTON != BUTTON_DOWN)//如果按键没有被按下 continue;//结束本次while循环         else { /* 以下为对按键的机械抖动的处理处理代码 */ delayMs(10);//延后10毫秒 if (BUTTON != BUTTON_DOWN)//再次检测按钮的状态,如果按键没有被按下 continue;//结束本次while循环 }                  while (BUTTON == BUTTON_DOWN);//等待BUTTON != BUTTON_DOWN,即等待按键松开                  DEBUG_LOG("Key Pressed!\r\n");           LED = (LED == LED_ON)? LED_OFF : LED_ON;//翻转LED的状态 } } static void delayMs(uint16_t nMs) { uint16_t i,j; for (i = 0; i < nMs; i++) for (j = 0; j < 535; j++); } static void initLed() { P0SEL &= ~(1<<4); P0DIR |= (1<<4); } /* * @fn initButton * * @brief 初始化Button,完成P0_1相关寄存器的配置 */ static void initButton() { P0SEL &= ~(1<<1);//把P0SEL寄存器的第1位设置为0,即让P0_1用作通用IO口 P0DIR &= ~(1<<1);//把P0DIR寄存器的第1位设置为0,即让让P0_1处于输入信号模式 P0INP &= ~(1<<1);//把P0INP寄存器的第1位设置为0,即让P0_1处于上拉/下拉输入模式 P2INP &= ~(1<<5);//把P2INP寄存器的第5位设置为0,即让端口0处于上拉输入模式 } ``` <br/> #### **处理机械按键抖动** 上述代码包含了按键抖动的处理,对其简单讲解一下。由于按键内部采用了弹簧,所以当按键被按下或松开的时候,会产生一定的震动,这种震动可以称为机械抖动。这种机械抖动会导致电平的抖动,如图所示。 ![](https://img.kancloud.cn/58/ae/58ae4a38afad2fe5ddf33ded2e021b26_582x324.png =200x) 图中的中的横坐标是电平,纵坐标是时间,展示了按钮从按下到松开这个过程的电平变化。按键被按下时产生的抖动称为前沿抖动,松开时产生的是后沿抖动。这个抖动时间一般持续5~10ms。因此在代码上当检测到按钮被按下后,需要延后10ms后再检测一次按钮是否真的被按下。 <br/> #### **使用调试模式** 在程序开发调试过程中,可设置一个调试模式。在调试模式下可以输出相关的调试信息来了解程序运行状态。然而在程序开发完成后,可以关闭调试模式,停止输出调试信息。 ### DEBUG\_LOG是一个宏定义,其定义在上述代码的开端处。 * 当代码定义了 DEBUG 这个宏时,表示当前模式是调试模式,此时DEBUG\_LOG和printf是一致的。 * 而没有定义DEBUG 这个宏时,表示关闭调试模式,此时DEBUG\_LOG什么都不做。所以,当需要关闭调试模式时,可以把DEBUG更改为xDEBUG,表示关闭调试模式。 <br/> ## **仿真调试** 1. 把开发板通过仿真器连接到电脑上。 2. 按一下仿真器的复位按键。 ![](https://img.kancloud.cn/a6/65/a66518b91448e99ee3e1594218f21591_1710x612.png =200x) ### 3. 打开本实验代码,打开调试模式,编译链接通过后,点击“下载仿真”按钮全速运行程序,每当有按键按下时Terminal I/O中就会输出相应的信息,如图所示。 ![](https://img.kancloud.cn/03/38/03381fce1d48e5c5c0057963f798d1a4_830x274.png =600x) <br/> <br/> ## **商务合作** 如有以下需求,可扫码添加管理员好友,注明“**商务合作**” * 项目定制开发,技术范围:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等; * 入驻平台,成为讲师; * 接项目赚外快; * 善学坊官网:[www.sxf-iot.com](https://www.sxf-iot.com/) ![](https://img.kancloud.cn/ca/73/ca739f92cab220a3059378642e3bd502_430x430.png =200x) * 非合作**勿扰**,此处**非**技术支持