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、模糊…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
