目录

1. 开发环境

1.1 系统环境与硬件环境

2. GPIO中断

2.1 GPIO中断介绍

2.2 中断的好处

3. 分析Zephry设备树DTC文件

3.1 通过名称找到对应GPIO口

3.2 设备树类型

3.3 实例化设备树类型

3.4 GPIO操作API

4. 示例

4.1 包含头文件与定义操作的PIN脚

4.2 创建中断服务函数

4.3 实例化LED0 与 定义存储callback属性的结构体

4.4 定义一个逻辑变量来表示灯状态

4.5 开启中断

4.6 初始化led与循环控制led

4.7 完整代码:

5. 注意事项


1. 开发环境

1.1 系统环境与硬件环境

系统环境

系统

版本

UBNUTU 20.04 LTS

硬件环境

厂商

型号

STM32 F746G_DISCO CORTEX-M7 

中断控制器

型号

说明

NVIC (Nested Vectored Interrupt Controller) 嵌套向量中断控制器

你可以在你的芯片资料中找到你的芯片是什么中断控制器

NVIC支持嵌套式中断,意思就是当触发中断时支持多层中断,每个中断拥有优先级,每个中断都会有一个优先级,CPU根据优先级高低执行不同的中断

如在执行当前中断时又来了一个中断,那么CPU会判断这个中断的中断优先级与目前执行的中断优先级相比谁更高,若大于当前中断则跳转过去执行新中断,否则挂起等待此次中断执行结束下次处理

NVIC与CPU紧密贴近,CPU可以通过总线与NVIC通讯获取当前中断的状态以确保该执行哪个中断

在操作系统封装之后我们基本上不用去关心使用的什么中断处理器,因为操作系统使用了统一API来管理这些中断处理器,如中断处理器FIQ或IRQ模式

中断信号

说明

FIQ 快速中断 IRQ
IRQ 外部中断 IR

那么要开启它们的话需要使用特定指令来使能对应的中断

指令

描述

cpsid i 禁止IRQ中断
cpsie i 使能IRQ中断
cpsid f 禁止FIQ中断
cpsie f 使能FIQ中断

2. GPIO中断

2.1 GPIO中断介绍

Zephry使用了与Linux内核下一致的Dtc设备树对底层硬件进行了封装 , 大部分的底层对上层是不可见的 , 同时提供了一组API用来便于我们操作这些底层硬件 , 使得开发变得更其简单了.

我们如果想开启一个GPIO中断首先需要知道这个GPIO名称 , 这里不是地址 , 相较于裸机我们需要通过GPIO得到地址并对里面的功能寄存器进行配置 , Zephry下只需要通过GPIO名称然后通过一组特定API就可以对其进行配置了.

Zephry下的GPIO中断与裸机编程时的中断无区别 , 流程都是先对GPIO寄存器进行配置 , 然后使能工作

这里我的中断处理器类型如下:

设置流程如下:

设置INPUT模式->设置INT中断模式->注册中断函数与配置触发条件 (上升沿触发 | 下降沿触发···)->注册到LVT->使能中断

2.1.2 中断执行过程

我之前学过x8086架构的,所以这里以x8086架构的中断来说会更加清晰一点

首先第一步当设备通过总线向8259A(x8086架构常用的中断控制器)发送中断信号时,8259A会将中断IRQ号发送给CPU

CPU根据IRQ中断表到中断向量表LVT中寻找对应的节点,LVT是一个队列结构体,IRQ号就是它的索引,在里面会找到一些基本信息与LDT(局部描述符)的段选择符

拿着这个段选择符(GDT全局描述符的索引)到GDT里去寻找中断服务程序的信息,其中就有一个属性叫DPL,它代表当前服务的优先级,这里CPU会根据优先级的不同来决定是否执行它

CPU会从当前CS寄存器(代码段基地址寄存器)里把CPL取出来,CPL是当前代码段的优先级,中断服务与普通程序的代码优先级是不同的,若当前CPL大于DPL那么则不会执行中断服务,否则执行。

其次8259A支持嵌套模式

一般完全嵌套方式:只执行优先级高的,低优先级的屏蔽不执行

特殊完全嵌套方式:优先级高的先执行,优先级低的保存起来等待执行

下图是特殊完全嵌套方式的8259A的中断过程

x8086的cpu会每执行一条语句就去检查一下中断标志位

那么知道了x8086的以后其实arm架构的也很简单,arm架构与x8086相比就是少了GDT与LDT,它会直接在向量表里就可以找到中断服务的基本信息,其次新中断服务优先级是通过NVIC里的寄存器获得的

2.2 中断的好处

当我们需要为一个外设开发中断时首先应是确定外设接线位置 , 如我想为传感器开发一个驱动用于检测传感器的变化 , 但这个传感器只有在一些特定情况下才有会数据过来 , 如红外传感器只有在红外线有反馈的情况下才会输出数据 , 除此以外大多数情况下都是无数据的 , 难道我们要编写一个程序一直循环监听目标GPIO口是否有数据过来吗? 这样的做法非常不合理 , 因为这会吃尽CPU的占有率 , 一直处于while循环状态下监听不如此时让CPU进入低功耗状态或者我们去做一些其它的事情 , 当标志位溢出产生中断时才唤醒我们的CPU去干活这是最合理的设计.

3. 分析Zephry设备树DTC文件

3.1 通过名称找到对应GPIO口

我的开发板上有一个LED的灯 , 其实这里我们可以不用看它的原理图LED接在哪儿 , 我们只需要根据板子的型号去Zephry下的boards目录下找到你板子的dtc文件目录 , 这里已经把你板子所有的硬件环境配置出来了 , Zephry会调用脚本解析这个文件并生成对应的结构体文件供我们使用.

如我的板子是stm32f746g_disco

可以在boards下去寻找 , 注意是小写 , Zephry下统一小写格式命名dts文件

find . -iname "stm32f746g_disco.dts"

如果没有找到你的板子可以根据类似的板型做适当的移植

如以下是我的配置:

/dts-v1/;
#include <st/f7/stm32f746Xg.dtsi>
#include <st/f7/stm32f746nghx-pinctrl.dtsi>
#include "arduino_r3_connector.dtsi"/ {model = "STMicroelectronics STM32F746G DISCOVERY board";compatible = "st,stm32f746g-disco";chosen {zephyr,console = &usart1;zephyr,shell-uart = &usart1;zephyr,sram = &sram0;zephyr,flash = &flash0;zephyr,dtcm = &dtcm;zephyr,flash-controller = &n25q128a1;};leds {compatible = "gpio-leds";green_led_1: led_1 {gpios = <&gpioi 1 GPIO_ACTIVE_HIGH>;label = "User LD1";};};gpio_keys {compatible = "gpio-keys";user_button: button {label = "User";gpios = <&gpioi 11 GPIO_ACTIVE_HIGH>;};};aliases {led0 = &green_led_1;sw0 = &user_button;kscan0 = &touch_controller;};
};

可以看到里面的led已经定义出来 , 里面有一个aliases的选项树结构 , 这个关键字代表别名这里将green_led_1定义别名为led0 , 同时也有其它的别名

aliases {led0 = &green_led_1;sw0 = &user_button;kscan0 = &touch_controller;};

这些别名我们是可以直接在代码里使用的 , Zephry的编译系统会解析dts文件并生成对应的头文件并包含到我们的项目工程里去 , 这样编译期间就可以引用它们了.

其中也可以看到它包含了一些头文件 , 在dtc里dtsi是属于头文件的后缀 , 但是也可以包含.h文件 , 这也是支持的

#include <st/f7/stm32f746Xg.dtsi>
#include <st/f7/stm32f746nghx-pinctrl.dtsi>
#include "arduino_r3_connector.dtsi"

我们可以打开一个头文件看一下 , 就拿"stm32f746Xg.dtsi"头文件来说 , 它位于Zephry项目工程的"dts/arm/st/f7/"目录中 , 它里面定义了soc的基本信息

#include <mem.h>
#include <st/f7/stm32f746.dtsi>/ {soc {flash-controller@40023c00 {flash0: flash@8000000 {reg = <0x08000000 DT_SIZE_K(1024)>;};};};
};

它里面包含了一个头文件"stm32f746.dtsi" 这个头文件包含了"stm32f745.dtsi" 而这个文件包含了所有GPIO以及UART等硬件信息

从这个包含角度可以得出stm32f746的架构与stm32f745基本一致.

可以打开stm32f745.dtsi看一下 (位于dts/arm/st/f7/stm32f745.dtsi)

由于代码过长这里只把要分析的部分列出来

#include <st/f7/stm32f7.dtsi>
···

它包含了"stm32f7.dtsi"文件 , 这个文件里定义f7系列的所有基本硬件信息  , 我们在打开它就可以看到所有的硬件信息

这里只列了一小部分

···           gpioc: gpio@40020800 {compatible = "st,stm32-gpio";gpio-controller;#gpio-cells = <2>;reg = <0x40020800 0x400>;clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000004>;label = "GPIOC";};gpiod: gpio@40020C00 {compatible = "st,stm32-gpio";gpio-controller;#gpio-cells = <2>;reg = <0x40020C00 0x400>;clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000008>;label = "GPIOD";};gpioe: gpio@40021000 {compatible = "st,stm32-gpio";gpio-controller;#gpio-cells = <2>;reg = <0x40021000 0x400>;clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000010>;label = "GPIOE";};gpiof: gpio@40021400 {compatible = "st,stm32-gpio";gpio-controller;#gpio-cells = <2>;reg = <0x40021400 0x400>;clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000020>;label = "GPIOF";};
···

可以很清晰的看到所有gpio信息 , 这里可以看下我们led的定义

leds {compatible = "gpio-leds";green_led_1: led_1 {gpios = <&gpioi 1 GPIO_ACTIVE_HIGH>;label = "User LD1";};};

它里面定义了一个gpios的口指向gpioi配置属性为即高电平有效 , 就是告诉Zephry想要驱动它必须给高电平 , 有的线路连接极性不同对电平高低有要求 , 有的线路可能需要低电平才能驱动 , 这部分需要看电路原理图.

通常情况下若Zephry不支持你的板子型号 , 我们只需要根据soc型号到Zephry下去寻找对应的DTC配置工程然后做一个简单的移植就可以了.

3.2 设备树类型

gpio_dt_spec类型是一个结构体 , 是专门用于实例化dtc设备树中定义的信息 , 它位于"zephyr/include/drivers"目录中

原型如下

struct gpio_dt_spec {const struct device *port;gpio_pin_t pin;gpio_dt_flags_t dt_flags;
};

参数介绍

变量名

类型

作用

port device* 指向dtc实例化后的设备句柄
pin gpio_pin_t 指向设备pin脚
dt_flags gpio_dt_flags_t 设备属性

其中port变量里保存了一些基本的设备运行时的属性与参数 , 其原型如下

struct device {const char *name;const void *config;const void *api;struct device_state * const state;void * const data;const device_handle_t *const handles;
#ifdef CONFIG_PM_DEVICEpm_device_control_callback_t pm_control;struct pm_device * const pm;
#endif
};

参数介绍

变量名

类型

作用

api const void * 设备实例公开的API结构的地址
config const void * 设备实例配置信息的地址
data void * const 设备实例私有数据的地址
handles device_handle_t * 指向与设备关联的句柄的可选指针
name const char * 设备实例的名称 , 在DTC文件中配置
pm pm_device * 指向设备实例电源管理数据的指针 (仅设备支持电源情况下可用)
pm_control pm_device_control_callback_t 电源管理功能 (仅设备支持电源情况下可用)
state device_state * 公共设备状态的地址

基本上当我们在需要使用定义在设备树文件中的总线或外设时都需要用到"gpio_dt_spec"类型

3.3 实例化设备树类型

在实例化设备树时提供了一组宏函数:

  1. DT_ALIAS
  2. DT_GPIO_LABEL
  3. DT_GPIO_PIN
  4. DT_GPIO_FLAGS
  5. GPIO_DT_SPEC_GET_OR

定义在:/zephyr/include/drivers/gpio.h

这组宏函数会在编译期间获取实例化的参数 , Zephry在真正实际编译我们代码之前会先调用脚本将DTC设备树解析并生成与修改对应的.h文件给我们c文件使用 , 会自动包含进来 , 这组宏函数就是获取生成的文件中对应的变量类型

这些工作都是在编译期间完成的.

这里介绍一下每个宏函数的作用以及用法

3.3.1 DT_ALIAS

函数原型

参数说明

作用

DT_ALIAS(alias) 别名 获取设备树中aliases元素下的别名类型

用法示例:

/*dtc文件  leds {compatible = "gpio-leds";green_led_1: led_1 {gpios = <&gpioi 1 GPIO_ACTIVE_HIGH>;label = "User LD1";};};aliases {led0 = &green_led_1;};
*/
/*用法*/
//从aliases元素中获取led0别名实际的名称
DT_ALIAS(led0) //返回green_led_1元素

3.3.2 DT_GPIO_LABEL

函数原型

参数说明

作用

DT_GPIO_LABEL(node_id, gpio_pha) 节点名 , GPIO元素名称 获取GPIO名称

用法示例:

/*dtc文件  leds {compatible = "gpio-leds";green_led_1: led_1 {gpios = <&gpioi 1 GPIO_ACTIVE_HIGH>;label = "User LD1";};};aliases {led0 = &green_led_1;};
*/
/*用法*/
//获取实际gpio名称
DT_GPIO_LABEL(green_led_1,gpios) //返回gpioi

3.3.3 DT_GPIO_PIN

函数原型

参数说明

作用

DT_GPIO_PIN(node_id, gpio_pha) 节点名 , GPIO元素名称 获取GPIO的PIN脚索引

用法示例:

/*dtc文件  leds {compatible = "gpio-leds";green_led_1: led_1 {gpios = <&gpioi 1 GPIO_ACTIVE_HIGH>;label = "User LD1";};};aliases {led0 = &green_led_1;};
*/
/*用法*/
//获取实际pin脚索引
DT_GPIO_LABEL(green_led_1,gpios) //返回1

3.3.4 DT_GPIO_FLAGS

函数原型

参数说明

作用

DT_GPIO_FLAGS(node_id, gpio_pha) 节点名 , GPIO元素名称 获取GPIO的属性

用法示例:

/*dtc文件  leds {compatible = "gpio-leds";green_led_1: led_1 {gpios = <&gpioi 1 GPIO_ACTIVE_HIGH>;label = "User LD1";};};aliases {led0 = &green_led_1;};
*/
/*用法*/
//获取GPIO属性 , 可以理解为获取GPIO中特殊功能寄存器的状态
DT_GPIO_FLAGS(green_led_1,gpios) //返回GPIO_ACTIVE_HIGH

3.3.5 GPIO_DT_SPEC_GET_OR

函数原型

参数说明

作用

GPIO_DT_SPEC_GET_OR(node_id, prop, default_value) 节点名 , GPIO元素名称 , 下标索引 获取GPIO的属性 , 并实例化为gpio_dt_spec类型

用法示例:

/*dtc文件  leds {compatible = "gpio-leds";green_led_1: led_1 {gpios = <&gpioi 1 GPIO_ACTIVE_HIGH>;label = "User LD1";};};aliases {led0 = &green_led_1;};
*/
/*用法*/
//获取GPIO属性 , 可以理解为获取GPIO中特殊功能寄存器的状态
static struct gpio_dt_spec gpio_led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios,{0}) //这里索引用{}为格式 , 从0开始计算

3.4 GPIO操作API

  1. gpio_pin_configure_dt
  2. gpio_pin_interrupt_configure_dt
  3. gpio_init_callback
  4. gpio_add_callback
  5. gpio_pin_configure
  6. gpio_pin_set

定义在:/zephyr/include/drivers/gpio.h

函数统一返回值为:成功返回0,失败返回非0

函数原型:

3.4.1 gpio_pin_configure_dt

函数原型

参数说明

作用

gpio_pin_configure_dt(struct gpio_dt_spec * st, int FLAGS) dt实例化结构体 , 要设置的属性 设置GPIO属性

3.4.2 gpio_pin_interrupt_configure_dt

函数原型

参数说明

作用

gpio_pin_interrupt_configure_dt(struct gpio_dt_spec * st, int FLAGS) dt实例化结构体 , 要设置的属性 设置GPIO中断

3.4.3 gpio_init_callback

函数原型

参数说明

作用

gpio_init_callback(struct gpio_dt_spec * st, void (*func)(const struct device *,struct gpio_callback* ,uint32_t) ,_addr,bit_pin) dt实例化结构体 , 中断服务函数入口,pin脚需要使用BIT宏转换 设置GPIO中断函数

3.4.4 gpio_add_callback

函数原型

参数说明

作用

gpio_add_callback(struct device *port , struct gpio_callback * st) device结构体 , 存储设置属性 添加中断服务

3.4.5 gpio_pin_configure

函数原型

参数说明

作用

gpio_pin_configure(struct device *port , pin,int FLAGS) device结构体 , pin脚,属性 设置GPIO相应PIN脚属性

3.4.6 gpio_pin_set

函数原型

参数说明

作用

gpio_pin_set(struct device *port , pin,int value) device结构体 , pin脚,值 设置GPIO值

属性可选如下参数:

宏定义

说明

宏定义

说明

GPIO_INPUT 输入模式
GPIO_OUTPUT 输出模式
GPIO_DISCONNECTED 禁用输入输出模式
GPIO_OUTPUT_INIT_LOW 将输出初始状态设置为低
GPIO_OUTPUT_INIT_HIGH

将输出初始状态设置为高

GPIO_OUTPUT_INIT_LOGICAL 根据逻辑级别初始化输出
GPIO_OUTPUT_LOW 将GPIO引脚配置为输出,并将其初始化为低状态
GPIO_OUTPUT_HIGH 将GPIO引脚配置为输出,并将其初始化为高状态。
GPIO_OUTPUT_INACTIVE 将GPIO引脚配置为输出,并将其初始化为逻辑0。
GPIO_OUTPUT_ACTIVE 将GPIO引脚配置为输出,并将其初始化为逻辑1。
GPIO_INT_DISABLE 禁用GPIO引脚中断
GPIO_INT_LEVELS_LOGICAL 电平敏感
GPIO_INT_EDGE 边沿敏感
GPIO_INT_LOW_0 低电平或逻辑电平为0触发
GPIO_INT_HIGH_1 高电平或逻辑电平为1触发
GPIO_INT_EDGE_RISING 将GPIO中断配置为在引脚上升沿上触发并启用它
GPIO_INT_EDGE_FALLING 将GPIO中断配置为在引脚上升沿或下降沿触发,并启用它
GPIO_INT_EDGE_FALLING 将GPIO中断配置为在引脚下降沿上触发并启用它
GPIO_INT_EDGE_BOTH 将GPIO中断配置为在引脚上升沿或下降沿触发,并启用它
GPIO_INT_LEVEL_LOW 将GPIO中断配置为在引脚物理电平低时触发并启用它
GPIO_INT_LEVEL_HIGH 将GPIO中断配置为在引脚物理电平高时触发并启用它
GPIO_INT_EDGE_TO_INACTIVE 将GPIO中断配置为在引脚状态更改为逻辑级别0时触发,并启用它
GPIO_INT_EDGE_TO_ACTIVE 将GPIO中断配置为在引脚状态更改为逻辑级别1时触发,并启用它
GPIO_INT_LEVEL_INACTIVE 将GPIO中断配置为在引脚逻辑级别0上触发并启用它
GPIO_INT_LEVEL_ACTIVE

将GPIO中断配置为在引脚逻辑级别1上触发,并启用它

GPIO_INT_DEBOUNCE 启用GPIO引脚去抖动

4. 示例

这里写一个监听LED灯的中断服务

业务需求:

检测LED灯是否亮起,若LED灯亮起则执行中断

4.1 包含头文件与定义操作的PIN脚

#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <inttypes.h>
#include <sys/util.h>
#include <sys/printk.h>
//pin
#define PIN DT_GPIO_PIN(DT_ALIAS(led0), gpios)

4.2 创建中断服务函数

这里原型上面说过,要求是:void (*func)(const struct device *,struct gpio_callback* ,uint32_t)

这里说一下下面的参数作用:dev指向device设备指针,上面介绍过,可以通过它获取当前中断设备的一些基本信息

cb里面保存了中断服务的一些属性

pins是当前中断引脚的索引

void iqr_func(const struct device *dev,struct gpio_callback* cb,uint32_t pins){printk("okay\n");
}

4.3 实例化LED0 与 定义存储callback属性的结构体

上面分析过DTC设备树,我们的别名是LED0,这里可以使用DT_ALIAS

static struct gpio_dt_spec gpio_led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios,{0});
static struct gpio_callback gpio_data;

4.4 定义一个逻辑变量来表示灯状态

bool led_is_on = false;

4.5 开启中断

这里的gpios是在dtc文件里定义的指向GPIO属性的结构元素

//设置中断为input模式,接受来自外部数据
gpio_pin_configure_dt(&gpio_led,GPIO_INPUT);
//将GPIO中断配置为在引脚状态更改为逻辑级别1时触发,并启用它
gpio_pin_interrupt_configure_dt(&gpio_led,GPIO_INT_EDGE_TO_ACTIVE);
//将中断函数与pin脚绑定,并将初始化结构存放到gpio_data中
gpio_init_callback(&gpio_data,my_isr,BIT(gpio_led.pin));
//将刚刚绑定的结构添加到向量表中
gpio_add_callback(gpio_led.port,&gpio_data);
//配置pin脚模式
gpio_pin_configure(gpio_led.port, PIN, GPIO_OUTPUT_ACTIVE | 0);

4.6 初始化led与循环控制led

//led
while (1) {//设置循环状态gpio_pin_set(gpio_led.port, PIN, (int)led_is_on);//状态取反led_is_on = !led_is_on;//沉睡一秒k_msleep(1000);
}

4.7 完整代码:

#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <inttypes.h>
#include <sys/util.h>
#include <sys/printk.h>
//pin
#define PIN DT_GPIO_PIN(DT_ALIAS(led0), gpios)//中断函数
void iqr_func(const struct device *dev,struct gpio_callback* cb,uint32_t pins){//向串口打印一行字符printk("okay\n");
}void main(void){//实例化dtc设备树static struct gpio_dt_spec gpio_led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios,{0});//存储初始call数据结构体static struct gpio_callback gpio_data;//led状态bool led_is_on = false;//设置中断为input模式,接受来自外部数据gpio_pin_configure_dt(&gpio_led,GPIO_INPUT);//将GPIO中断配置为在引脚状态更改为逻辑级别1时触发,并启用它gpio_pin_interrupt_configure_dt(&gpio_led,GPIO_INT_EDGE_TO_ACTIVE);//将中断函数与GPIO 引脚脚绑定,并将初始化结构存放到gpio_data中gpio_init_callback(&gpio_data,iqr_func,BIT(gpio_led.pin));//将刚刚绑定的结构添加到向量表中gpio_add_callback(gpio_led.port,&gpio_data);//配置GPIO引脚配置为输出,并将其初始化为逻辑1,使能led灯gpio_pin_configure(gpio_led.port, PIN, GPIO_OUTPUT_ACTIVE | 0);//ledwhile (1) {//设置GPIO功能寄存器值,改变输出电流gpio_pin_set(gpio_led.port, PIN, (int)led_is_on);//状态取反led_is_on = !led_is_on;//沉睡一秒k_msleep(1000);}}

上面代码运行并烧录到板子上,读取串口输出可以发现每过一秒输出一次okay

使用west debug即可开始调试

以下是调试过程

(gdb) b main.c:iqr_func
Breakpoint 1 at 0x80004d4: file /home/test/my_work/zephyr/irq/blinky/src/main.c, line 21.
(gdb) c
Info : halted: PC: 0x080004d6
halted: PC: 0x080004d6
Breakpoint 1, iqr_func (dev=0x80033bc <__device_dts_ord_19>, cb=0x20010148 <gpio_data>, pins=2)at /home/test/my_work/zephyr/irq/blinky/src/main.c:21
21          printk("okay\n");

5. 注意事项

中断服务一定要快,不能慢,在中断上下文中CPU对中断服务有要求,不能在中断里嵌套可能造成死循环的函数以及代码,或者嵌套的函数里还嵌套了一曾类似递归的函数或者比较复杂的函数调用等都会导致CPU RESET,因为中断服务需要暂停其它工作,中断服务目的是为了不用用户监听等待,当来工作时候CPU通知一声然后由中断服务去通知对应的服务去处理然后CPU在正常工作。

Zephry_GPIO的中断使用详解以及中断原理相关推荐

  1. 中断程序_ABB机器人中断程序详解(安川FANUC)

    ABB机器人中断程序详解 1.新建一个中断程序 test001,类型中断 TRAP hanmianshadiaoliao StopMove; SetDO DO04, 0; !Stop; StartMo ...

  2. GD32F4—RTC闹钟及自动唤醒中断配置详解

    GD32F4-RTC闹钟及自动唤醒中断配置详解 一.简介 二.框图 三.RTC 初始化和配置 一.简介 GD32F4x的RTC例程网上资源较少,详细阅读用户手册后做出如下配置.RTC模块提供了一个包含 ...

  3. linux 的中断 命令,linux skill命令参数及用法详解(linux中断进程执行命令)

    linux skill命令参数及用法详解(linux中断进程执行命令) 发布时间:2012-07-21 12:09:37   作者:佚名   我要评论 linux 冻结进程命令 skill 使用详解 ...

  4. 中断系统结构及中断控制详解

    中断系统结构及中断控制详解 MCS-51提供5个中断请求源,2个中断优先级,可实现两级中断服务程序嵌套.当CPU执行关中断指令后(或复位),将屏蔽所有中断请求,只有CPU执行开中断指令后才有可能接受中 ...

  5. 【转详解步进电机工作原理】

    详解步进电机工作原理[转自知乎gk-auto] 步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件.在非超载的情况下,电机的转速.停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响, ...

  6. FFmpeg入门详解--音视频原理及应用:梅会东:清华大学出版社

    大家好,我的第一本书正式出版了,可以在京东各大店铺抢购哦. <FFmpeg入门详解--音视频原理及应用:梅会东:清华大学出版社> 京东自营链接:https://item.jd.com/13 ...

  7. 初级游戏外挂编程详解 windows运行原理+游戏辅助编程 游戏外挂编程

    @TOC初级游戏外挂编程详解 windows运行原理+游戏辅助编程 游戏外挂编程 [1]什么是windows API Windows API 中文翻译过来就是windows应用程序接口(Applica ...

  8. 多维度详解redis以及原理实现,结构与应用分析

    6个方面了解redis应用及其实现原理 1.redis数据存储概述 2.string结构以及应用 3.list结构以及应用 4.hash结构以及应用 5.set结构以及应用 6.zset结构以及应用 ...

  9. 详解帧中继工作原理及作用

    详解帧中继工作原理及作用 帧中继特点 帧中继工作原理 帧中继的作用 帧中继习题 帧中继(FrameRelay)是一种用于连接计算机系统的面向分组的通信方法.它主要用在公共或专用网上的局域网互联以及广域 ...

最新文章

  1. 干货|全面理解无监督学习基础知识
  2. Qt中的QWidget
  3. 数理统计-5.2 样本数据的整理和显示
  4. 在运行SSIS包时,如何动态更新变量值
  5. Event事件-基础
  6. 编程大讲坛 坛坛是佳酿--编程大讲坛:C语言核心开发技术从入门到精通
  7. mysql 数据备份 crontab
  8. 《水经注全国POI兴趣点1.0》发布
  9. 棕榈油跌停见顶,铁矿石认沽上涨,YP05惊天大反弹2022.3.14
  10. Excel中IFs函数如何输出不满足条件下的内容
  11. 通达信 c java,通达信的c
  12. 几种负荷预测方法及其应用
  13. matlab barrier,使用fmincon函数出现barrier问题
  14. 傅里叶------傅里叶变换
  15. c语言 原子操作,原子操作
  16. Android应用开发之FrameLayout(帧布局)
  17. 通信模组电源设计问题总结
  18. win7 64位系统与32系统的区别
  19. java基于Ssm汽车零配件维修管理系统vue+elementui项目介绍
  20. 生动解析何为ERP以及与SAP的关系

热门文章

  1. vue 3.0记录Element UI 表单使用(看了隔壁小孩儿都会用的Element UI 表单组件使用)
  2. 查看服务器的性能和使用状态(top,free,df)
  3. 三菱melsec-a系列plc的指令与编程_三菱Q系列PLC定时器、计数器结构化编程基础
  4. 对超级计算机的认识有关论文,计算机科与技术专业的认识与思考.docx
  5. 笨办法学python在线阅读_『笨办法』学Python 3
  6. php中unset函数是在哪一章_PHP引用(amp;)使用详解
  7. python课程设计的主要任务是什么_Python网络编程课程设计 任务1.docx
  8. java servlet init方法_Servlet详解之两个init方法的作用
  9. ge linux安装apt_教你如何在 Linux 中使用 apt 命令
  10. pycharm缩进对齐线_代码中的缩进线