3.5 独立按键中断实验

您当前位置: 首页 > K210开发者套件 > 基础实验例程

3.5 独立按键中断实验

一、实验目的

本节课主要学习K210的独立按键以及中断的功能。

 

二、实验准备

1.实验元件

独立按键BOOT、RGB灯

image.png

2.元件特性

独立按键BOOT按下时IO口为低电平,松开为高电平。

3.硬件连接

K210开发板出厂默认已经焊接好BOOT按键和RGB灯。按键连接的引脚为IO16。RGB灯R连接的是IO6,G连接的是IO7, B连接的是IO8。

image.png

image.pngimage.png

 

4.SDK中对应API功能

对应的头文件 plic.h

PLIC可以将任一外部中断源单独分配到每个 CPU 的外部中断上。这提供了强大的灵活性,能适应不同的应用需求。

PLIC模块可以设置中断回调函数,当触发中断时,会自动运行中断回调函数,并且可以配置中断优先级。

为用户提供以下接口:

• plic_init:PLIC初始化外部中断。

• plic_irq_enable:使能外部中断。

• plic_irq_disable:禁用外部中断。

• plic_set_priority:设置中断优先级。

• plic_get_priority:获取中断优先级。

• plic_irq_register:注册外部中断函数。

• plic_irq_deregister:注销外部中断函数。

 

三、实验原理

BOOT按键按下的时候会把电平拉低,松开的时候会把电平拉高,只需要检测BOOT按键的IO口的电平,如果是按下则会产生下降沿,松开会产生上升沿,以此的方式来检测并触发系统的中断,然后控制RGB灯亮或者灭。

 

四、实验过程

1.首先根据上面的硬件连接引脚图,K210的硬件引脚和软件功能使用的是FPIOA映射关系。

这里要注意的是程序里操作的都是软件引脚,所以需要先把硬件引脚映射成软件GPIO功能,操作的时候直接操作软件GPIO即可。

image.png

image.png

2.第二部需要初始化外部中断服务,并且使能全局中断。如果没有这一步操作,系统的中断就不会运行,所以也不会调用中断回调函数。

image.png

3.在使用RGB灯前需要初始化,也就是把RGB灯的软件GPIO设置为输出模式。

image.png

4.然后关闭RGB灯,同样是设置RGB灯的GPIO为高电平则可以让RGB灯熄灭。

image.png

5.使用BOOT按键同样需要初始化,设置BOOT键为上拉输入模式,设置按键的GPIO电平触发模式为上升沿和下降沿,也可以设置单上升沿或单下降沿等,设置BOOT按键的中断回调函数为key_irq_cb,参数为g_count, g_count是一个全局uint32_t变量,功能是记录电平触发的次数。

image.png

image.png

6.每次BOOT按下或者松开都会触发中断函数key_irq_cb,在中断里先读取当前按键的状态,保存到key_state中,并且通过串口打印出当前按键的状态,这里只是为了调试才在中断中打印信息的,在后续的开发中不建议这样操作。由于ctx为void型指针,void型指针表示不指定指针类型,所以我们需要新建一个uint32_t类型的指针tmp指向它,然后每次进中断tmp所指向的值自动加1,也就是g_count的值加1。最后是判断按键的状态,当按键为按下时,点亮红灯,当按键为松开时,关闭红灯。

image.png

7.最后是一个while(1)循环,这个是必须的,否则系统就会退出,不再运行。

image.png

8.编译调试,烧录运行

把本课程资料中的button复制到SDK中的src目录下,

然后进入build目录,运行以下命令编译。

cmake .. -DPROJ=button -G "MinGW Makefiles"

make

image.png

编译完成后,在build文件夹下会生成button.bin文件。

使用type-C数据线连接电脑与K210开发板,打开kflash,选择对应的设备,再将程序固件烧录到K210开发板上。

 

五、实验现象

烧录完成固件后,系统会弹出一个终端界面,如果没有弹出终端界面的可以打开串口助手显示调试内容。

打开电脑的串口助手,选择对应的K210开发板对应的串口号,波特率设置为115200,然后点击打开串口助手。注意还需要设置一下串口助手的DTR和RTS。在串口助手底部此时的4.DTR和7.RTS默认是红色的,点击4.DTR和7.RTS,都设置为绿色,然后按一下K210开发板的复位键。

image.png

按下BOOT按键不松开,可以看到RGB亮红灯,并且串口助手上显示IRQ The PIN is 0  count is 0,松开的时候会显示IRQ The PIN is 1  count is 1,每次按下或松开count的值都自动加1。

 image.png

image.png

六、实验总结

1.BOOT按键与RGB同样适用GPIOHS的函数,只是按键使用输入模式,RGB使用输出模式。

2.使用外部中断前需要先初始化PLIC以及使能全局中断服务。

3.在中断回调函数中可以传入一个参数,参数类型可以传入自己需要的类型。

 

 

 

附:API

对应的头文件 plic.h

plic_init

描述

PLIC初始化外部中断。

函数原型

void plic_init(void)


参数

无。

返回值

无。

plic_irq_enable

描述

使能外部中断。

函数原型

int plic_irq_enable(plic_irq_t irq_number)


参数

参数名称

描述

输入输出

irq_number

中断号

输入

返回值

返回值

描述

0

成功

0

失败

plic_irq_disable

描述

禁用外部中断。

函数原型

int plic_irq_disable(plic_irq_t irq_number)


参数

参数名称

描述

输入输出

irq_number

中断号

输入

返回值

返回值

描述

0

成功

0

失败

plic_set_priority

描述

设置中断优先级。

函数原型

int plic_set_priority(plic_irq_t irq_number, uint32_t priority)


参数

参数名称

描述

输入输出

irq_number

中断号

输入

priority

中断优先级

输入

返回值

返回值

描述

0

成功

0

失败

plic_get_priority

描述

获取中断优先级。

函数原型

uint32_t plic_get_priority(plic_irq_t irq_number)


参数

参数名称

描述

输入输出

irq_number

中断号

输入

返回值

irq_number中断的优先级。

plic_irq_register

描述

注册外部中断函数。

函数原型

int plic_irq_register(plic_irq_t irq, plic_irq_callback_t callback, void* ctx)


参数

参数名称

描述

输入输出

irq

中断号

输入

callback

中断回调函数

输入

ctx

回调函数的参数

输入

返回值

返回值

描述

0

成功

0

失败

plic_irq_deregister

描述

注销外部中断函数。

函数原型

int plic_irq_deregister(plic_irq_t irq)


参数

参数名称

描述

输入输出

irq

中断号

输入

返回值

返回值

描述

0

成功

0

失败

举例

/* 设置GPIOHS0的触发中断 */
int count = 0;
int gpiohs_pin_onchange_isr(void *ctx)
{
    int *userdata = (int *)ctx;
    *userdata++;
}
plic_init();
plic_set_priority(IRQN_GPIOHS0_INTERRUPT, 1);
plic_irq_register(IRQN_GPIOHS0_INTERRUPT, gpiohs_pin_onchange_isr, &count);
plic_irq_enable(IRQN_GPIOHS0_INTERRUPT);
sysctl_enable_irq();


数据类型

相关数据类型、数据结构定义如下:

·         plic_irq_t:外部中断号。

·         plic_irq_callback_t:外部中断回调函数。

plic_irq_t

描述

外部中断号。

定义

typedef enum _plic_irq
{
    IRQN_NO_INTERRUPT        = 0, /*!< The non-existent interrupt */
    IRQN_SPI0_INTERRUPT      = 1, /*!< SPI0 interrupt */
    IRQN_SPI1_INTERRUPT      = 2, /*!< SPI1 interrupt */
    IRQN_SPI_SLAVE_INTERRUPT = 3, /*!< SPI_SLAVE interrupt */
    IRQN_SPI3_INTERRUPT      = 4, /*!< SPI3 interrupt */
    IRQN_I2S0_INTERRUPT      = 5, /*!< I2S0 interrupt */
    IRQN_I2S1_INTERRUPT      = 6, /*!< I2S1 interrupt */
    IRQN_I2S2_INTERRUPT      = 7, /*!< I2S2 interrupt */
    IRQN_I2C0_INTERRUPT      = 8, /*!< I2C0 interrupt */
    IRQN_I2C1_INTERRUPT      = 9, /*!< I2C1 interrupt */
    IRQN_I2C2_INTERRUPT      = 10, /*!< I2C2 interrupt */
    IRQN_UART1_INTERRUPT     = 11, /*!< UART1 interrupt */
    IRQN_UART2_INTERRUPT     = 12, /*!< UART2 interrupt */
    IRQN_UART3_INTERRUPT     = 13, /*!< UART3 interrupt */
    IRQN_TIMER0A_INTERRUPT   = 14, /*!< TIMER0 channel 0 or 1 interrupt */
    IRQN_TIMER0B_INTERRUPT   = 15, /*!< TIMER0 channel 2 or 3 interrupt */
    IRQN_TIMER1A_INTERRUPT   = 16, /*!< TIMER1 channel 0 or 1 interrupt */
    IRQN_TIMER1B_INTERRUPT   = 17, /*!< TIMER1 channel 2 or 3 interrupt */
    IRQN_TIMER2A_INTERRUPT   = 18, /*!< TIMER2 channel 0 or 1 interrupt */
    IRQN_TIMER2B_INTERRUPT   = 19, /*!< TIMER2 channel 2 or 3 interrupt */
    IRQN_RTC_INTERRUPT       = 20, /*!< RTC tick and alarm interrupt */
    IRQN_WDT0_INTERRUPT      = 21, /*!< Watching dog timer0 interrupt */
    IRQN_WDT1_INTERRUPT      = 22, /*!< Watching dog timer1 interrupt */
    IRQN_APB_GPIO_INTERRUPT  = 23, /*!< APB GPIO interrupt */
    IRQN_DVP_INTERRUPT       = 24, /*!< Digital video port interrupt */
    IRQN_AI_INTERRUPT        = 25, /*!< AI accelerator interrupt */
    IRQN_FFT_INTERRUPT       = 26, /*!< FFT accelerator interrupt */
    IRQN_DMA0_INTERRUPT      = 27, /*!< DMA channel0 interrupt */
    IRQN_DMA1_INTERRUPT      = 28, /*!< DMA channel1 interrupt */
    IRQN_DMA2_INTERRUPT      = 29, /*!< DMA channel2 interrupt */
    IRQN_DMA3_INTERRUPT      = 30, /*!< DMA channel3 interrupt */
    IRQN_DMA4_INTERRUPT      = 31, /*!< DMA channel4 interrupt */
    IRQN_DMA5_INTERRUPT      = 32, /*!< DMA channel5 interrupt */
    IRQN_UARTHS_INTERRUPT    = 33, /*!< Hi-speed UART0 interrupt */
    IRQN_GPIOHS0_INTERRUPT   = 34, /*!< Hi-speed GPIO0 interrupt */
    IRQN_GPIOHS1_INTERRUPT   = 35, /*!< Hi-speed GPIO1 interrupt */
    IRQN_GPIOHS2_INTERRUPT   = 36, /*!< Hi-speed GPIO2 interrupt */
    IRQN_GPIOHS3_INTERRUPT   = 37, /*!< Hi-speed GPIO3 interrupt */
    IRQN_GPIOHS4_INTERRUPT   = 38, /*!< Hi-speed GPIO4 interrupt */
    IRQN_GPIOHS5_INTERRUPT   = 39, /*!< Hi-speed GPIO5 interrupt */
    IRQN_GPIOHS6_INTERRUPT   = 40, /*!< Hi-speed GPIO6 interrupt */
    IRQN_GPIOHS7_INTERRUPT   = 41, /*!< Hi-speed GPIO7 interrupt */
    IRQN_GPIOHS8_INTERRUPT   = 42, /*!< Hi-speed GPIO8 interrupt */
    IRQN_GPIOHS9_INTERRUPT   = 43, /*!< Hi-speed GPIO9 interrupt */
    IRQN_GPIOHS10_INTERRUPT  = 44, /*!< Hi-speed GPIO10 interrupt */
    IRQN_GPIOHS11_INTERRUPT  = 45, /*!< Hi-speed GPIO11 interrupt */
    IRQN_GPIOHS12_INTERRUPT  = 46, /*!< Hi-speed GPIO12 interrupt */
    IRQN_GPIOHS13_INTERRUPT  = 47, /*!< Hi-speed GPIO13 interrupt */
    IRQN_GPIOHS14_INTERRUPT  = 48, /*!< Hi-speed GPIO14 interrupt */
    IRQN_GPIOHS15_INTERRUPT  = 49, /*!< Hi-speed GPIO15 interrupt */
    IRQN_GPIOHS16_INTERRUPT  = 50, /*!< Hi-speed GPIO16 interrupt */
    IRQN_GPIOHS17_INTERRUPT  = 51, /*!< Hi-speed GPIO17 interrupt */
    IRQN_GPIOHS18_INTERRUPT  = 52, /*!< Hi-speed GPIO18 interrupt */
    IRQN_GPIOHS19_INTERRUPT  = 53, /*!< Hi-speed GPIO19 interrupt */
    IRQN_GPIOHS20_INTERRUPT  = 54, /*!< Hi-speed GPIO20 interrupt */
    IRQN_GPIOHS21_INTERRUPT  = 55, /*!< Hi-speed GPIO21 interrupt */
    IRQN_GPIOHS22_INTERRUPT  = 56, /*!< Hi-speed GPIO22 interrupt */
    IRQN_GPIOHS23_INTERRUPT  = 57, /*!< Hi-speed GPIO23 interrupt */
    IRQN_GPIOHS24_INTERRUPT  = 58, /*!< Hi-speed GPIO24 interrupt */
    IRQN_GPIOHS25_INTERRUPT  = 59, /*!< Hi-speed GPIO25 interrupt */
    IRQN_GPIOHS26_INTERRUPT  = 60, /*!< Hi-speed GPIO26 interrupt */
    IRQN_GPIOHS27_INTERRUPT  = 61, /*!< Hi-speed GPIO27 interrupt */
    IRQN_GPIOHS28_INTERRUPT  = 62, /*!< Hi-speed GPIO28 interrupt */
    IRQN_GPIOHS29_INTERRUPT  = 63, /*!< Hi-speed GPIO29 interrupt */
    IRQN_GPIOHS30_INTERRUPT  = 64, /*!< Hi-speed GPIO30 interrupt */
    IRQN_GPIOHS31_INTERRUPT  = 65, /*!< Hi-speed GPIO31 interrupt */
    IRQN_MAX
} plic_irq_t;


成员

成员名称

描述

IRQN_NO_INTERRUPT

不存在

IRQN_SPI0_INTERRUPT

SPI0中断

IRQN_SPI1_INTERRUPT

SPI1中断

IRQN_SPI_SLAVE_INTERRUPT

SPI中断

IRQN_SPI3_INTERRUPT

SPI3中断

IRQN_I2S0_INTERRUPT

I2S0 中断

IRQN_I2S1_INTERRUPT

I2S1 中断

IRQN_I2S2_INTERRUPT

I2S2 中断

IRQN_I2C0_INTERRUPT

I2C0 中断

IRQN_I2C1_INTERRUPT

I2C1 中断

IRQN_I2C2_INTERRUPT

I2C2 中断

IRQN_UART1_INTERRUPT

UART1中断

IRQN_UART2_INTERRUPT

UART2中断

IRQN_UART3_INTERRUPT

UART3中断

IRQN_TIMER0A_INTERRUPT

TIMER0通道01中断

IRQN_TIMER0B_INTERRUPT

TIMER0通道23中断

IRQN_TIMER1A_INTERRUPT

TIMER1通道01中断

IRQN_TIMER1B_INTERRUPT

TIMER1通道23中断

IRQN_TIMER2A_INTERRUPT

TIMER2通道01中断

IRQN_TIMER2B_INTERRUPT

TIMER2通道23中断

IRQN_RTC_INTERRUPT

RTC 滴答中断和报警中断

IRQN_WDT0_INTERRUPT

看门狗0中断

IRQN_WDT1_INTERRUPT

看门狗1中断

IRQN_APB_GPIO_INTERRUPT

普通GPIO中断

IRQN_DVP_INTERRUPT

数字摄像头(DVP)中断

IRQN_AI_INTERRUPT

AI 加速器中断

IRQN_FFT_INTERRUPTFFT

傅里叶加速器中断

IRQN_DMA0_INTERRUPT

DMA 通道0中断

IRQN_DMA1_INTERRUPT

DMA 通道1中断

IRQN_DMA2_INTERRUPT

DMA 通道2中断

IRQN_DMA3_INTERRUPT

DMA 通道3中断

IRQN_DMA4_INTERRUPT

DMA 通道4中断

IRQN_DMA5_INTERRUPT

DMA 通道5中断

IRQN_UARTHS_INTERRUPT

高速UART中断

IRQN_GPIOHS0_INTERRUPT

高速GPIO0中断

IRQN_GPIOHS1_INTERRUPT

高速GPIO1中断

IRQN_GPIOHS2_INTERRUPT

高速GPIO2中断

IRQN_GPIOHS3_INTERRUPT

高速GPIO3中断

IRQN_GPIOHS4_INTERRUPT

高速GPIO4中断

IRQN_GPIOHS5_INTERRUPT

高速GPIO5中断

IRQN_GPIOHS6_INTERRUPT

高速GPIO6中断

IRQN_GPIOHS7_INTERRUPT

高速GPIO7中断

IRQN_GPIOHS8_INTERRUPT

高速GPIO8中断

IRQN_GPIOHS9_INTERRUPT

高速GPIO9中断

IRQN_GPIOHS10_INTERRUPT

高速GPIO10中断

IRQN_GPIOHS11_INTERRUPT

高速GPIO11中断

IRQN_GPIOHS12_INTERRUPT

高速GPIO12中断

IRQN_GPIOHS13_INTERRUPT

高速GPIO13中断

IRQN_GPIOHS14_INTERRUPT

高速GPIO14中断

IRQN_GPIOHS15_INTERRUPT

高速GPIO15中断

IRQN_GPIOHS16_INTERRUPT

高速GPIO16中断

IRQN_GPIOHS17_INTERRUPT

高速GPIO17中断

IRQN_GPIOHS18_INTERRUPT

高速GPIO18中断

IRQN_GPIOHS19_INTERRUPT

高速GPIO19中断

IRQN_GPIOHS20_INTERRUPT

高速GPIO20中断

IRQN_GPIOHS21_INTERRUPT

高速GPIO21中断

IRQN_GPIOHS22_INTERRUPT

高速GPIO22中断

IRQN_GPIOHS23_INTERRUPT

高速GPIO23中断

IRQN_GPIOHS24_INTERRUPT

高速GPIO24中断

IRQN_GPIOHS25_INTERRUPT

高速GPIO25中断

IRQN_GPIOHS26_INTERRUPT

高速GPIO26中断

IRQN_GPIOHS27_INTERRUPT

高速GPIO27中断

IRQN_GPIOHS28_INTERRUPT

高速GPIO28中断

IRQN_GPIOHS29_INTERRUPT

高速GPIO29中断

IRQN_GPIOHS30_INTERRUPT

高速GPIO30中断

IRQN_GPIOHS31_INTERRUPT

高速GPIO31中断

plic_irq_callback_t

描述

外部中断回调函数。

定义

typedef int (*plic_irq_callback_t)(void *ctx);