AiPi-Eyes-S1是安信可开源团队专门为Ai-M61-32S设计的一款开发板,支持WiFi6、BLE5.3。所搭载的Ai-M61-32S 模组具有丰富的外设接口,具体包括 DVP、MJPEG、Dispaly、AudioCodec、USB2.0、SDU、以太网 (EMAC)、SD/MMC(SDH)、SPI、UART、I2C、I2S、PWM、GPDAC、GPADC、ACOMP 和 GPIO 等。
AiPi-Eyes-S1集成了SPI屏幕接口,DVP摄像头接口,外置ES8388音频编解码芯片以及预留TF卡座,并且引出USB接口,可接入USB摄像头。
从零开始学习小安派:
上期的 GPIO 输入输出编程是基于在 main 函数中设置 while 循环不断的改变 IO0 的电平,同时打印 IO1 的电平状态。本期了解关于中断编程的概念方法。
一、中断概念了解
我们在常规的程序中,都是在 main 函数中设置 While 函数不断运行代码。而中断的概念则是打断当前的程序,并保护现场,执行另外的程序,而后回到最初打断的位置,举个恰当的例子,比如我们在敲代码,忽然外卖小哥敲门说外卖到了,于是我们先 ctrl+s 保存,然后去拿完外卖顺便吃了回来继续敲代码。敲代码就是我们的常规程序(发量危),中断源就是外卖小哥的敲门声,而拿外卖吃外卖的过程就是中断服务函数。这就是中断的基本概念。
为什么要使用中断?中断是为了应对各种突发事件,如敲代码的时候忽然有人敲门送外卖。正如使用按键扫描检测和外部中断的区别来说,按键扫描会一直在循环中持续扫描按键在状态,正如我们在敲代码时,因为不知道外卖什么时候送来,还要时不时看看有没有人敲门,注意力都用在盯着门上了,怎么能认真敲代码。而中断正如我们已经设置好了耳朵,我们可以认真敲代码,当有人敲门时我们再自然而然的去开门即可,不需要一直盯着门看。
1.中断源
在上面的例子中,中断源就是外卖小哥的敲门声。我们在开门之后他就会停止敲门,但是实际上我们还是需要手动的告诉 MCU 不用敲门了,这也就是要清除中断源
的操作。
2.中断服务函数
中断服务函数,也就是我们触发中断后需要执行的操作,这里的吃外卖过程就是中断服务函数的执行过程。一般会在中断服务函数内清除中断源,也就是让外卖小哥别敲门了。
二、中断的配置函数
1.bflb_gpio_int_init
说明: gpio 外部中断初始化
void bflb_gpio_int_init(struct bflb_device_s *dev, uint8_t pin, uint8_t trig_mode);
parameter | description |
dev | 设备句柄 |
pin | gpio pin |
trig_mode | 中断触发模式 |
2.bflb_gpio_int_mask
说明:gpio 外部中断屏蔽开关
void bflb_gpio_int_mask(struct
bflb_device_s *dev, uint8_t pin, bool mask);
parameter | description |
dev | 设备句柄 |
pin | gpio pin |
mask | 中断触发模式 |
3.bflb_gpio_get_intstatus
说明: 获取 gpio 外部中断是否触发的标志
bool bflb_gpio_get_intstatus(struct bflb_device_s *dev, uint8_t pin);
parameter | description |
dev | 设备句柄 |
pin | gpio pin |
return | true 为触发,false 未触发 |
4.bflb_gpio_int_clear
说明: 清除 gpio 中断标志
void bflb_gpio_int_clear(struct bflb_device_s *dev, uint8_t pin);
parameter | description |
dev | 设备句柄 |
pin | gpio pin |
5.bflb_irq_attach
说明:设置触发中断后进入的回调函数
int bflb_irq_attach(int irq, irq_callback isr, void *arg)
parameter | description |
irq | 中断号 |
isr | 中断服务函数 |
arg | 设备句柄 |
6.bflb_irq_enable
说明:中断使能
void bflb_irq_enable(int irq)
parameter | description |
irq | 中断号 |
其他:bflb_gpio_uart_init
说明: gpio 配置成 uart 的某一个功能,可配置的可能参考上一期的 gpio uart function
void bflb_gpio_uart_init(struct bflb_device_s *dev, uint8_t pin, uint8_t uart_func);
parameter | description |
dev | 设备句柄 |
pin | gpio pin |
uart_func | uart 具体某一功能 |
三、示例讲解
这里还是对 SDK 的中断示例稍作修改
main
#include "bflb_gpio.h"
#include "bflb_mtimer.h"
#include "board.h"
struct bflb_device_s *gpio;
void gpio_isr(int irq, void *arg)
{
bool intstatus = bflb_gpio_get_intstatus(gpio, GPIO_PIN_0);
if (intstatus) {
bflb_gpio_int_clear(gpio, GPIO_PIN_0);
printf("Finished eating\r\n");
}
}
int main(void)
{
board_init();
gpio = bflb_device_get_by_name("gpio");
printf("gpio interrupt\r\n");
bflb_gpio_int_init(gpio, GPIO_PIN_0, GPIO_INT_TRIG_MODE_SYNC_LOW_LEVEL);
bflb_gpio_int_mask(gpio, GPIO_PIN_0, false);
bflb_irq_attach(gpio->irq_num, gpio_isr, gpio);
bflb_irq_enable(gpio->irq_num);
while (1) {
printf("I am typing the code\r\n");
bflb_mtimer_delay_ms(2000);
}
}
效果
当正常识别串口信息时,只会每两秒打印一次“I am typing the code”
当我用 IO0 去碰一下 TTL 的 GND 脚,也就是拉低,触发了中断,每进入一次中断会打印一次“Finished eating