本帖最后由 iiv 于 2023-9-1 21:02 编辑
啥是中断
当你在打游戏时,如果有突发事件发生(例如你妈让你去打酱油),那么这个事件就成为了一个中断。中断会打断当前正在执行的任务(打游戏),并处理新的事件(去打酱油)。一旦处理完成,会返回之前的任务继续执行(打游戏)。
可以用来做什么
当单片机程序只能按顺序执行while循环中的代码时,并且需要在执行过程中判断某个数据是否到达,中断就发挥了重要作用。中断可以让程序在执行while循环的同时,当有更高优先级的事件发生时(例如某个引脚接收到了数据),自动暂停当前任务并保存上下文数据,然后执行相应的中断服务程序(通常是使用回调函数)。一旦中断任务执行完成,程序会返回到之前被中断的位置,继续恢复执行while循环,提高了程序的实时性和响应能力。
通过使用中断,程序不再需要持续地轮询或堵塞来判断数据是否到达,而是可在即时性要求较高的情况下立即响应外部事件。这种优化方式使得程序能够更加高效地利用系统资源,同时也提供了更灵活的处理方式。
大家好,俺又来啦,这次楼楼来分享一下小安派如果实现简单的中断,中断对楼楼来说用的还是比较多的,所以特意研究了一下,代码不多,楼楼把研究成果分享给大家。
效果展示:
因为我们是上升沿触发,并且上拉了io,当按键被释放时,硬件电路会检测到状态变化,并引发一个中断事件,并进入相应的中断服务程序。
楼楼把代码贴在下面 - #include "bflb_gpio.h"
- #include "bflb_mtimer.h"
- #include "board.h"
- #include "bflb_pwm_v2.h"
- #include "bflb_clock.h"
- struct bflb_device_s *gpio;
- struct bflb_device_s *pwm;
- #define io_pin GPIO_PIN_24 //中断 IO
- #define led_pin GPIO_PIN_31 //led IO
- uint8_t flg = 0;
- // 中断回调
- void gpio_isr(int irq, void *arg)
- {
- static int i = 0;
- bool intstatus = bflb_gpio_get_intstatus(gpio, io_pin);
- if (intstatus) {
- bflb_gpio_int_clear(gpio, io_pin);
- if(! flg){
- flg = 1;
- bflb_gpio_set(gpio,led_pin);
- }else{
- flg = 0;
- bflb_gpio_reset(gpio,led_pin);
- }
- printf("%d\r\n", i++);
- }
- }
- int main(void)
- {
- board_init();;
- gpio = bflb_device_get_by_name("gpio");
- pwm = bflb_device_get_by_name("pwm_v2_0");
- bflb_gpio_init(gpio,led_pin,GPIO_OUTPUT); //lde 引脚
- bflb_gpio_init(gpio, io_pin, GPIO_INPUT | GPIO_PULLUP); //上拉中断引脚
- bflb_gpio_int_init(gpio, io_pin, GPIO_INT_TRIG_MODE_SYNC_RISING_EDGE); //上升沿触发
- bflb_gpio_int_mask(gpio, io_pin, false); //启用中断
- bflb_irq_attach(gpio->irq_num, gpio_isr, gpio); //配置中断回调函数
- bflb_irq_enable(gpio->irq_num); // 使能中断
-
- // PWM配置
- bflb_gpio_init(gpio, 34, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
- struct bflb_pwm_v2_config_s cfg = {
- .clk_source = BFLB_SYSTEM_XCLK,
- .clk_div = 40,
- .period = 1000,
- };
- // 初始化
- bflb_pwm_v2_init(pwm, &cfg);
- // 启用
- bflb_pwm_v2_start(pwm);
- bflb_pwm_v2_channel_positive_start(pwm, 2);
- while (1) {
- for(int i=100;i>0;i--)
- {
- bflb_pwm_v2_channel_set_threshold(pwm, 2, i, 100);
- bflb_mtimer_delay_ms(10);
- }
- for(int i=1;i<100;i++)
- {
- bflb_pwm_v2_channel_set_threshold(pwm, 2, i, 100);
- bflb_mtimer_delay_ms(10);
- }
- }
- }
复制代码
代码很简单,楼楼添加了一些注释,如果有错误的地方大家可以自己修改,希望楼楼的分享可以帮助到大家。
|