C语言 cortex-A7核 按键中断 实验【重点】
一、KEY1
include/key.h
#ifndef __KEY_H__
#define __KEY_H__#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"//RCC/GPIO章节初始化
void hal_rcc_gpio_init();//EXTI章节初始化 ---> KEY1
void hal_exti_key1_init();//GIC章节初始化 ---> KEY1
void hal_gic_key1_init();#endif
src/key.c
#include "key.h"//KEY1 ---> PF9
//KEY2 ---> PF7
//KEY3 ---> PF8//RCC/GPIO章节初始化
void hal_rcc_gpio_init()
{//RCC章节初始化 //1.使能GPIOF组控制器 MP_AHB4ENSETR[5] = 1RCC->MP_AHB4ENSETR |= (0X1 << 5);//GPIO章节初始化//1.使能PF9引脚为输入模式 MODER[19:18] = 00GPIOF->MODER &= (~(0X3 << 18));//2.使能PF7引脚为输入模式 MODER[15:14] = 00GPIOF->MODER &= (~(0x3 << 14)); //3.使能PF8引脚为输入模式 MODER[17:16] = 00GPIOF->MODER &= (~(0x3 << 16));
}//EXTI章节初始化 ---> KEY1
void hal_exti_key1_init()
{//1.设置EXTI中断选择寄存器 PF9 ---> EXTI9 EXTICR3[15:8]=0x05EXTI->EXTICR3 &= (0xff << 8);EXTI->EXTICR3 |= (0x05 << 8);//2.设置PF9引脚,中断触发方式为下降沿触发 FTSR1[9]=1EXTI->FTSR1 |= (0x1 << 9);//3.设置EXTI层中断不屏蔽 IMR1[9]=1EXTI->C1IMR1 |= (0x1 << 9);
}//GIC章节初始化 ---> KEY1
void hal_gic_key1_init()
{//GICD章节初始化//1.设置GICD层使能组0 CTRL[0] = 1GICD->CTRL |= (0x1 << 0); //2.设置GICD层中断层使能 ISENABLER[3] 第3位写1GICD->ISENABLER[3] |= (0x1 << 3);//3.设置GICD层中断优先级寄存器 IPRIORITYR[24] 第[31:27] = 00000GICD->IPRIORITYR[24] &= (~(0x1f << 27));//4.设置GICD层中断目标分配寄存器 给CPU0 ITARGETSR[24] 第[25:24] = 01GICD->ITARGETSR[24] &= (~(0x1 << 25));GICD->ITARGETSR[24] |= (0x1 << 24);//GICC章节初始化//1.使能GICC组0 CTLR[0] = 1GICC->CTRL |= (0x1 << 0);//2.设置KEY1 GICC层优先级 PMR[7:3] = 11111GICC->PMR |= (0x1f << 3);
}
src/do_irq.c
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"extern void printf(const char *fmt, ...);void do_irq(void)
{unsigned int interrupt_id;//获取中断号interrupt_id = GICC->IAR & (0x3ff);switch(interrupt_id){case 97:break;case 98:break;case 99:printf("key1 down!!!");printf("key1 ID = %d\n",interrupt_id);//清除EXTI层中断挂起标志位EXTI->FPR1 |= (0x1 << 9);//清除GICD层中断挂起标志位 ICPENDR[3] 第3位 = 1GICD->ICPENDR[3] |= (0x1 << 3);break;}//清除GICC中对应断号GICC->EOIR = interrupt_id; //将IAR寄存器中的中断号获取值,赋值给EOIR
}
main.c
#include "key.h"extern void printf(const char *fmt, ...);void delay_ms(int ms)
{int i,j;for(i = 0; i < ms;i++)for (j = 0; j < 1800; j++);}int main(){hal_rcc_gpio_init(); //RCC/GPIO章节初始化hal_exti_key1_init(); //EXTI章节初始化hal_gic_key1_init(); //GIC章节初始化while(1){}return 0;
}
二、封装函数
include/key.h
#ifndef __KEY_H__
#define __KEY_H__#include "stm32mp1xx_rcc.h"
#include "led.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"typedef enum{Falling, //下降沿Rising, //上升沿
}trigger_t;//RCC/GPIO章节初始化
void hal_rcc_gpio_init();//void hal_exti_init(EXTI编号,GPIOF组号,触发方式);
void hal_exti_init(unsigned int EXTI_INPUT,unsigned int GPIOxGroup,trigger_t event_trigger);//void hal_gic_init(中断号,中断优先级);
void hal_gic_init(unsigned int interrupt_id,unsigned int priority);
#endif
src/key.c
#include "key.h"//KEY1 ---> PF9
//KEY2 ---> PF7
//KEY3 ---> PF8//RCC/GPIO章节初始化
void hal_rcc_gpio_init()
{//RCC章节初始化 //1.使能GPIOF组控制器 MP_AHB4ENSETR[5] = 1RCC->MP_AHB4ENSETR |= (0x1 << 5);//GPIO章节初始化//1.设置KEY1-->PF9引脚为输入模式 MODER[19:18] = 00GPIOF->MODER &= (~(0x3 << 18));//2.设置KEY2-->PF7引脚为输入模式 MODER[15:14] = 00GPIOF->MODER &= (~(0x3 << 14));//1.设置KEY3-->PF8引脚为输入模式 MODER[17:16] = 00GPIOF->MODER &= (~(0x3 << 16));
}//void hal_exti_init(EXTI编号,GPIOF组号,触发方式);
void hal_exti_init(unsigned int EXTI_INPUT,unsigned int GPIOxGroup,trigger_t event_trigger)
{//1.设置EXTI中断选择寄存器 PF9--->EXTI9 EXTICR3[15:8] = 0x05switch(EXTI_INPUT / 4){case 0:break;case 1:EXTI->EXTICR2 &= (~(0xff << (EXTI_INPUT % 4 * 8)));EXTI->EXTICR2 |= (GPIOxGroup << (EXTI_INPUT % 4 * 8));break;case 2:EXTI->EXTICR3 &= (~(0xff << (EXTI_INPUT % 4 * 8)));EXTI->EXTICR3 |= (GPIOxGroup << (EXTI_INPUT % 4 * 8));break;case 3:break;}//2.设置中断触发方式if(event_trigger == Falling){EXTI->FTSR1 |= (0x1 << EXTI_INPUT);}else{EXTI->RTSR1 |= (0x1 << EXTI_INPUT);}//3.设置EXTI层中断不屏蔽EXTI->C1IMR1 |= (0x1 << EXTI_INPUT);
}//void hal_gic_init(中断号,中断优先级);
void hal_gic_init(unsigned int interrupt_id,unsigned int priority)
{//GICD章节初始化 //1.设置GICD层使能组0 CTRL[0] = 1GICD->CTRL |= (0x1 << 0);//2.设置GICD层中断设置使能寄存器 GICD->ISENABLER[interrupt_id/32] |= (0x1 << (interrupt_id % 32));//3.设置GICD层中断优先级寄存器 GICD->IPRIORITYR[interrupt_id/4] &= (~(0x1f << (interrupt_id % 4 * 8 + 3)));GICD->IPRIORITYR[interrupt_id/4] |= (priority << (interrupt_id % 4 * 8 + 3));//4.设置GICD层中断目标分配寄存器 ITARGETSR[24] 第[25:24] = 01GICD->ITARGETSR[interrupt_id/4] &= (~(0x3 << (interrupt_id % 4 * 8)));GICD->ITARGETSR[interrupt_id/4] |= (0x1 << (interrupt_id % 4 * 8));//GICC章节初始化//1.设置GICC层使能组0 CTRL[0] = 1GICC->CTRL |= (0x1 << 0);//2.设置GICC层中断优先级寄存器 PMR[7:3] = 11111GICC->PMR &= (~(0x1f << 3));GICC->PMR |= (0x1f << 3);
}
src/do_irq.c
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"
#include "led.h"extern void printf(const char *fmt, ...);void do_irq(void)
{unsigned int interrupt_id;//获取中断号 IDinterrupt_id = GICC->IAR & (0x3ff);switch(interrupt_id){case 97: //KEY2 ---> LED2 ---->PF10printf("key2 down!!!");printf("key2 ID = %d\n",interrupt_id);GPIOF->ODR ^= (0x1 << 10);//清除EXTI层中断挂起标志位 FPR1[7] = 1EXTI->FPR1 |= (0x1 << 7);//清除GICD层中断挂起标志位 ICPENDR[3]第一位写1GICD->ICPENDR[3] |= (0x1 << 1);break;case 98: //KEY3 ---> LED1 ---->PE10printf("key3 down!!!");printf("key3 ID = %d\n",interrupt_id);GPIOE->ODR ^= (0x1 << 10);//清除EXTI层中断挂起标志位 FPR1[8] = 1EXTI->FPR1 |= (0x1 << 8);//清除GICD层中断挂起标志位 ICPENDR[3]第2位写1GICD->ICPENDR[3] |= (0x1 << 2);break;case 99: //KEY1 ---> LED3 ----> PE8printf("key1 down!!!");printf("key1 ID = %d\n",interrupt_id);GPIOE->ODR ^= (0x1 << 8);//清除EXTI层中断挂起标志位 FPR1[9] = 1EXTI->FPR1 |= (0x1 << 9);//清除GICD层中断挂起标志位 ICPENDR[3]第三位写1GICD->ICPENDR[3] |= (0x1 << 3);break;}//清除GICC层中断号 EOIRGICC->EOIR = interrupt_id;
}
main.c
#include "led.h"#include "key.h"extern void printf(const char *fmt, ...);void delay_ms(int ms){int i,j;for(i = 0; i < ms;i++)for (j = 0; j < 1800; j++);}void led_init(){//GPIOE组/GPIOF组使能RCC_MP_AHB4ENSETR |= (0x3 << 4);//结构体初始化gpio_init_t init = {OUTPUT,PP,LOW,NO_PU_PD};hal_gpio_init(GPIOE,GPIO_PIN_10,&init);hal_gpio_init(GPIOF,GPIO_PIN_10,&init);hal_gpio_init(GPIOE,GPIO_PIN_8,&init);}int main(){led_init();// LED1灯初始化//key1 ----> PF9 hal_rcc_gpio_init();hal_exti_init(9,0x05,Falling);hal_gic_init(99,9);//key2 ----> PF7 hal_exti_init(7,0x05,Falling);hal_gic_init(97,7);//key3 ----> PF8hal_exti_init(8,0x05,Falling);hal_gic_init(98,8);while(1){}return 0;}
调用:include/led.h
#ifndef __LED_H__
#define __LED_H__//LED1 ---> PE10
//LED2 ---> PF10
//LED3 ---> PE8//结构体封装
typedef struct{volatile unsigned int MODER; // 0x00volatile unsigned int OTYPER; // 0x04volatile unsigned int OSPEEDR; //0x08volatile unsigned int PUPDR; //0x0cvolatile unsigned int IDR; //0x10volatile unsigned int ODR; //0x14
}gpio_t;//GPIOE组基地址 0x50006000
#define GPIOE ((gpio_t*)0x50006000)//GPIOF组基地址 0x50007000
#define GPIOF ((gpio_t*)0x50007000)#define RCC_MP_AHB4ENSETR (*(volatile unsigned int*)0x50000A28)//引脚编号封装
#define GPIO_PIN_0 0
#define GPIO_PIN_1 1
#define GPIO_PIN_2 2
#define GPIO_PIN_3 3
#define GPIO_PIN_4 4
#define GPIO_PIN_5 5
#define GPIO_PIN_6 6
#define GPIO_PIN_7 7
#define GPIO_PIN_8 8
#define GPIO_PIN_9 9
#define GPIO_PIN_10 10
#define GPIO_PIN_11 11
#define GPIO_PIN_12 12
#define GPIO_PIN_13 13
#define GPIO_PIN_14 14
#define GPIO_PIN_15 15//模式寄存器封装
typedef enum{INPUT, //输入模式OUTPUT, //输出模式ALT, //复用功能模式ANALOG, //模拟模式
}gpio_moder_t;//输出类型寄存器封装
typedef enum{PP,//推挽OD,//开漏
}gpio_otyper_t;//输出速率寄存器封装
typedef enum{LOW,//低速MED,//中速HIGH,//高速VERY_HIGH,//快速
}gpio_ospeedr_t;//是否需要上下拉电阻进行封装
typedef enum{NO_PU_PD,//禁止上下拉电阻PU,//上拉PD,//下拉
}gpio_pupdr_t;//封装初始化结构体
typedef struct{gpio_moder_t moder; //模式相关寄存器gpio_otyper_t otyper; //输出类型寄存器 gpio_ospeedr_t ospeedr; //输出速率寄存器 gpio_pupdr_t pupdr; //是否需要上下拉电阻寄存器
}gpio_init_t;//输出高低电平
typedef enum{GPIO_RESET_T,//低电平GPIO_SET_T,//高电平
}gpio_status_t;//函数功能:gpio相关初始化操作
//参数1:GPIO组编号
//参数2:GPIO引脚编号
//参数3:初始化相关内容
//返回值:无
void hal_gpio_init(gpio_t* gpiox,unsigned int pin,gpio_init_t* init);//函数功能:gpio写相关操作
//参数1:GPIO组编号
//参数2:GPIO引脚编号
//参数3:写值 写1高电平 写0低电平
//返回值:无
void hal_gpio_write(gpio_t* gpiox,unsigned int pin,gpio_status_t status);#endif
相关文章:
C语言 cortex-A7核 按键中断 实验【重点】
一、KEY1 include/key.h #ifndef __KEY_H__ #define __KEY_H__#include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_exti.h" #include "stm32mp1xx_gic.h"//RCC/GPIO章节初始化 void hal_rcc_gpio_init…...

freertos中函数调用和启动第一个任务(栈相关!!!!!!)
本内容仅就一些较难理解的点讲解,请结合其它文章实用 在函数调用时,m3的处理器使用r0-r3共四个寄存器传参,其余的使用栈传参。 但是,如果传入的参数是全局变量,则不需传参,因为全局变量在函数内部是可见的…...

【PHP】如何关闭buffer实时输出内容到前端
前言 默认情况下,我们在PHP里使用echo等函数输出的内容,是不会马上发送给前端的,原因是有 buffer 的存在,buffer又分两处,一处是PHP本身的buffer,另一处是Nginx的buffer。只有当buffer满了之后,…...

Scala第二章节
Scala第二章节 scala总目录 章节目标 掌握变量, 字符串的定义和使用掌握数据类型的划分和数据类型转换的内容掌握键盘录入功能理解Scala中的常量, 标识符相关内容 1. 输出语句和分号 1.1 输出语句 方式一: 换行输出 格式: println(里边写你要打印到控制台的数据);方式二…...

Spring修炼之路(2)依赖注入(DI)
一、概念 依赖注入(Dependency Injection,DI)。 测试pojo类 : Address.java 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 . 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 . 二、 注入方式 2.1构造器注入 我们在之前的案例已经…...

编写Android.mk / Android.bp 引用三方 jar 包,aar包,so 库
一.前言 在Android10之后,所有项目工程中,官方推荐使用Android.bp去编译构建,以前使用Android.mk构建的项目随着版本迭代升级,慢慢需要变更为Android.bp, 两者的语法都需要去了解并熟练使用。 笔者之前写过Android.mk的…...

【kylin】【ubuntu】搭建本地源
文章目录 一、制作一个本地源仓库制作ubuntu本地仓库制作kylin本地源 二、制作内网源服务器ubuntu系统kylin系统 三、使用内网源ubuntukylin 一、制作一个本地源仓库 制作ubuntu本地仓库 首先需要构建一个本地仓库,用来存放软件包 mkdir -p /path/to/localname/pac…...

为什么 Go 语言 struct 要使用 tags
在 Go 语言中,struct 是一种常见的数据类型,它可以用来表示复杂的数据结构。在 struct 中,我们可以定义多个字段,每个字段可以有不同的类型和名称。 除了这些基本信息之外,Go 还提供了 struct tags,它可以用…...
WebGL笔记:WebGL中JS与GLSL ES 语言通信,着色器间的数据传输示例:用鼠标控制点位
用鼠标控制点位 <canvas id"canvas"></canvas><!-- 顶点着色器 --> <script id"vertexShader" type"x-shader/x-vertex">attribute vec4 a_Position;void main() {// 点位gl_Position a_Position;// 尺寸gl_PointSize…...
算法 主持人调度-(双指针+贪心)
牛客网: BM96 题目: 一个主持人只能参加一个活动,至少需要多少主持人 思路: 对start, end排序从小到大;初始化指针l, r 0, 0;start[r]< end[l]时需要累加人数同时r,否则l,r同时移动;直至不再满中l<n &&am…...

Elasticsearch 集群时的内部结构是怎样的?
Apache Lucene : Flush, Commit Elasticsearch 是一个基于 Apache Lucene 构建的搜索引擎。 它利用 Lucene 的倒排索引、查询处理和返回搜索结果等功能来执行搜索。 它还扩展了 Lucene 的功能,添加分布式处理功能以支持大型数据集的搜索。 让我们看一下 Apache Luc…...

IoTDB 在国际数据库性能测试排行榜中位居第一?测试环境复现与流程详解第一弹!...
最近我们得知,Apache IoTDB 多项性能表现位居 benchANT 时序数据库排行榜(Time Series: DevOps)性能排行第一名!(榜单地址:https://benchANT.com/ranking/database-ranking) benchANT 位于德国&…...

react项目优化
随着项目体积增大,打包的文件体积会越来越大,需要优化,原因无非就是引入的第三方插件比较大导致,下面我们先介绍如何分析各个文件占用体积的大小。 1.webpack-bundle-analyzer插件 如果是webpack作为打包工具的项目可以使用&…...

青藏高原1-km分辨率生态环境质量变化数据集(2000-2020)
青藏高原平均海拔4000米以上,人口1300万,是亚洲九大河流的源头,为超过15亿人口提供淡水、食物和其他生态系统服务,被誉为地球第三极和亚洲水塔。然而,在该地区的人与自然的关系的研究是有限的,尤其是在精细…...

Nature Communications | 张阳实验室:端到端深度学习实现高精度RNA结构预测
RNA分子是基因转录的主要执行者,也是细胞运作的隐形功臣。它们在基因表达调控、支架构建以及催化活性等多个生命过程中都扮演着关键角色。虽然RNA如此重要,但由于实验数据的缺乏,准确预测RNA 的三维空间结构仍然是目前计算生物学面临的重大挑…...

提升您的Mac文件拖拽体验——Dropzone 4 for mac
大家都知道,在Mac上进行文件拖拽是一件非常方便的事情。然而,随着我们在工作和生活中越来越多地使用电脑,我们对于这个简单操作的需求也越来越高。为了让您的文件拖拽体验更加高效和便捷,今天我们向大家介绍一款强大的工具——Dro…...

Vue之transition组件
Vue提供了transition组件,使用户可以更便捷地添加过渡动画效果。 transition组件 transition组件也是一个抽象组件,并不会渲染出真实dom。Vue会在其第一个真实子元素上添加过渡效果。 props render 这里将render分为两部分,第一部分界定真…...

lenovo联想笔记本电脑ThinkPad X13 AMD Gen2(20XH,20XJ)原装出厂Windows10系统镜像
联想原厂Win10系统,自带所有驱动、出厂主题壁纸、系统属性联想LOGO专属标志、Office办公软件、联想电脑管家等预装程序 链接:百度网盘 请输入提取码 提取码:dolg 适用于型号:20XL,20XJ,20XG,21A1,20XK,20XH,20XF,21A0 所需要…...

php导出cvs,excel打开数字超过16变科学计数法
今天使用php导出cvs,在excel中打开,某一个字段是数字,长度高于16位结果就显示科学计数法 超过15位的话从第16位开始就用0代替了 查询了半天总算解决了就是在后面加上"\t" $data[$key][1] " ".$value[1]."\t";…...

CSS 模糊效果 CSS 黑白效果 CSS调整亮度 对比度 饱和度 模糊效果 黑白效果反转颜色
CSS 模糊效果 CSS 黑白效果 CSS调整亮度 饱和度 模糊效果 黑白效果 实现 调整亮度 饱和度 模糊效果 黑白效果 使用 filter1、模糊2、亮度3、对比度4、饱和度5、黑白效果6、反转颜色7、组合使用8、 filer 完整参数 实现 调整亮度 饱和度 模糊效果 黑白效果 使用 filter 1、模糊…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...