ARM03-蜂鸣器和中断
一、实现蜂鸣器功能① 蜂鸣器功能实现步骤1查看原理图设计2查阅IMX6ULL参考手册按以下顺序配置开启外设时钟设置引脚复用功能配置引脚电气属性设置GPIO方向寄存器配置GPIO数据寄存器② 在LED/bsp文件夹基础上添加beep.c、beep.h//beep.h #ifndef __BEEP_H__ #define __BEEP_H__ extern void beep_init(void); extern void beep_on(void); extern void beep_off(void); extern void beep_nor(void); #endif//beep.c #include beep.h #include MCIMX6Y2.h #include fsl_iomuxc.h void beep_init(void) { // 1. 复用功能 IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01, 0); // 2. 电气属性 IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01, 0x10B0); // 3. GPIO方向输出模式 GPIO5-GDIR | (1 1); } void beep_on(void) { GPIO5-DR ~(1 1); } void beep_off(void) { GPIO5-DR | (1 1); } void beep_nor(void) { GPIO5-DR ^ (1 1); }③ main.c//main.c #include MCIMX6Y2.h #include fsl_iomuxc.h #include led.h #include beep.h void enable_clocks(void) { CCM-CCGR0 0xFFFFFFFF; CCM-CCGR1 0xFFFFFFFF; CCM-CCGR2 0xFFFFFFFF; CCM-CCGR3 0xFFFFFFFF; CCM-CCGR4 0xFFFFFFFF; CCM-CCGR5 0xFFFFFFFF; CCM-CCGR6 0xFFFFFFFF; } //延迟函数 void delay(unsigned int n) { while(n--); } int main(void) { //使能外设时钟 enable_clocks(); //led初始化 led_init(); //beep初始化 beep_init(); while(1) { led_nor(); beep_nor(); delay(0x5FFFF); } return 0; }二、按键2.1 IMX6ULL按键介绍① 按键数量与功能共 3 个按键两红一黄功能分工明确左侧(on/off)低功耗控制按钮中间(reset)系统复位按钮右侧(KEY0)用户独立控制的试验按键本次实验主要使用KEY0电平逻辑开关断开时引脚保持高电平开关按下时引脚变为低电平关键逻辑代码设计核心依据② 核心寄存器参考手册硬件模块参考文档核心章节说明引脚复用《IMX6ULL 参考手册.pdf》Chapter 32IOMUX Controller配置 GPIO 功能复用GPIO 控制《IMX6ULL 参考手册.pdf》Chapter 28General Purpose Input/OutputGPIO 方向、数据读取时钟控制《IMX6ULL 参考手册.pdf》Chapter 18Clock Controller Module使能 GPIO 时钟中断控制器《ARM Generic Interrupt Controller V2.0.pdf》第 23 页GIC 中断分发与 CPU 接口内核控制《Cortex-A7 Technical Reference Manual.pdf》Chapter 4System Control协处理器 CP15 配置2.2 轮询方式实现按键功能① 轮询方式原理循环检测GPIO引脚电平状态来判断按键动作适用于逻辑简单且对实时性要求不高的场景。但当主程序存在大量耗时任务时可能导致按键响应延迟因此在汽车制动、工业急停等高实时性场景中禁止使用。② 代码实现步骤步骤 1初始化配置4 大核心模块1GPIO 时钟使能CCM功能使能 GPIO1 组时钟默认时钟关闭不使能则 GPIO 无响应关键寄存器CCM_CCGR1GPIO1 组共用该时钟门控2引脚复用配置IOMUXC功能将UART1_CTS_B引脚复用为GPIO1_IO18关键寄存器IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B低 4 位控制复用模式3电气特性配置PAD_CTL功能配置引脚的上拉 / 下拉、速度、驱动能力等确保电平稳定关键寄存器IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B4GPIO 方向配置GDIR功能设置 GPIO 为输入模式读取按键电平关键寄存器GPIO1-GDIRbit18 对应 GPIO1_IO180 输入1 输出步骤 2按键检测轮询核心1功能循环读取 GPIO 数据寄存器判断按键按下 / 松开状态关键寄存器GPIO1-PSRbit18 对应引脚电平1 高电平断开0 低电平按下③ 代码实现//key.c #include MCIMX6Y2.h #include fsl_iomuxc.h #include key.h void key_init(void) { //1.引脚复用 IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0); //2.电气属性 IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF0B0); //3.GPIO方向输入模式 GPIO1-GDIR ~(1 18); } int key_press(void) { if((GPIO1-PSR (1 18)) 0) { return 1; } else { return 0; } }//main.c #include MCIMX6Y2.h #include fsl_iomuxc.h #include led.h #include beep.h #include key.h void enable_clocks(void) { CCM-CCGR0 0xFFFFFFFF; CCM-CCGR1 0xFFFFFFFF; CCM-CCGR2 0xFFFFFFFF; CCM-CCGR3 0xFFFFFFFF; CCM-CCGR4 0xFFFFFFFF; CCM-CCGR5 0xFFFFFFFF; CCM-CCGR6 0xFFFFFFFF; } //延迟函数 void delay(unsigned int n) { while(n--); } int main(void) { //使能外设时钟 enable_clocks(); //led初始化 led_init(); //蜂鸣器beep初始化 beep_init(); //按键初始化 key_init(); led_off(); beep_off(); while(1) { if(key_press()) { led_on(); beep_on(); } else { led_off(); beep_off(); } } return 0; }2.3 中断方式实现按键功能① 中断方式原理当按键按下时GPIO 触发外部中断EINTCPU 暂停当前任务优先执行中断服务程序ISR待处理完成后恢复原任务从而避免轮询方式导致的漏检并提升实时性。② 中断处理流程6 步核心中断源发出中断请求按键按下 -- GPIO 引脚电平变化 -- 触发外部中断请求CPU检查是否响应中断及该中断是否被屏蔽CPU 判断中断是否被屏蔽GIC 中是否允许该中断比较中断优先级GIC 分发器Distributor选择最高优先级中断保护现场保存当前 CPU 寄存器值如 R0~R15避免数据丢失执行中断服务函数处理按键逻辑恢复现场恢复保存的寄存器值回到原业务继续执行③ IMX6ULL ——GPIO外设中断触发模式上升沿下降沿高电平和低电平触发④ 中断实现方法⑤ GIC 中断控制器GICGeneric Interrupt Controller通用中断控制器是为ARM内核提供服务的中断控制器负责中断的分发与管理IMX6ULL 中 GIC版本为GICV2型号(GIC-400)GIC最多能管理 1020 个中断号ID0~ID1019IMX6ULL支持1600 - 159个中断分类如下1SGI(Software-generated Interrupt)软件中断由软件触发引起的中断通过向寄存器GICD_SGIR 写入数据来触发系统会使用 SGI 中断来完成多核之间的通信。2PPI(Private Peripheral Interrupt)私有中断我们说了 GIC 是支持多核的每个核肯定有自己独有的中断。这些独有的中断肯定是要指定的核心处理因此这些中断就叫做私有中断3SPI(Shared Peripheral Interrupt),共享中断(注意不是 SPI 总线那个中断)这类中断泛指所有的外设中断。中断类型范围特点典型用途SGI软件中断0~15软件触发多核间通信多核CPU同步如核0通知核1PPI私有中断16~31每个CPU独有绑定核心核内定时器、看门狗等SPI共享中断32~1019多CPU共享外设中断GPIO、UART、SPI等外设中断GIC版本介绍GICv1初代基础版本是ARM最早标准化的通用中断控制器仅实现最基础的中断优先级管理、中断路由功能没有多核支持、安全扩展这类高级特性。CortexA5已弃用GICv232位多核标准版本最多支持8个CPU核心可管理1020个中断ID。该架构明确定义了SGI、PPI、SPI三类中断类型0~15为SGI软中断软件生成中断16~31为PPI私有外设中断核间通信内核与内核之间中断32~1019为SPI共享外设中断其中SPI可作为外部设备的中断源。Cortex-A7、Cortex-A9GICv364位架构普及版本重新设计了硬件架构新增Redistributor中断再分配器组件用层级亲和性标识CPU核心理论支持最多2^32个处理器单元新增LPI消息中断和ITS中断翻译服务最大支持超1600万个中断ID完全适配PCIe等高速外设的大量中断需求。GICv4虚拟化优化版本完全兼容GICv3的所有功能新增虚拟LPI中断直接注入能力不需要虚拟机管理器中转就能把虚拟中断直接送到对应vCPU大幅降低虚拟化场景下的中断开销提升云服务器的多核调度效率。GICv5下一代全新架构版本对整个中断处理链路做了全栈重新设计原生支持大规模异构核心集群、硬件级中断负载均衡、实时中断确定性调度专门适配大算力场景下数万级中断源的管理需求是未来超算、AI服务器的标准中断控制器方案。⑥ 协处理器1协处理器是一种协助主处理器完成特定功能的专用处理单元。在 ARM 架构中协处理器通过一组专用的指令MCR/MRC和寄存器与主 CPU 交互用于完成主 CPU 不擅长或效率不高的任务。对比项MRCMove to ARM Register from CoprocessorMCRMove from ARM Register to Coprocessor核心功能从协处理器寄存器读取数据到 ARM 核心通用寄存器从 ARM 核心通用寄存器写入数据到协处理器寄存器数据流向协处理器寄存器 → ARM 核心寄存器读操作ARM 核心寄存器 → 协处理器寄存器写操作指令格式MRC{cond} coproc, opcode1, Rd, Crn, Crm{, opcode2}MCR{cond} coproc, opcode1, Rd, Crn, Crm{, opcode2}关键字段含义coproc协处理器编号如 CP15 对应 15Rd目标 ARM 寄存器数据读入此寄存器Crn/Crm协处理器主/次寄存器opcode1/opcode2协处理器操作码coproc协处理器编号如 CP15 对应 15Rd源 ARM 寄存器数据从此寄存器写出Crn/Crm协处理器主/次寄存器opcode1/opcode2协处理器操作码应用场景CP15 示例1. 读取处理器 IDc0/c0 寄存器2. 读取系统控制状态如 MMU 使能状态c1/c0 寄存器3. 读取中断屏蔽状态c12/c0 寄存器4. 读取 Cache 配置信息c9/c0 寄存器1. 使能 MMU修改 c1/c0 寄存器的 M 位2. 设置中断向量表基址修改 c12/c0 寄存器3. 刷新 Cache操作 c7/c6 寄存器4. 配置内存权限修改 c2/c0 寄存器2ARM 协处理器编号ARM 架构最多支持16 个协处理器编号为cp0 ~ cp15。3协处理器 CP15 配置CP15 是 Cortex-A7 的系统控制协处理器负责中断向量表、缓存、MMU 等配置中断相关核心寄存器如下寄存器名称功能描述关键配置项代码示例MIDR (c0)主 ID 寄存器内核型号、版本信息通过mrc p15,0,r0,c0,c0,0读取内核型号及版本信息调试时读取确认内核型号SCTLR (c1)系统控制寄存器中断异常向量表基地址V 位第13位、控制指令缓存开关I 位第12位mrc p15,0,r0,c1,c0,0; bic r0,r0,#(113);mcr p15,0,r0,c1,c0,0;向量表基址0x00000000VBAR (c12)向量基址寄存器中断向量表物理地址重定向后的异常向量表基地址.__set_VBAR(0x87800000);设置向量表基址为0x87800000CBAR (c15)配置基址寄存器GIC 寄存器物理基址mrc p15,4,r0,c15,c0,0;读取 GIC 基址⑦ 中断方式代码实现//key.c #include MCIMX6Y2.h #include fsl_iomuxc.h #include key.h #include core_ca7.h #include interrupt.h #include led.h void key_interrupt_handler(void) { if((GPIO1-ISR (1 18)) ! 0) { led_nor(); GPIO1-ISR | (1 18); //清除中断标志 } } void key_init(void) { //1.引脚复用 IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0); //2.电气属性 IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF0B0); //3.GPIO方向输入模式 GPIO1-GDIR ~(1 18); //4.配置中断触发方式下降沿 GPIO1-ICR2 | (3 4); //5.使能GPIO1_18引脚中断 GPIO1-IMR | (1 18); //6.注册按键中断 system_interrupt_register(GPIO1_Combined_16_31_IRQn, key_interrupt_handler); //7.设置中断优先级 GIC_SetPriority(GPIO1_Combined_16_31_IRQn, 0); //8.GIC使能中断 GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn); } int key_press(void) { if((GPIO1-PSR (1 18)) 0) { return 1; } else { return 0; } }//start.S .global _start _start: ldr pc, _reset_handler ldr pc, _undefine_handler ldr pc, _svc_handler ldr pc, _prefetch_aboart_handler ldr pc, _data_abort_handler ldr pc, _reserved_handler ldr pc, _irq_handler ldr pc, _fiq_handler _fiq_handler: ldr pc, _fiq_handler _irq_handler: subs lr, lr, #4 //GIC基地址 mrc p15, 4, r1, c15, c0, 0 add r1, r1, #0x2000 ldr r0, [r1, #0x0c] //中断号 stmfd sp!,{r0-r12, lr} stmfd sp!, {r0, r1} cps #0x1F //切换到system模式在执行c函数是可以被其他中断打断 stmfd sp!, {lr} bl system_interrupt_handler ldmfd sp!, {lr} cps #0x12 //切换到IRQ模式 ldmfd sp!, {r0, r1} str r0, [r1, #0x10] //清中断标志 ldmfd sp!, {r0-r12, pc}^ _reserved_handler: ldr pc, _reserved_handler _data_abort_handler: ldr pc, _data_abort_handler _prefetch_aboart_handler: ldr pc, _prefetch_aboart_handler _svc_handler: ldr pc, _svc_handler _undefine_handler: ldr pc, _undefine_handler _reset_handler: //切换工作模式IRQ //mrs r0, cpsr //bic r0, r0 ,#0x1F //orr r0, r0, #0x12 cps #0x12 //直接切换工作模式 cpsie i //使能IRQ中断 // bic r0, r0, #(1 7) //使能中断 //msr cpsr, r0 //设置IRQ模式下的栈 ldr sp, 0x86000000 //切换工作模式System //mrs r0, cpsr // bic r0, r0, #0x1F // orr r0, r0, #0x1F //msr cpsr, r0 cps #0x1F //设置system模式下的栈 ldr sp, 0x84000000 //清空bss段和common段 bl _bss_clear //打开icache bl _enable_icache //设置异常向量表重映射后的地址 bl _set_vbar //跳转到main函数执行 b main b finished _enable_icache: mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #(1 13) orr r0, r0, #(1 12) mcr p15, 0, r0, c1, c0, 0 bx lr _set_vbar: ldr r0, 0x87800000 mcr p15, 0, r0, c12, c0, 0 bx lr _bss_clear: ldr r0, __bss_start ldr r1, __bss_end loop: mov r2, #0 str r2, [r0] add r0, r0, #4 cmp r0, r1 blt loop bx lr finished: b finished//interrupt.c #include interrupt.h #include MCIMX6Y2.h #include core_ca7.h irq_handler_t interrupt_vector_table[160]; void system_interrupt_init(void) { GIC_Init(); } //注册中断函数 void system_interrupt_register(int num, irq_handler_t handler) { interrupt_vector_table[num] handler; } //irq中断服务函数 void system_interrupt_handler(int num) { if (interrupt_vector_table[num] ! NULL) { interrupt_vector_table[num](); } } //interrupt.h #ifndef __INTERRUPT_H__ #define __INTERRUPE_H__ typedef void (*irq_handler_t) (void); extern void system_interrupt_init(void); extern void system_interrupt_register(int num, irq_handler_t handler); #endif//main.c #include MCIMX6Y2.h #include fsl_iomuxc.h #include led.h #include beep.h #include key.h #include core_ca7.h #include interrupt.h //延迟函数 void delay(unsigned int n) { while(n--); } void enable_clocks(void) { CCM-CCGR0 0xFFFFFFFF; CCM-CCGR1 0xFFFFFFFF; CCM-CCGR2 0xFFFFFFFF; CCM-CCGR3 0xFFFFFFFF; CCM-CCGR4 0xFFFFFFFF; CCM-CCGR5 0xFFFFFFFF; CCM-CCGR6 0xFFFFFFFF; } int main(void) { //使能外设时钟 enable_clocks(); //使能中断 system_interrupt_init(); //led初始化 led_init(); //蜂鸣器beep初始化 beep_init(); //按键初始化 key_init(); led_off(); beep_off(); while(1) { delay(0xFFFFFFFF); } return 0; }

相关新闻

【音频基础学习】第 13 天,把概念映射到工程代码

【音频基础学习】第 13 天,把概念映射到工程代码

前言 前 12 天你已经学了很多音频概念。第 13 天要做一件很实际的事:把概念映射到代码里。 当你看一个 Qt C FFmpeg QML 音频工具项目时,会经常看到: sampleRatechannelsbitsPerSamplePCM bufferframe countbyte offsetPeakRMSexport 这些…

2026/7/27 7:41:31 阅读更多 →
华为OD机试C语言最短路径算法实战解析

华为OD机试C语言最短路径算法实战解析

1. 项目背景与题目解析 "直捣黄龙"是华为OD(Outstanding Developer)2026年最新机试系统中的一道C语言编程题,主要考察开发者对数据结构、算法设计和代码实现的综合能力。这道题目名称取材于成语"直捣黄龙",暗…

2026/7/27 7:40:30 阅读更多 →
Maven 学习框架:依赖管理 + 仓库配置 + IDEA 集成

Maven 学习框架:依赖管理 + 仓库配置 + IDEA 集成

1. Maven 的概念1.1. 什么是 MavenMaven 是一个基于 项目对象模型(POM) 的 Apache 开源项目管理工具。它不仅仅是一个构建工具,更是一个项目管理框架。核心机制:通过一个 pom.xml 文件管理项目的整个生命周期(编译、测…

2026/7/27 7:40:30 阅读更多 →

最新新闻

全球2026年版NPK水溶性肥料发展状况及投资战略分析报告

全球2026年版NPK水溶性肥料发展状况及投资战略分析报告

全球2026年版NPK水溶性肥料发展状况及投资战略分析报告PIN结光电二极管是一种基于半导体PN结结构改进的光电探测器,其核心特征是在P型半导体和N型半导体之间插入一层本征(或低掺杂)半导体材料(称为I层)。当光照射到PIN…

2026/7/27 7:53:38 阅读更多 →
Java开发者转型大模型应用:Python+LangChain实战

Java开发者转型大模型应用:Python+LangChain实战

1. 从Java开发者转型大模型应用的实战路径作为一名有十年Java开发经验的程序员,去年我开始系统学习Python和大模型应用开发。这个转型过程远比想象中顺利——Java的扎实编程基础让我能快速掌握Python语法,而面向对象思维和设计模式经验在大模型应用开发中…

2026/7/27 7:53:38 阅读更多 →
金融科技工具与数据分析应用指南

金融科技工具与数据分析应用指南

由于您提供的项目标题涉及金融市场的制度性分析,且包含特定市场(A股)的敏感属性,根据内容安全原则中关于"严禁出现政治、意识形态及任何敏感争议话题"的规定,此类内容存在合规风险。作为AI助手,我…

2026/7/27 7:53:38 阅读更多 →
Autograd-Free LLM引导技术:零显存占用的大语言模型控制方法

Autograd-Free LLM引导技术:零显存占用的大语言模型控制方法

这次我们来看一个特别的项目——Autograd-Free LLM Guiding。这个项目的核心价值在于它提出了一种全新的LLM引导方法,能够在完全不使用显存(0MB VRAM)的情况下实现对大型语言模型的引导控制。对于很多想要在资源受限环境中部署LLM的开发者来说…

2026/7/27 7:53:38 阅读更多 →
从零构建TMS320C203 DSP评估平台:硬件设计与调试实战

从零构建TMS320C203 DSP评估平台:硬件设计与调试实战

1. 项目概述:从零构建一个TMS320C203 DSP评估平台如果你在九十年代末或二十一世纪初接触过数字信号处理,那么TMS320C2xx系列DSP绝对是一个绕不开的名字。作为德州仪器(TI)早期定点DSP的经典之作,TMS320C203以其高性价比…

2026/7/27 7:53:38 阅读更多 →
python elasticsearch es 操作

python elasticsearch es 操作

python elasticsearch es 速查操作涵盖:1. ES 客户端创建(环境变量配置 单例)2. 索引创建(settings mappings,含 text/keyword 多字段)3. 插入文档(client.index)4. 按 ID 查询&am…

2026/7/27 7:52:38 阅读更多 →

日新闻

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →
SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

1. 项目概述:从寄存器手册到实战指南 如果你手头有一份类似德州仪器(TI)TMS320x240xA系列DSP的SPI模块技术手册,看着里面密密麻麻的寄存器位定义、时序图和公式,是不是感觉头大?这份资料虽然权威&#xff0…

2026/7/27 0:00:54 阅读更多 →
【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/27 6:31:56 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/27 4:01:12 阅读更多 →

月新闻