GD32开发实战指南(基础篇) 第6章 按键

发布者:美丽花朵最新更新时间:2024-11-07 来源: elecfans关键字:GD32  开发实战  按键 手机看文章 扫描二维码
随时随地手机看文章


4)选定要配置为 EXTI 的 I/O 口线和 I/O 口的工作模式。


5)EXTI 中断线工作模式配置。


/*

    brief      configure key

    param[in]  keynum: specify the key to be configured

      arg        KEY_TAMPER: tamper key

      arg        KEY_WAKEUP: wakeup key

      arg        KEY_USER: user key

    param[in]  keymode: specify button mode

      arg        KEY_MODE_GPIO: key will be used as simple IO

      arg        KEY_MODE_EXTI: key will be connected to EXTI line with interrupt

    param[out] none

    retval     none

*/

void key_init(key_typedef_enum keynum, keymode_typedef_enum keymode)

{

    /* enable the key clock */

    rcu_periph_clock_enable(KEY_CLK[keynum]);

    rcu_periph_clock_enable(RCU_AF);


    /* configure button pin as input */

    gpio_init(KEY_PORT[keynum], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, KEY_PIN[keynum]);


    if (keymode == KEY_MODE_EXTI) 

    {

        /* enable and set key EXTI interrupt to the lowest priority */

        nvic_irq_enable(KEY_IRQn[keynum], 2U, 0U);


        /* connect key EXTI line to key GPIO pin */

        gpio_exti_source_select(KEY_PORT_SOURCE[keynum], KEY_PIN_SOURCE[keynum]);


        /* configure key EXTI line */

        exti_init(KEY_EXTI_LINE[keynum], EXTI_INTERRUPT, EXTI_TRIG_FALLING);

        exti_interrupt_flag_clear(KEY_EXTI_LINE[keynum]);

    }

}

key_init()代码中,不仅配置了NVIC ,还对按键的GPIO进行了初始化,这部分和按键轮询的设置类似。


接下来,调用 gpio_exti_source_select () 函数把 GPIOA、Pin0 与EXTI连接起来。


最后调用 exti_init() 把 EXTI 初始化,函数如下:


/*!

    \brief      initialize the EXTI

    \param[in]  linex: EXTI line number, refer to exti_line_enum

                only one parameter can be selected which is shown as below:

      \arg        EXTI_x (x=0..19): EXTI line x

    \param[in]  mode: interrupt or event mode, refer to exti_mode_enum

                only one parameter can be selected which is shown as below:

      \arg        EXTI_INTERRUPT: interrupt mode

      \arg        EXTI_EVENT: event mode

    \param[in]  trig_type: interrupt trigger type, refer to exti_trig_type_enum

                only one parameter can be selected which is shown as below:

      \arg        EXTI_TRIG_RISING: rising edge trigger

      \arg        EXTI_TRIG_FALLING: falling trigger

      \arg        EXTI_TRIG_BOTH: rising and falling trigger

      \arg        EXTI_TRIG_NONE: without rising edge or falling edge trigger

    \param[out] none

    \retval     none

*/

void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type)

{

    /* reset the EXTI line x */

    EXTI_INTEN &= ~(uint32_t)linex;

    EXTI_EVEN &= ~(uint32_t)linex;

    EXTI_RTEN &= ~(uint32_t)linex;

    EXTI_FTEN &= ~(uint32_t)linex;


    /* set the EXTI mode and enable the interrupts or events from EXTI line x */

    switch(mode) {

    case EXTI_INTERRUPT:

        EXTI_INTEN |= (uint32_t)linex;

        break;

    case EXTI_EVENT:

        EXTI_EVEN |= (uint32_t)linex;

        break;

    default:

        break;

    }


    /* set the EXTI trigger type */

    switch(trig_type) {

    case EXTI_TRIG_RISING:

        EXTI_RTEN |= (uint32_t)linex;

        EXTI_FTEN &= ~(uint32_t)linex;

        break;

    case EXTI_TRIG_FALLING:

        EXTI_RTEN &= ~(uint32_t)linex;

        EXTI_FTEN |= (uint32_t)linex;

        break;

    case EXTI_TRIG_BOTH:

        EXTI_RTEN |= (uint32_t)linex;

        EXTI_FTEN |= (uint32_t)linex;

        break;

    case EXTI_TRIG_NONE:

    default:

        break;

    }

}

AFIO 时钟

代码中调用rcu_periph_clock_enable(RCU_AF)表示开启 AFIO的时钟。


AFIO (alternate-function I/O),指 GPIO 端口的复用功能,GPIO 除了用作普通的输入输出(主功能),还可以作为片上外设的复用输入输出,如串口、ADC,这些就是复用功能。大多数 GPIO 都有一个默认复用功能,有的 GPIO 还有重映射功能。重映射功能是指把原来属于 A 引脚的默认复用功能,转移到B引脚进行使用,前提是 B 引脚具有这个重映射功能。


当把 GPIO 用作 EXTI 外部中断或使用重映射功能的时候,必须开启 AFIO 时钟,而在使用默认复用功能的时候,就不必开启 AFIO 时钟了。


编写中断服务函数

在这个 EXTI 设置中我们把 PA0 连接到内部的 EXTI0,GPIO 配置为上拉输入,工作在下降沿中断。在外围电路上我们将 PA0 接到了 key上。当按键没有按下时,PA0 始终为高,当按键按下时 PA0 变为低,从而 PA0 上产生一个下降沿跳变,EXTI0 会捕捉到这一跳变,并产生相应的中断,中断服务程序在 gd32f20x_it.c 中实现。gd32f20x_it.c 文件是专门用来存放中断服务函数的。文件中默认只有几个关于系统异常的中断服务函数,而且都是空函数,在需要的时候自行编写。那么中断服务函数名是不是可以自己定义呢?不可以。中断服务函数的名字必须要与启动文件startup_gd32f20x_cl.s 中的中断向量表定义一致。



EXTI0_IRQHandler 表示为 EXTI0 中断向量的服务函数名。于是,我们就可以在 gd32f20x_it.c文件中加入名为 EXTI0_IRQHandler() 的函数。


/*!

    \brief      this function handles external lines 0 interrupt request

    \param[in]  none

    \param[out] none

    \retval     none

*/

void EXTI0_IRQHandler(void)

{

    if(RESET != exti_interrupt_flag_get(EXTI_0))

    {

        /* turn toggle LED */

        led_toggle(LED1);

        led_toggle(LED2);

        led_toggle(LED3);

        led_toggle(LED4);


       exti_interrupt_flag_clear(EXTI_0);

   }

}

其内容比较容易理解,进入中断后,调用exti_interrupt_flag_get() 库函数来重新检查是否产生了 EXTI_Line 中断,接下来把 LED 取反,操作完毕后,调用 exti_interrupt_flag_clear()清除中断标志位再退出中断服务函数。


3 实验现象

编译好程序后,下载到板子上,不管是普通方式还是中断方式,当按在按键KEY1时,LED或亮或灭。


[1] [2]
关键字:GD32  开发实战  按键 引用地址:GD32开发实战指南(基础篇) 第6章 按键

上一篇:零基础学习GD32 红外遥控器原理
下一篇:最后一页

推荐阅读最新更新时间:2024-11-07 10:17

【自学51单片机】8 -- 按键的学习,单片机最小系统
1、单片机最小系统 电源 单片机中常见5v和3.3v的单片机,“5v”和“3.3v”分别只是他们正常工作的典型值,5v和3.3v单片机也是以他们正常工作典型值命名的,他们正常工作电压的标准范围要根据单片机手册查询, 晶振 晶振分无源晶振和有源晶振。实物图和原理图见下图。 无源晶振: 依靠单片机内部振荡电路才能工作,接到单片机两个振荡引脚即可,晶体两个引脚无区别,电压无要求,两侧通常有电容,手册有要求根据手册选电容,手册无要求一般选20pf。 有源晶振: 无需依靠单片机内部振荡电路,只需外部供电达到电压要求,即可产生振荡频率,接到单片机晶振输入引脚即可接受到晶振频率,单片机晶振输出引脚无需连接。 两者区别:无源晶振信号质
[单片机]
【自学51单片机】8 -- <font color='red'>按键</font>的学习,单片机最小系统
51单片机数字频率计仿真(可按键切换量程)
之前课程设计做的 误差很小 分享给大家 里面有程序和仿真 也做过实物 可以按键切换量程10倍和1倍 单片机源程序如下: #include reg52.h #include intrins.h #define uint unsigned int #define uchar unsigned char sbit k1=P3^0; sbit k2=P2^0; sbit LED=P2^1; unsigned char code dispbit ={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//共阴数码管 unsigned char code dispcode ={0x3f,0x06,
[单片机]
51单片机数字频率计仿真(可<font color='red'>按键</font>切换量程)
STM32中按键中断分析(附源码)
  在按键学习中,我们有用到查询的方法来判断按键事件是否发生,这种查询按键事件适用于程序工作量较少的情况下,一旦程序中工作量较大较多,则势必影响程序运行的效率,为了简化程序中控制的功能模块的执行时间,引入中断控制就很有必要,,一旦有中断时间发生,则程序立马跳转到中断向量的执行程序中,执行完成后就恢复到正常的程序状态。   在STM32F中采用中断控制器NVIC来设定中断。按照中断初始化配置的结构体文件,我们需要在NVIC初始化结构体配置如下:   void EXti_PB12_Config(void)   {   //定义结构体   GPIO_InitTypeDef GPIO_InitStructure;   EXTI_I
[单片机]
如何通过GD32 MCU内部ADC参考电压通道提高采样精度?
ADC采样精度受很多因素影响,比如电源波动、参考电压波动、输入信号波动等,GD32 MCU内部提供了一个参考电压通道,理论上可以优化由于电源和参考电压较大波动引入的采样误差。 如下图所示,GD32F303 ADC内部17通道为VREFINT参考电压通道,内部参考电压的典型数值为1.2V。 当外部参考电压波动较大的情况下,如何通过内部参考电压通道提高ADC采样精度呢? 比如我们采样ADC_IN0通道的电压VIN0,那么采样的数值为: $$Rin0=(VIN0/VREF)*4096.----公式1$$ 其中,Rin0为通道0的采样数值,VIN0为通道0的输入电压,VREF为参考电压。 采样完通道0后,我们可以立即采样VREFIN
[单片机]
如何通过<font color='red'>GD32</font> MCU内部ADC参考电压通道提高采样精度?
一个按键控制四个灯的亮灭
#define uchar unsigned char //定义一下方便使用 #define uint unsigned int #define ulong unsigned long #include //包括一个52标准内核的头文件 sbit P10 = P1^0; //头文件中没有定义的IO就要自己来定义了 sbit P11 = P1^1; sbit P12 = P1^2; sbit P13 = P1^3; sbit K1= P3^4; bit ldelay=0; //长定时溢出标记,预置是0 uchar speed=10; //设置一个变量保存默认的跑马灯的移动速度 uchar speedlever
[单片机]
手机实体按键要取消,高通设屏下指纹识别
2017年,智能手机设计出现了一次小幅度的变革,其中包括使用2:1的瘦长屏幕,取消实体按键,提高屏占比。这一改变的一个前提,就是淘汰基于实体键的指纹识别。据外媒最新消息,美国高通已经推出了屏下指纹识别方案,明年的智能手机有望普及这一技术。下面就随手机便携小编一起来了解一下相关内容吧。 据美国科技新闻网站AppleInsider报道,日前,高通和中国手机厂商Oppo联合对外展示了这项技术以及原型设计,据悉指纹识别模块将会放置在手机显示屏之下。 手机实体按键要取消,高通设屏下指纹识别 据悉,高通研发的屏下指纹识别方案使用了超声波技术,这已经是第二代技术。高通表示,新的指纹识别技术可以穿透650微米的铝制材料,800微米的玻璃,
[手机便携]
S1按键中断控制LED灯
学习MSP430F5529单片机的第一个正式的程序(是CCSV5里面的例程,自己改了一点),所以注释有点弱智,大神请路过~ 代码如下: #include msp430.h int main(void) { WDTCTL = WDTPW | WDTHOLD; /* 关闭看门狗计时器,因为看门狗寄存器会不定时重置程序,即重新开始运行; 而且关闭看门狗定时器可以省去一些设置定时计数值处理的代码 */ P1DIR|=BIT0; //将P1.0设置为输出,即LED1 /* BITx的值等于第x位为1,其余位为0的二进制数的值(二进制数最
[单片机]
AVR128的程序——独立按键控制蜂鸣器鸣叫
#include iom128v.h #define uchar unsigned char #define uint unsigned int void Delayms(uint MS) { uint i,j; for(i=0;i MS;i++) for(j=0;j 1141;j++); } void main(void) { DDRA = 0XFF; PORTA = 0XFF; DDRC = 0XFF; PORTC = 0XFF; DDRF |= 0X0E; PORTF |=
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved