历史上的今天
返回首页

历史上的今天

今天是:2024年09月28日(星期六)

2019年09月28日 | 再造STM32---第十部分:GPIO输入—按键检测

2019-09-28 来源:eefocus

       本章参考资料:《STM32F4xx 参考手册》、库帮助文档《stm32f4xx_dsp_stdperiph_lib_um.chm》。

       按键检测使用到 GPIO 外设的基本输入功能,本章中不再赘述 GPIO 外设的概念,如您忘记了,可重读前面“GPIO 框图剖析”小节, STM32 标准库中 GPIO 初始化结构体GPIO_TypeDef 的定义与“定义引脚模式的枚举类型”小节中讲解的相同。


10.1 硬件设计:

       按键机械触点断开、闭合时,由于触点的弹性作用,按键开关不会马上稳定接通或一下子断开,使用按键时会产生图 10-1 中的带波纹信号,需要用软件消抖处理滤波,不方便输入检测。本实验板连接的按键带硬件消抖功能,见图 10-2,它利用电容充放电的延时,消除了波纹,从而简化软件的处理,软件只需要直接检测引脚的电平即可。

       从按键的原理图可知,这些按键在没有被按下的时候, GPIO 引脚的输入状态为低电平(按键所在的电路不通,引脚接地),当按键按下时, GPIO 引脚的输入状态为高电平(按键所在的电路导通,引脚接到电源)。只要我们检测引脚的输入电平,即可判断按键是否被按下。

       若您使用的实验板按键的连接方式或引脚不一样,只需根据我们的工程修改引脚即可,程序的控制原理相同。


10.2 软件设计:

       同 LED 的工程,为了使工程更加有条理,我们把按键相关的代码独立分开存储,方便以后移植。在“工程模板”之上新建“bsp_key.c”及“bsp_key.h”文件,这些文件也可根据您的喜好命名,这些文件不属于 STM32 标准库的内容,是由我们自己根据应用需要编写的。


10.2.1 编程要点:

1. 使能 GPIO 端口时钟;

2. 初始化 GPIO 目标引脚为输入模式(引脚默认电平受按键电路影响,浮空/上拉/下拉均没有区别);

3. 编写简单测试程序,检测按键的状态,实现按键控制 LED 灯。


10.2.2 代码分析:

1. 按键引脚宏定义:

       同样,在编写按键驱动时,也要考虑更改硬件环境的情况。我们把按键检测引脚相关的宏定义到 “bsp_key.h”文件中,见代码清单 10-1。

代码清单 10-1 按键检测引脚相关的宏


//引脚定义

/*******************************************************/

#define KEY1_PIN GPIO_Pin_0

#define KEY1_GPIO_PORT GPIOA

#define KEY1_GPIO_CLK RCC_AHB1Periph_GPIOA

#define KEY2_PIN GPIO_Pin_13

#define KEY2_GPIO_PORT GPIOC

#define KEY2_GPIO_CLK RCC_AHB1Periph_GPIOC

/*******************************************************/

       以上代码根据按键的硬件连接, 把检测按键输入的 GPIO 端口、 GPIO 引脚号以及

GPIO 端口时钟封装起来了。


2. 按键 GPIO 初始化函数:

       利用上面的宏,编写按键的初始化函数,见代码清单 10-2。

代码清单 10-2 按键 GPIO 初始化函数


/**

* @brief 配置按键用到的 I/O 口

* @param 无

* @retval 无

*/

void Key_GPIO_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/*开启按键 GPIO 口的时钟*/

RCC_AHB1PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);

/*选择按键的引脚*/

GPIO_InitStructure.GPIO_Pin = KEY1_PIN;

/*设置引脚为输入模式*/

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

/*设置引脚不上拉也不下拉*/

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

/*使用上面的结构体初始化按键*/

GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);

/*选择按键的引脚*/

GPIO_InitStructure.GPIO_Pin = KEY2_PIN;

/*使用上面的结构体初始化按键*/

GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);

}

同为 GPIO 的初始化函数,初始化的流程与“LED GPIO 初始化函数”章节中的类似,主要区别是引脚的模式。函数执行流程如下:

       (1) 使用 GPIO_InitTypeDef 定义 GPIO 初始化结构体变量,以便下面用于存储 GPIO 配置。

       (2) 调用库函数 RCC_AHB1PeriphClockCmd 来使能按键的 GPIO 端口时钟,调用时我们使用“|”操作同时配置两个按键的时钟。

       (3) 向 GPIO 初始化结构体赋值,把引脚初始化成浮空输入模式,其中的 GPIO_Pin 使用宏“KEYx_PIN”来赋值,使函数的实现方便移植。 由于引脚的默认电平受按键电路影响,所以设置成“浮空/上拉/下拉”模式均没有区别。

       (4) 使用以上初始化结构体的配置,调用 GPIO_Init 函数向寄存器写入参数,完成 GPIO 的初始化,这里的 GPIO 端口使用“KEYx_GPIO_PORT”宏来赋值,也是为了程序移植方便。

       (5) 使用同样的初始化结构体,只修改控制的引脚和端口,初始化其它按键检测时使用的GPIO 引脚。

3. 检测按键的状态:

       初始化按键后,就可以通过检测对应引脚的电平来判断按键状态了,见代码清单 10-3。

代码清单 10-3 检测按键的状态


/** 按键按下标置宏

* 按键按下为高电平,设置 KEY_ON=1, KEY_OFF=0

* 若按键按下为低电平,把宏设置成 KEY_ON=0 , KEY_OFF=1 即可

*/

#define KEY_ON 1

#define KEY_OFF 0

/**

* @brief 检测是否有按键按下

* @param GPIOx:具体的端口, x 可以是(A...K)

* @param GPIO_PIN:具体的端口位, 可以是 GPIO_PIN_x(x 可以是 0...15)

* @retval 按键的状态

* @arg KEY_ON:按键按下

* @arg KEY_OFF:按键没按下

*/

uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)

{

/*检测是否有按键按下 */

if (GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON ) {

/*等待按键释放 */

while (GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);

return KEY_ON;

} else

return KEY_OFF;

}

       在这里我们定义了一个 Key_Scan 函数用于扫描按键状态。 GPIO 引脚的输入电平可通过读取 IDR 寄存器对应的数据位来感知,而 STM32 标准库提供了库函数GPIO_ReadInputDataBit 来获取位状态,该函数输入 GPIO 端口及引脚号,函数返回该引脚的电平状态,高电平返回 1,低电平返回 0。 Key_Scan 函数中以 GPIO_ReadInputDataBit 的返回值与自定义的宏“KEY_ON”对比,若检测到按键按下,则使用 while 循环持续检测按键状态,直到按键释放,按键释放后 Key_Scan 函数返回一个“KEY_ON”值;若没有检测到按键按下,则函数直接返回“KEY_OFF”。若按键的硬件没有做消抖处理,需要在这个 Key_Scan 函数中做软件滤波,防止波纹抖动引起误触发。

4. 主函数:

       接下来我们使用主函数编写按键检测流程,见代码清单 10-4。

代码清单 10-4 按键检测主函数


/**

* @brief 主函数

* @param 无

* @retval 无

*/

int main(void)

{

/* LED 端口初始化 */

LED_GPIO_Config();

/*初始化按键*/

Key_GPIO_Config();

/* 轮询按键状态,若按键按下则反转 LED */

while (1) {

if ( Key_Scan(KEY1_GPIO_PORT,KEY1_PIN) == KEY_ON ) {

/*LED1 反转*/

LED1_TOGGLE;

}

if ( Key_Scan(KEY2_GPIO_PORT,KEY2_PIN) == KEY_ON ) {

/*LED2 反转*/

LED2_TOGGLE;

}

}

}

       代码中初始化 LED 灯及按键后,在 while 函数里不断调用 Key_Scan 函数,并判断其返回值,若返回值表示按键按下,则反转 LED 灯的状态。


10.2.3 下载验证:

       把编译好的程序下载到开发板并复位,按下按键可以控制 LED 灯亮、灭状态。


推荐阅读

史海拾趣

CONEC公司的发展小趣事

作为一家有远见的企业,CONEC不仅关注自身的经济效益,还积极履行社会责任。公司致力于推动电子行业的可持续发展,通过采用环保材料、优化生产工艺等方式降低生产过程中的环境影响。同时,CONEC还积极参与社会公益事业,支持教育、环保等领域的发展。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实的基础。

请注意,以上故事仅为基于公开信息的推测和构建,可能并不完全准确反映CONEC公司的实际发展历程。如果您需要更详细和准确的信息,建议查阅CONEC公司的官方资料或相关新闻报道。

台湾第一电阻(Firstohm)公司的发展小趣事
定期清洁电冰箱对于保持其良好工作状态至关重要。首先,使用吸尘器或软布清理冰箱背面和底部的灰尘和污垢,确保通风良好。其次,定期清理冰箱内部的食物残渣和异味来源,保持内部清洁。此外,还应注意清理冷却器和风扇等部件上的灰尘和污垢,以确保制冷效果。
Everett Charles Technologies (ECT)公司的发展小趣事

1996年,ECT为了进一步壮大在产业中的主导地位,加入了Dover集团。Dover集团是一家在纽约股票交易所上市的全美500强大企业之一,其业务涵盖工业、工程系统、流体、电子技术等多个领域。加入Dover集团后,ECT得到了更多的资源和支持,实现了跨越式发展。Dover集团的全球布局和丰富资源,为ECT在全球范围内的业务拓展提供了有力保障。

泽耀科技(Ashining)公司的发展小趣事

泽耀科技(Ashining)在创立之初,面临着资金短缺、市场竞争激烈和技术难题等挑战。然而,公司的创始人凭借对电子行业的深刻理解和坚定信念,带领团队攻坚克难,不断研发创新。他们深入市场调研,准确把握消费者需求,成功推出了一款具有竞争力的电子产品,为公司的发展打开了局面。

Bellin公司的发展小趣事

随着市场的不断变化和消费者需求的升级,泽耀科技(Ashining)意识到只有不断创新才能在竞争中立于不败之地。公司加大了对研发的投入,引进了一批高素质的研发人才,并建立了完善的研发体系。经过多次尝试和实验,泽耀科技成功突破了某项关键技术,并推出了升级版的产品。这些新产品不仅性能更加优越,而且具有更高的性价比,深受消费者的喜爱。

Diode Laser Concepts公司的发展小趣事

Diode Laser Concepts公司始终关注社会责任,积极参与各类公益活动。公司定期向贫困地区捐赠教育设备和资金,支持当地的教育事业发展;同时,公司还组织员工参与环保志愿活动,宣传环保理念,为保护地球环境贡献一份力量。这些公益活动不仅体现了公司的社会责任感,也增强了员工之间的凝聚力和向心力。

问答坊 | AI 解惑

苹果腰斩售价抢滩中国市场

本帖最后由 jameswangsynnex 于 2015-3-3 20:00 编辑 苹果公司罕见地放低了身价,期望以平价亲近中国消费者。昨日,苹果借在中国推出新款电脑大幅下调高端笔记本的入门价格,降价幅度超过7000元。最低配置款售价仅为8498元,这是苹果公司首次把价 ...…

查看全部问答>

给做射频朋友们推荐款微型低功耗可过日本电波法认证的ASK发射模块

  工作电压:3V(2.4-3.6V) 工作电流:14mA   发射强度:10dBm   发射频率:315MHz、433MHz、390MHz 发射天线:18-25mm   工作温度:-20-- +85℃…

查看全部问答>

请高手指教一下如何通过pwm实现DA的转化?最好有电路图

做毕业设计需要的,毕业设计的题目是基于stm32的语音播放,想要通过pwm实现DA的转换,但是不知道程序如何写,以及电路如何实现,希望高手给与帮助,谢谢!…

查看全部问答>

有用过MAX436这个滤波芯片,进来帮我解决一下问题

我用MAX436对信号进行处理 MAX436的资料看了,但实际上用的时候和理论上相反 想请教一下高手来帮助下 我是按照MAX.PDF文件里的图12那图连接方法,各个参数是与图13的那些参数一样 但出来的信号时衰减的啊 而且,我调节RL,信号的幅值在中心幅 ...…

查看全部问答>

wince 5 中的图标变为黑色的,有没有遇到过这个问题,怎么解决?

在wince 5中修改显示分辨率中,发现wince 5 中的图标变为黑色的,有没有遇到过这个问题,怎么解决? 谢谢!…

查看全部问答>

精密多圈电位器

求教:精密多圈电位器与DSP连接电路是怎么样的,怎么引出精密多圈电位器的电阻传递给DSP…

查看全部问答>

求msp430下载软件simple insidepro

如题。xdwll88@126.com.  谢谢!…

查看全部问答>

芯片内部短路

前些天折腾电路时,发现stm32最小系统板上电源和地之间短路了!感叹之后,开始测查吧。令我十分意外而悲哀的是,两个小时没查出来!我还不至于垃圾到这个份上啊。后来,我终于发现是芯片内部的问题(99和100脚之间)。我把引脚悬起来,依然短路。那 ...…

查看全部问答>

求工作--1年硬件工程师--北方城市

我2月9号---2月12号 在哈尔滨    2月13号可能去长春,也可能直接去北京; 希望有哪个公司觉得我还有用处的话,就把我收了吧。。。     个人简历个人基本信息 姓    名:孟祥振       ...…

查看全部问答>

MSP430 FFTB6638

这几天学这个芯片   英语不好 还全是英文资料,有没有中文资料   或者对新手学430的  好书   谢谢各位大神了!…

查看全部问答>