0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【GD32F470紫藤派开发板使用手册】第二讲 GPIO-按键查询实验

聚沃科技 2024-04-30 11:39 次阅读
wKgaomYwSqiAY_PQAAnl063z3JE116.png

2.1实验内容

通过本实验主要学习以下内容:

  • GPIO输入功能原理;
  • 按键查询输入检测原理;

2.2实验原理

2.2.1GPIO输入功能原理

GD32F4xx系列MCU GPIO输入配置结构如下图所示,输入可配置上下拉电阻,通过施密特触发器后可通过备用功能输入或者通过输入状态寄存器进行读取。

wKgaomYwZxSANcQyAAC4a9fgeFM847.png

输入状态寄存器为GPIOx_ISTAT,其状态位定义如下图所示,每个控制位对应相应引脚的输入电平状态。

wKgaomYwZyCAJe5PAAM8o5nR5Wk051.png

GPIO引脚输入电平判断阈值如下图所示,当输入电平小于0.3VDD时,可被内部有效识别为低电平;当输入电平大于0.7VDD时,可被内部有效识别为高电平。

wKgZomYwZzuAX4MaAAKo_3uIgbQ249.png

2.3硬件设计

GD32F4xx紫藤派开发板具有两个按键,对应电路图如下图所示,其中,唤醒按键未按下时为低电平,按下后唤醒按键为高电平;用户按键未按下时为高电平,按下后用户按键为低电平,通过读取按键对应GPIO引脚的电平状态可检测对应按键是否被按下。

wKgaomYwZ1KAPhARAAEYtkjSdds247.png

注意:机械按键在按下或者松开时具有抖动,建议可增加硬件消抖或者软件消抖,以避免按键检测被多次触发。

2.4代码解析

本例程实现通过查询的方式可查询按键按下的时间,进而可实现短时间按下和长时间按下的检测。

主函数代码如下,首先进行驱动初始化/按键初始化/LED初始化/串口初始化,并打印Example of key scan detection.之后进入主循环,通过key_scan函数实现对按键的扫描并检测按键按下时间。

C
int main(void)
{
/* 系统延时初始化 */
driver_init();

//注册按键扫描
driver_tick_handle[0].tick_value=10;
driver_tick_handle[0].tick_task_callback=key_scan_10ms_callhandle;


/* 按键组初始化 */
bsp_key_group_init();

/* LED组初始化 */
bsp_led_group_init();

/* 板载UART初始化 */
bsp_uart_init(&BOARD_UART);

delay_ms(1000);

printf_log("Example of key scan detection.\r\n");


while (1)
{
delay_ms(1);

/* 按键扫描结果检查:检测任意按键和多按键组合按下时间,所有按键弹起后有效 */
if(SET==all_key_up)
{
/* 检测按键组合按下时长 */
if(USER_KEY.press_timerms >= PRESS_3000MS && WKUP_KEY.press_timerms >= PRESS_3000MS)
{
printf_log("USER_KEY/KEY2/WKUP_KEY pressed together for more than 3000ms.\r\n");
USER_KEY.press_timerms=PRESS_NONE;
WKUP_KEY.press_timerms=PRESS_NONE;
}
else if(USER_KEY.press_timerms >= PRESS_50MS && WKUP_KEY.press_timerms >= PRESS_50MS)
{
printf_log("USER_KEY/KEY2/WKUP_KEY pressed together for more than 50ms.\r\n");
USER_KEY.press_timerms=PRESS_NONE;
WKUP_KEY.press_timerms=PRESS_NONE;
}

if(USER_KEY.press_timerms >= PRESS_200MS && USER_KEY.press_timerms < PRESS_5000MS)
{
USER_KEY.press_timerms=PRESS_NONE;
printf_log("USER_KEY press more than 200ms, less than 5000ms .\r\n");
}
else if(USER_KEY.press_timerms >= PRESS_5000MS)
{
USER_KEY.press_timerms=PRESS_NONE;
printf_log("USER_KEY press more than 5000ms.\r\n");
}
else if(USER_KEY.press_timerms >= PRESS_DOWN)
{
USER_KEY.press_timerms=PRESS_NONE;
printf_log("USER_KEY press briefly.\r\n");
}


if(WKUP_KEY.press_timerms >= PRESS_200MS && WKUP_KEY.press_timerms < PRESS_5000MS)
{
WKUP_KEY.press_timerms=PRESS_NONE;
printf_log("WKUP_KEY press more than 200ms, less than 5000ms .\r\n");
}
else if(WKUP_KEY.press_timerms >= PRESS_5000MS)
{
WKUP_KEY.press_timerms=PRESS_NONE;
printf_log("WKUP_KEY press more than 5000ms.\r\n");
}
else if(WKUP_KEY.press_timerms >= PRESS_DOWN)
{
WKUP_KEY.press_timerms=PRESS_NONE;
printf_log("WKUP_KEY press briefly.\r\n");
}

all_key_up=RESET;
}

//非弹起检查
if(USER_KEY.press_cycle_count >= PRESS_50MS)
{
bsp_led_toggle(&LED2);
}
else if(WKUP_KEY.press_cycle_count >= PRESS_50MS)
{
bsp_led_toggle(&LED2);
}
else
{
bsp_led_off(&LED2);
}


//直接读取
if(bsp_key_state_get(&USER_KEY)==SET)
{
bsp_led_toggle(&LED1);
}
else if(bsp_key_state_get(&WKUP_KEY)==SET)
{
bsp_led_toggle(&LED1);
}
else
{
bsp_led_off(&LED1);
}
}
}

按键初始化函数如下,通过KEY_DEF定义相关按键参数,之后调用bsp_key_init对按键进行分别初始化。

C
void bsp_key_group_init(void)
{
uint8_t i;
for(i=0;i{
bsp_key_init(((typdef_bsp_key *)KEY_INIT_GROUP[i]));
}
}
KEY_DEF(USER_KEY,A,1,IN_PU,SET,NULL); // PA1定义为USER_KEY非中断模式,默认状态高
KEY_DEF(WKUP_KEY,A,0,IN_PD,RESET,NULL); // PA0定义为KEY2非中断模式,默认状态高

通过key_scan进行按键扫描,实现对按键按下时间长度范围的检测。

C
bit_status key_scan(uint16_t scan_ms_cycle)
{
uint8_t i;
bit_status press_flag=RESET;
for(i=0;i{
// ((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_timerms=press_none;
if(bsp_key_state_get((typdef_bsp_key *)KEY_INIT_GROUP[i])==SET && ((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count<0xffff){

((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_timerms =PRESS_DOWN;
((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count+=scan_ms_cycle;
}
}

for(i=0;i{

if(bsp_key_state_get((typdef_bsp_key *)KEY_INIT_GROUP[i])==SET && ((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count < 0xffff) //持续60s被按下按键可能损坏        
{
return press_flag;
}
}

for(i=0;i{
if(((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count>PRESS_50MS)
{
press_flag=SET;
if(((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count > PRESS_5000MS){
((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_timerms=PRESS_5000MS;
}
else if(((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count>PRESS_4000MS){
((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_timerms=PRESS_4000MS;
}
else if(((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count>PRESS_3000MS){
((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_timerms=PRESS_3000MS;
}
else if(((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count>PRESS_2000MS){
((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_timerms=PRESS_2000MS;
}
else if(((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count>PRESS_1000MS){
((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_timerms=PRESS_1000MS;
}
else if(((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count>PRESS_500MS){
((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_timerms=PRESS_500MS;
}
else if(((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count>PRESS_200MS){
((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_timerms=PRESS_200MS;
}
else{
((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_timerms=PRESS_50MS;
}
}
if(bsp_key_state_get((typdef_bsp_key *)KEY_INIT_GROUP[i])==RESET){
((typdef_bsp_key *)KEY_INIT_GROUP[i])->press_cycle_count=0;
}
}

return press_flag;

}

2.5实验结果

将本例程烧录到紫藤派开发板中,在液晶屏上首先打印Example of key scan detection.

之后短按或者长按WKUP或USER按键,将在液晶上显示按下的状态。

wKgaomYwZ5mAA-Y6AChIR_PRYTY426.png

教程由GD32 MCU方案商聚沃科技原创发布,了解更多GD32 MCU教程,关注聚沃科技官网

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6035

    文章

    44554

    浏览量

    634621
  • 嵌入式
    +关注

    关注

    5082

    文章

    19104

    浏览量

    304796
  • 开发板
    +关注

    关注

    25

    文章

    5032

    浏览量

    97371
  • GD32
    +关注

    关注

    7

    文章

    403

    浏览量

    24326
收藏 人收藏

    评论

    相关推荐

    GD32F470紫藤开发板使用手册】第九 USART-printf打印实验

    通过本实验主要学习以下内容: 串口简介 GD32F470串口工作原理 使用printf打印信息
    的头像 发表于 05-13 10:14 1725次阅读
    【<b class='flag-5'>GD32F470</b><b class='flag-5'>紫藤</b><b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>使用手册</b>】第九<b class='flag-5'>讲</b>  USART-printf打印<b class='flag-5'>实验</b>

    GD32F470紫藤开发板使用手册】第十一讲 SPI-SPI NOR FLASH读写实验

    通过本实验主要学习以下内容: •SPI简介 •GD32F470 SPI简介 •SPI NOR FLASH——GD25Q32ESIGR简介 •使用GD32F470 SPI接口实现对
    的头像 发表于 05-17 09:57 1771次阅读
    【<b class='flag-5'>GD32F470</b><b class='flag-5'>紫藤</b><b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>使用手册</b>】第十一讲 SPI-SPI NOR FLASH读写<b class='flag-5'>实验</b>

    迅为iMX6ULL开发板使用手册资料下载

    开发板使用手册》第一部分 开发板入门第二部分 开发环境搭建第三部分 Linux系统编译第四部分 QT
    发表于 12-02 14:13

    YL-51开发板使用手册

    YL-51开发板使用手册,YL-51开发板使用手册YL-51开发板使用手册YL-51
    发表于 05-10 16:31 21次下载

    51开发板使用手册

    51开发板使用手册,感兴趣的小伙伴们可以瞧一瞧。
    发表于 11-23 15:45 11次下载

    KC705开发板英文使用手册

    KC705开发板英文使用手册
    发表于 11-01 10:19 5次下载

    APT32F102 开发板使用手册

    电子发烧友网站提供《APT32F102 开发板使用手册.pdf》资料免费下载
    发表于 04-16 09:07 0次下载

    GD32H757Z海棠开发板使用手册第二 GPIO-按键查询检测实验

    2.1实验内容通过本实验主要学习以下内容:GPIO输入功能原理;按键查询输入检测原理;2.2实验
    的头像 发表于 04-17 10:42 723次阅读
    【<b class='flag-5'>GD</b>32H757Z海棠<b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>使用手册</b>】<b class='flag-5'>第二</b><b class='flag-5'>讲</b> <b class='flag-5'>GPIO-</b><b class='flag-5'>按键</b><b class='flag-5'>查询</b>检测<b class='flag-5'>实验</b>

    GD32F470紫藤开发板使用手册】第一 GPIO-流水灯实验

    GPIO结构及原理; GPIO输出功能实现; LED驱动原理。
    的头像 发表于 04-30 11:34 977次阅读
    【<b class='flag-5'>GD32F470</b><b class='flag-5'>紫藤</b><b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>使用手册</b>】第一<b class='flag-5'>讲</b> <b class='flag-5'>GPIO-</b>流水灯<b class='flag-5'>实验</b>

    GD32F470紫藤开发板使用手册】第三 EXTI-按键中断检测实验

    通过本实验主要学习以下内容: EXTI中断原理; 按键中断检测原理;
    的头像 发表于 05-05 09:22 538次阅读
    【<b class='flag-5'>GD32F470</b><b class='flag-5'>紫藤</b><b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>使用手册</b>】第三<b class='flag-5'>讲</b> EXTI-<b class='flag-5'>按键</b>中断检测<b class='flag-5'>实验</b>

    GD32F470紫藤开发板使用手册】第五 PMU-低功耗实验

    通过本实验主要学习以下内容: PMU原理; 低功耗的进入以及退出操作
    的头像 发表于 05-07 09:29 675次阅读
    【<b class='flag-5'>GD32F470</b><b class='flag-5'>紫藤</b><b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>使用手册</b>】第五<b class='flag-5'>讲</b>  PMU-低功耗<b class='flag-5'>实验</b>

    GD32F470紫藤开发板使用手册】第八 ADC-规则组多通道采样实验

    通过本实验主要学习以下内容: •ADC的简介 •GD32F470 ADC工作原理 •DMA原理 •规则组多通道循环采样
    的头像 发表于 05-12 10:00 751次阅读
    【<b class='flag-5'>GD32F470</b><b class='flag-5'>紫藤</b><b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>使用手册</b>】第八<b class='flag-5'>讲</b> ADC-规则组多通道采样<b class='flag-5'>实验</b>

    GD32F303红枫开发板使用手册第二 GPIO-流水灯实验

    GD32F303系列MCU最多可支持 112 个通用I/O 引脚(GPIO),分别为 PA0 ~ PA15, PB0 ~ PB15, PC0 ~ PC15,PD0 ~ PD15, PE0
    的头像 发表于 05-29 10:02 1631次阅读
    【<b class='flag-5'>GD32F</b>303红枫<b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>使用手册</b>】<b class='flag-5'>第二</b><b class='flag-5'>讲</b> <b class='flag-5'>GPIO-</b>流水灯<b class='flag-5'>实验</b>

    GD32F303红枫开发板使用手册】第三 GPIO-按键查询检测实验

    GD32F303系列MCU GPIO输入配置结构如下图所示,输入可配置上下拉电阻,通过施密特触发器后可通过备用功能输入或者通过输入状态寄存器进行读取。
    的头像 发表于 05-30 10:02 852次阅读
    【<b class='flag-5'>GD32F</b>303红枫<b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>使用手册</b>】第三<b class='flag-5'>讲</b> <b class='flag-5'>GPIO-</b><b class='flag-5'>按键</b><b class='flag-5'>查询</b>检测<b class='flag-5'>实验</b>

    GD32F303红枫开发板使用手册第二 SPI-SPI NAND FLASH读写实验

    通过本实验主要学习以下内容: •SPI通信协议,参考19.2.1东方红开发板使用手册GD32F303 SPI操作方式,参考19.2.2东方红
    的头像 发表于 06-20 09:50 883次阅读
    【<b class='flag-5'>GD32F</b>303红枫<b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>使用手册</b>】<b class='flag-5'>第二</b>十<b class='flag-5'>讲</b> SPI-SPI NAND FLASH读写<b class='flag-5'>实验</b>