linuxARM裸机学习笔记(4)----GPIO中断以及定时器中断实验

1.中断向量表

这个表里面存放的都是中断向量,中断服务程序的入口地址或存放中断服务程序的首地址成为中断向量。中断向量表是一系列中断服务程序入口地址组成的表,当某个中断触发的时候会自动跳转到中断向量表对应的中断服务程序的入口。

2.NVIC(内嵌向量中断控制器)

在IMU6U的中断管理机构叫做GIC。GIC接受到外部中断汇报给ARM内核,ARM内核提供了四个信号给GIC来回报中断情况。

中断源分为三个部分:

SPI(Shared Peripheral Interrupt), 共享中断,顾名思义,所有 Core 共享的中断,这个是最
常见的,那些外部中断都属于 SPI 中断 ( 注意!不是 SPI 总线那个中断 ) 。比如按键中断、串口
中断等等,这些中断所有的 Core 都可以处理,不限定特定 Core
PPI(Private Peripheral Interrupt) ,私有中断,我们说了 GIC 是支持多核的,每个核肯定
有自己独有的中断。这些独有的中断肯定是要指定的核心处理,因此这些中断就叫做私有中断。
SGI(Software-generated Interrupt) ,软件中断,由软件触发引起的中断,通过向寄存器
GICD_SGIR 写入数据来触发,系统会使用 SGI 中断来完成多核之间的通信。
ID0~ID15 :这 16 ID 分配给 SGI
ID16~ID31 :这 16 ID 分配给 PPI
ID32~ID1019 :这 988 ID 分配给 SPI。

GIC逻辑模块:

Distributor【分发器端】 和 CPU Interface【CPU接口端】

 中断使能

IRQ和FIQ分别是外部中断和快速中断的总开关

中断使能

GIC 寄存器 GICD_ISENABLERn 和 GICD_ ICENABLERn 用来完成外部中断的使能和禁
止,对于 Cortex-A7 内核来说中断 ID 只使用了 512 个。一个 bit 控制一个中断 ID 的使能,那么
就需要 512/32=16 个 GICD_ISENABLER 寄存器来完成中断的使能。同理,也需要 16 个
GICD_ICENABLER 寄存器来完成中断的禁止。其中 GICD_ISENABLER0 的 bit[15:0]对应
ID15~0 的 SGI 中断,GICD_ISENABLER0 的 bit[31:16]对应 ID31~16 的 PPI 中断。剩下的
GICD_ISENABLER1~GICD_ISENABLER15 就是控制 SPI 中断的

中断优先级设置

中断优先级也可以分为抢占优先级和子优先级,根据GICC_PMR的低八位来控制优先级级数的范围, GIC 控制器最多可以支持 256 个优先级,数字越小,优先级越高

 I.MX6U Cortex-A7 内核,所以支持 32 个优先级,因此 GICC_PMR 要设置为 0b11111000

抢占优先级和子优先级位数设置

I.MX6U 的优先级
位数为 5(32 个优先级 ) ,所以可以设置 Binary point 2 ,表示 5 个优先级位全部为抢占优先级。

这里解释一下:优先级位数如果是5,则代表的是2的5次方即32个不同的优先级级别,,所以才选择了Binary Point为2。全部为抢占优先级。

 优先级设置

1.设置寄存器 GICC_PMR ,配置优先级个数,比如 I.MX6U 支持 32 级优先级。
2.设置抢占优先级和子优先级位数,一般为了简单起见,会将所有的位数都设置为抢占
优先级。
3.设置指定中断 ID 的优先级,也就是设置外设优先级。

代码段

/***************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名	: 	 bsp_exit.c
作者	   : 左忠凯
版本	   : V1.0
描述	   : 外部中断驱动。
其他	   : 配置按键对应的GPIP为中断模式
论坛 	   : www.wtmembed.com
日志	   : 初版V1.0 2019/1/4 左忠凯创建
***************************************************************/
#include "bsp_exit.h"
#include "bsp_gpio.h"
#include "bsp_int.h"
#include "bsp_delay.h"
#include "bsp_beep.h"/** @description			: 初始化外部中断* @param				: 无* @return 				: 无*/
void exit_init(void)
{gpio_pin_config_t key_config;/* 1、设置IO复用 */IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18,0);			/* 复用为GPIO1_IO18 */IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18,0xF080);/* 2、初始化GPIO为中断模式 */key_config.direction = kGPIO_DigitalInput;key_config.interruptMode = kGPIO_IntFallingEdge;key_config.outputLogic = 1;gpio_init(GPIO1, 18, &key_config);GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);				/* 使能GIC中对应的中断 */system_register_irqhandler(GPIO1_Combined_16_31_IRQn, (system_irq_handler_t)gpio1_io18_irqhandler, NULL);	/* 注册中断服务函数 */gpio_enableint(GPIO1, 18);								/* 使能GPIO1_IO18的中断功能 */
}/** @description			: GPIO1_IO18最终的中断处理函数* @param				: 无* @return 				: 无*/
void gpio1_io18_irqhandler(void)
{ static unsigned char state = 0;/**采用延时消抖,中断服务函数中禁止使用延时函数!因为中断服务需要*快进快出!!这里为了演示所以采用了延时函数进行消抖,后面我们会讲解*定时器中断消抖法!!!*/delay(10);if(gpio_pinread(GPIO1, 18) == 0)	/* 按键按下了  */{state = !state;beep_switch(state);}gpio_clearintflags(GPIO1, 18); /* 清除中断标志位 */
}

复用IO口,设置中断触发方式。使能GIC以及GPIO中断

EPIT 定时器实验
EPIT定时器:完成 周期性的中断定时方式【仅此一个功能!!!】,32位寄存器, EPIT 是一个 向下计数器

EPIT 定时器有两种工作模式:set-and-forget free-running 

set-and-forget 模式 :EPITx_CR(x=1, 2) 寄存器的 RLD 位置 1 的时候 EPIT 工作在此模式
下,在此模式下 EPIT 的计数器从加载寄存器 EPITx_LR 中获取初始值,不能直接向计数器寄存
器写入数据。不管什么时候,只要计数器计数到 0 ,那么就会从加载寄存器 EPITx_LR 中重新
加载数据到计数器中,周而复始。
free-running 模式 EPITx_CR 寄存器的 RLD 位清零的时候 EPIT 工作在此模式下,当计数
器计数到 0 以后会重新从 0XFFFFFFFF 开始计数,并不是从加载寄存器 EPITx_LR 中获取数据。

/***************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名	: 	 bsp_epittimer.c
作者	   : 左忠凯
版本	   : V1.0
描述	   : EPIT定时器驱动文件。
其他	   : 配置EPIT定时器,实现EPIT定时器中断处理函数
论坛 	   : www.wtmembed.com
日志	   : 初版V1.0 2019/1/5 左忠凯创建
***************************************************************/
#include "bsp_epittimer.h"
#include "bsp_int.h"
#include "bsp_led.h"/** @description		: 初始化EPIT定时器.*					  EPIT定时器是32位向下计数器,时钟源使用ipg=66Mhz		 * @param - frac	: 分频值,范围为0~4095,分别对应1~4096分频。* @param - value	: 倒计数值。* @return 			: 无*/
void epit1_init(unsigned int frac, unsigned int value)
{if(frac > 0XFFF)frac = 0XFFF;EPIT1->CR = 0;	/* 先清零CR寄存器 *//** CR寄存器:* bit25:24 01 时钟源选择Peripheral clock=66MHz* bit15:4  frac 分频值* bit3:	1  当计数器到0的话从LR重新加载数值* bit2:	1  比较中断使能* bit1:    1  初始计数值来源于LR寄存器值* bit0:    0  先关闭EPIT1*/EPIT1->CR = (1<<24 | frac << 4 | 1<<3 | 1<<2 | 1<<1);EPIT1->LR = value;	/* 倒计数值 */EPIT1->CMPR	= 0;	/* 比较寄存器,当计数器值和此寄存器值相等的话就会产生中断 *//* 使能GIC中对应的中断 			*/GIC_EnableIRQ(EPIT1_IRQn);/* 注册中断服务函数 			*/system_register_irqhandler(EPIT1_IRQn, (system_irq_handler_t)epit1_irqhandler, NULL);	EPIT1->CR |= 1<<0;	/* 使能EPIT1 */ 
}/** @description			: EPIT中断处理函数* @param				: 无* @return 				: 无*/
void epit1_irqhandler(void)
{ static unsigned char state = 0;state = !state;if(EPIT1->SR & (1<<0)) 			/* 判断比较事件发生 */{led_switch(LED0, state); 	/* 定时器周期到,反转LED */}EPIT1->SR |= 1<<0; 				/* 清除中断标志位 */
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/54828.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记一次 .NET某医疗器械清洗系统 卡死分析

一&#xff1a;背景 1. 讲故事 前段时间协助训练营里的一位朋友分析了一个程序卡死的问题&#xff0c;回过头来看这个案例比较经典&#xff0c;这篇稍微整理一下供后来者少踩坑吧。 二&#xff1a;WinDbg 分析 1. 为什么会卡死 因为是窗体程序&#xff0c;理所当然就是看主…

【elementui】解决el-select组件失去焦点blur事件每次获取的是上一次选中值的问题

目录 【问题描述】 【问题摘要】 【分析问题】 【完整Test代码】 【封装自定义指令】 ↑↑↑↑↑↑↑↑↑↑↑↑ 不想看解决问题过程的可点击上方【封装自定义指令】目录直接跳转获取结果即可~~~ 【问题描述】 一位朋友遇到这么一个开发场景&#xff1a;在表格里面嵌入el-…

Redis内网主从节点搭建

Redis内网主从节点搭建 1、文件上传2、服务安装3、服务启动4、配置主从复制 1、文件上传 内网环境手动上传gcc-c、redis.tar文件 2、服务安装 # 解压 unzip gcc-c.zip unzip gcc_rpm.zip tar -zxvf redis-6.2.13.tar.gz# 安装 cd gcc_rpm/ rpm -ivh *.rpm --nodeps --force…

以太网ICMP协议(九)

目录 一、概述 二、ICMP消息类型 2.1 ICMP类型0和类型8&#xff1a;Ping功能 2.2 ICMP类型3&#xff1a;目标不可达 2.3 ICMP类型5&#xff1a;重定向 2.4 ICMP类型11&#xff1a;超时 三、报文格式 一、概述 由于IP协议是不可靠的通信协议&#xff0c;需要有其他协议的…

JMeter 4.x 简单使用

文章目录 前言JMeter 4.x 简单使用1. 启动2. 设置成中文3. 接口测试3.1. 设置线程组3.2. HTTP信息请求头管理器3.3. 添加HTTP请求默认值3.4. 添加HTTP cookie 管理3.5. 添加http请求3.5.1. 添加断言 3.6. 添加监听器-查看结果树3.7. 添加监听器-聚合报告 4. 测试 前言 如果您觉…

gcc编译过程

源文件需要经过编译才能生成可执行文件。在 Windows 下进行开发时&#xff0c;只 需要点几个按钮即可编译&#xff0c;集成开发环境 ( 比如 Visual studio) 已经将各种编 译工具的使用封装好了。 Linux 下也有很优秀的集成开发工具&#xff0c;但是更多的时 候是直接使用…

C++ 指针函数和函数指针

除了void类型的函数之外&#xff0c;函数在调用结束之后都要有返回值&#xff0c;指针也可以是函数的返回值。当一个函数的返回值是指针类型时&#xff0c;这个函数就是指针型函数。 使用指针型函数的最主要目的就是要在函数结束时把大量的数据从被调函数返回到主调函数中。而通…

【MySQL】当前读和快照读

文章目录 当前读快照读 在学习 MVCC 多版本并发控制之前&#xff0c;必须先了解一下&#xff0c;什么是 MySQL InnoDB 下的 当前读和 快照读? 当前读 读取的是记录的最新版本&#xff0c;读取时还要保证其他并发事务不能修改当前记录&#xff0c;会对读取的记录进行加锁。对…

【动态网页抓取】 :用Python抓取所有内容的指南

一、说明 您在抓取动态网页内容时是否得到了糟糕的结果&#xff1f;不仅仅是你。对于标准抓取工具来说&#xff0c;爬网动态数据是一项具有挑战性的任务&#xff08;至少可以说&#xff09;。这是因为当发出HTTP请求时&#xff0c;响应程序的某些部分JavaScript在后台运行&…

Java转换流

文章目录 转换流的理解**InputStreamReader****OutputStreamWriter**练习 引入情况1&#xff1a; 使用FileReader 读取项目中的文本文件。由于IDEA设置中针对项目设置了UTF-8编码&#xff0c;当读取Windows系统中创建的文本文件时&#xff0c;如果Windows系统默认的是GBK编码&a…

437. 路径总和 III

题目描述&#xff1a; 主要思路&#xff1a; 方法一&#xff1a;递归 从每个节点开始一次递归 class Solution { public:int ans0;void dfs(TreeNode* now,int targetSum, long sum){if(!now)return;sumnow->val;if(sumtargetSum)ans1;dfs(now->left,targetSum,sum);df…

Mysql主从搭建 基于DOCKER

创建目录 #主节点目录 mkdir -p /home/data/master/mysql/#从节点目录 mkdir -p /home/data/slave/mysql/创建配置文件 # 主节点配置 touch /home/data/master/mysql/my.cnf# 从节点配置 touch /home/data/slave/mysql/my.cnf编辑配置文件 主节点配置文件 vim /home/data/m…