嵌入式开发学习日志Day8(ARM体系架构——按键、蜂鸣器及中断)

一、蜂鸣器学习

 

代码实现:

二、BSP工程管理及Makefile

1、BSP工程管理

利用BSP工程管理,使文档显示不杂乱;

        将这些文件分为4类,并保存到4个不同的文件夹里。

        首先在新的工程文件夹里创建一个之后我们编写的类似led驱动,clk驱动等等外设驱动程序都放在这文件夹里面,创建名为bsp

 再创建project文件夹,存放 start.s和 main.c 文件,也就是应用文件;

   一个imx6ull文件夹,用来保存NXP的相关库cc.h、fsl_common.h、fsl_iomuxch和 MCIMX6Y2.h 这四个文件;

最后再创建一个obj文件夹,用来存放编译生成的.o 文件。

2、Makefile 

target = ledcross_compiler = arm-linux-gnueabihf-cc = $(cross_compiler)gcc
ld = $(cross_compiler)ld
objcopy = $(cross_compiler)objcopy
objdump = $(cross_compiler)objdumpincdirs = bsp imx6ull #所有包含头文件的文件夹
srcdirs = bsp project #所有包含源文件的文件夹include = $(patsubst %, -I%, $(incdirs))  #处理了头文件之后生成了$(incdirs),然后在生成的每个文件前面加-I
#I是include,-Idsp意思是使用的头文件去dsp文件夹找cfiles = $(foreach dir, $(srcdirs), $(wildcard $(dir)/*.c))  #将所有源文件中的.c找出来,但是得到的结果带目录。eg:文件名/main.c
sfiles = $(foreach dir, $(srcdirs), $(wildcard $(dir)/*.S))   #将所有源文件中的.s找出来,但是得到的结果带目录。eg:文件名/main.Scfilenodir = $(notdir $(cfiles)) #去掉了目录名,得到的是main.c
sfilenodir = $(notdir $(sfiles))#去掉了目录名,得到的是main.Scobjs = $(patsubst %, obj/%, $(cfilenodir:.c=.o)) #编译之后生成的结果是main.o,(.c)需要放入obj的目录中去,obj/表示放在obj这个目录中去
sobjs = $(patsubst %, obj/%, $(sfilenodir:.S=.o)) #编译之后生成的结果是main.o,(.S)需要放入obj的目录中去,obj/表示放在obj这个目录中去objs = $(cobjs) $(sobjs)  #将.c生成的obj和.S生成的obj放在一起VPATH = $(srcdirs)  #表示如果找源文件找不到的话,就去srcdirs中去查找;$(target).bin : $(objs)$(ld) -Timx6ull.lds -o$(target).elf $^$(objcopy) -O binary -S -g $(target).elf $@$(objdump) -D $(target).elf > $(target).dis$(sobjs) : obj/%.o : %.S    #.S生成sobj@mkdir -p obj   #如果没有obj文件,创建obj目录,@符号表示,创建的过程中没有回显,,-p表示如果这个目录已存在,则不报错$(cc) -Wall -nostdlib -c $(include) -o $@ $<$(cobjs) : obj/%.o : %.c  #.c生成cobj@mkdir -p obj     #如果没有obj文件,创建obj目录,@符号表示,创建的过程中没有回显,,-p表示如果这个目录已存在,则不报错$(cc) -Wall -nostdlib -c $(include) -o $@ $<.PHONY : clean
clean:rm -rf $(objs) $(target).elf $(target).bin $(target).dis

三、 按键练习

代码实现:

#include"key.h"
#include"MCIMX6Y2.h"
#include"fsl_iomuxc.h"
#include "core_ca7.h"
#include "gpio.h"
void init_key(void)
{IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18,0);IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_UART1_CTS_B,0x10F0);GPIO_Pin_Config_t t = {.direction = GPIO_Direction_In};gpio_pin_config(GPIO1,18,&t);GPIO1->ICR2 |= (3 << 18);GPIO1->IMR |= (1 << 18);GIC_SetPriority(GPIO1_Combined_16_31_IRQn,1);GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);}int key_pressed(void)
{return((GPIO1->DR & (1 << 18)) == 0) ? 1 : 0;}

四、中断

4.1 GIC控制器(通用中断控制器)

 VFIQ/VIRQ中V指虚拟化的;

        GIC 接收众多的外部中断,然后对其进行处理,最终就只通过四个信号报给 ARM 内核,这四个信号的含义分别为: VFIQ:虚拟快速 FIQ。 VIRQ:虚拟 IRQ。 FIQ:快速中断 IRQ。 IRQ:中断 IRQ。

作用:

  1. 作用是中断优先级排序;
  2. 中断屏蔽的控制;

    GIC控制器(v2版本)最多处理8个内核;最多有1020个中断源:

    SGI  (软件中断):( 0 - 15 ),,软件中断,由软件触发引起的中断,通过向寄存器GICD_SGIR

    写入数据来触发,系统会使用 SGI 中断来完成多核之间的通信。
    PPIs(私有中断):(16 - 31), GIC 是支持多核的,每个核肯定有自己独有的中断。这些独有的中断肯定是要指定的核心处理,因此这些中断就叫做私有中断;
    SPI(共享中断):(32-1019), (注意!不是 SPI 总线那个中断),这类中断泛指所有的外设中断;如定时器、外部中断、串口中断等。

            实际用到的只有(32-159)128个,这128是imx6ull所支持的

            PS:GIC也可以屏蔽不需要的中断
                    V2版本的GIC不在ARM内部,V3、V4版本的是64位

4.2 异常向量表

        异常向量表重映射是指在处理器发生异常时,通过改变异常向量表的物理地址与逻辑地址之间的映射关系

        目的:确保系统能够正确响应和处理异常。

        各模式下的sp只能在进入对应模式后 才能设置,这是因为每种模式的sp都是分离的。 这里分别设置irq、sys、svc模式下的大小都为2MB。

异常状态返回地址偏移量:当异常状态发生以后,返回地址和lr中保留的地址偏移量

4.3 协处理器

        协处理器:用于减轻系统微处理器特定处理任务的芯片;

        cortex A7 共16个协处理器,CP0~CP15

4.3.1 mcr指令与mrc指令 

用mcr与mrc来访问协处理器;

mcr写入协处理器;

mrc读取协处理器;


协处理器编号p0-p15;

读取出来的寄存器内容:

SCTLR寄存器:


eg:mrc p15, 0, r0, c0, c0, 0(mrc指令读取MIDR(主ID)寄存器,读出来的结果放入了寄存器R0中)

    CPSR分为I位(bit[7](0不屏蔽  1屏蔽))、F位(bit[6] 0不屏蔽 1屏蔽)

CPS指令

        这里的 effect 分为俩个bit[7](IE使能 cpsie(0)、ID失能cpsid(1)),使用了effect的话就不能省略iflags,i位指irq,f位指frq

PS:在汇编中调main.c中的函数时,要先保护现场

获取中断号,并记录 

GPIOx_ICR        //设置中断寄存器 

GPIOx_IMR        //设置中断屏蔽寄存器 ,若为1,开中断

GPIOx_ISR        //设置中断标记寄存器 ,若为1,则说明该位产生中断,但要手动清零

4.4  抢占优先级

        Cortex——A7 有32个抢占优先级(谁数小,谁的优先级就高)

        1 1111 ---> 32个

        0(组优先级) xxxx(子优先级)

五、提高代码的耦合性

gpio.c

#include "gpio.h"void gpio_pin_config(GPIO_Type *base, int pin, GPIO_Pin_Config_t *config)   //初始化函数,GPIo引脚的配置,   
// 参数分别是GPIO_Type类型的base,将GPIO的组号传入   参数2:引脚号     参数3:初始化引脚
{if(config->direction == GPIO_Direction_Out)     //判断  将相关寄存器,方向配置为输出{base->GDIR |= (1 << pin);if(config->defalut_value != 0)   //该引脚的默认值为高电平{  base->DR |= (1 << pin);   }else   // 该引脚的默认应该配置为低电平{base->DR &= ~(1 << pin);   }}else  //需要将该引脚配置为低电平{base->GDIR &= ~(1 << pin);}
}void gpio_write(GPIO_Type *base, int pin, int value)  //写入函数,参数分别是:参数1:参数分别是GPIO_Type类型的base,将GPIO的组号传入
// 参数2:引脚   参数3:需要写入的值
{if(value)       //判断写入的值是不是1,如果是1的话,则在其DR写入1;{base->DR |= (1 << pin);  //在输入得引脚写入1}else    // 如果不是,则进行指定位清0{base->DR &= ~(1 << pin);     //在输入得引脚写入0}
}int gpio_read(GPIO_Type *base, int pin) // 读函数,参数分别是GPIO_Type类型的base,第二个参数:引脚
{return (base->DR & (1 << pin)) != 0;
}

gpio.h

#ifndef _GPIO_H_
#define _GPIO_H_
#include "MCIMX6Y2.h"
typedef enum
{GPIO_Direction_Out,GPIO_Direction_In
}GPIO_Direction_t;   //枚举的方法列举GPIO两种状态,输入或者输出的方向typedef struct 
{GPIO_Direction_t direction;  // 引脚的工作方式,列:输入或者输出int defalut_value;       // 初始化引脚后,该引脚的默认值是高电平还是低电平
}GPIO_Pin_Config_t;    //    初始化引脚extern void gpio_pin_config(GPIO_Type *base, int pin, GPIO_Pin_Config_t *config);
extern void gpio_write(GPIO_Type *base, int pin, int value);
extern int gpio_read(GPIO_Type *base, int pin);#endif

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

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

相关文章

Linux部署Sonic前后端(详细版)(腾讯云)

系统用的是Ubuntu 22.04 LTS 1、安装Docker sudo apt update sudo apt install -y docker.io docker-compose sudo systemctl start docker sudo systemctl enable docker# 如果不想每次用 sudo&#xff0c;可以加权限 sudo usermod -aG docker $USER 2、安装 docker-compose…

腾讯云CBS:企业级云存储的性能与可靠性重构

摘要 根据Forrester 2025年网络分析与可见性&#xff08;NAV&#xff09;报告&#xff0c;东西向流量安全与加密威胁检测成为企业核心痛点&#xff08;误报率降低需求↑40%&#xff09;。腾讯云CBS作为底层存储支柱&#xff0c;通过三副本跨可用区冗余架构与毫秒级故障切换能力…

ubuntu 22.04 更换阿里源 (wsl2 参照)

步骤 1: 备份当前源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 步骤 2: 编辑源列表文件 sudo nano /etc/apt/sources.list 步骤 3: 添加阿里云镜像源 ubuntu 阿里源地址可以在这查看 ubuntu镜像_ubuntu下载地址_ubuntu安装教程-阿里巴巴开源镜像站 …

idea中push拒绝,merge,rebase的区别

在 IntelliJ IDEA 中进行 Git 操作时&#xff0c;Push 拒绝&#xff08;Push Rejected&#xff09;、Merge 和 Rebase 是常见的冲突解决方式。它们有不同的适用场景和影响&#xff0c;下面详细说明它们的区别&#xff0c;并附上流程图帮助理解。 1. Push 拒绝&#xff08;Push …

轻松实现PDF局部擦除的技术级解决方案

在处理PDF文档时&#xff0c;我们常常会遇到这样的场景&#xff1a;想要删除某段文字、擦除一张图片&#xff0c;或者对页面内容进行局部调整。但很多编辑工具要么操作繁琐&#xff0c;要么功能受限&#xff0c;甚至还需要付费解锁核心功能。 这是一款轻便又实用的PDF编辑工具…

css color 十六进制颜色透明度

css color 十六进制颜色透明度 例&#xff1a;#FFFFFF ~~ #FFFFFF1A(10% ) 0% 为 FF10% 为 1A20% 为 3330% 为 4D40% 为 6650% 为 8060% 为 9970% 为 B380% 为 CC90% 为 E6100% 为 00

Git简介和常用命令

Git简介 Git是一款版本管理软件&#xff0c;可以在任何时间点保存文件&#xff0c;也能够恢复到以前任意时间点保存的文档&#xff0c;Git作用简单举例来说就是&#xff0c;写论文&#xff0c;有很多个版本&#xff0c;将原来的论文保存起来&#xff0c;新建一个副本&#xff…

Kafka 性能调优指南

文章目录 概述操作系统层面调优文件系统优化内存管理磁盘 I/O 优化 JVM 调优堆内存设置GC 收集器选择常见 GC 问题 Broker 端调优版本兼容性关键参数配置日志段大小调优设置原则推荐配置调优考虑因素监控命令 应用层调优客户端复用资源管理多线程消费模式 性能指标调优吞吐量优…

佰力博科技与您探讨低温真空探针台如何保养

低温真空探针台是一种用于在低温或真空环境下进行电学性能测试的精密仪器&#xff0c;其保养和维护对于确保设备的稳定运行和延长使用寿命至关重要。 一、日常清洁与检查 1、使用后应立即清洁探针台&#xff0c;尤其是探针、接口和连接器&#xff0c;避免灰尘和杂质影响精度。…

MySQL:深入总结锁机制

写在前面 在 MySQL 数据库中&#xff0c;锁机制是保障并发控制和数据一致性的关键。合理运用锁机制&#xff0c;能有效避免数据竞争&#xff0c;提升数据库性能。接下来&#xff0c;我们就深入了解 MySQL 中的各类锁。 博主总结&#xff08;注&#xff1a;针对总结的详解补充在…

AI+OT安全,让威胁情报实现主动防御

当前&#xff0c;网络犯罪组织的运作模式正日趋“企业化”&#xff0c;给全球网络安全带来了严峻挑战。企业以及各类组织机构有必要采用威胁情报驱动的防御体系&#xff08;Threat-Informed Defense, TID&#xff09;&#xff0c;将安全运营模式从被动响应彻底转向基于威胁情报…

深度剖析:UDS上下行分离隧道如何绕过主流防火墙?

&#x1f525; 深度剖析&#xff1a;UDS上下行分离隧道如何绕过主流防火墙&#xff1f; &#x1f4ca; 系统架构图 #mermaid-svg-lv5FKIvBMKPeTFuW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-lv5FKIvBMKPeTFuW …

Vue 使用vue-cli

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - 使用Vue-cli 笔记 目录 使用vue-cli 创建项目 配置文件 启动项目 入口文件 Index.html Main.js Eslint修复 第一种 第二种 第三种 更换为淘宝源 查看当前配置 配置淘宝源 验证配置 总结 使用vue-cli 创建项目…

Sentinel实现原理

Sentinel 是阿里巴巴开源的分布式系统流量控制组件&#xff0c;主要用于服务保护&#xff0c;涵盖流量控制、熔断降级、系统负载保护等功能。 以下是 Sentinel 的实现原理&#xff0c;使用中文简要说明&#xff1a; 1. 总体架构 Sentinel 采用 轻量级 设计&#xff0c;分为 核…

DeepSeek生成HTML5生命天数计算器

DeepSeek生成HTML5生命天数计算器 让DeepSeek生成一个生命天数计算器 提示词prompt 帮我做一个我活了多少天的网页 用户输入出生日期即可显示我活了多少天 页面ui要好看点&#xff0c;加上显示官方统计 人一生平均可以活多少天 自动计算剩余天数。帮我按照上述需求再次生成一个…

如何使typora图片不居中留白?

如何使typora图片不居中留白&#xff1f; 驻波使用typora记笔记的时候&#xff0c;好几次插入图片太大选择缩小都会发现图片仍然滞留在中间&#xff0c;居中显示&#xff0c;但我本人觉得并不好看&#xff0c;所以我决定改一下&#xff0c;于是有了这篇博客 检查看原理 软件内…

高精度频率基石:超低相噪恒温晶振的全场景应用解决方案

在科技高速发展的今天&#xff0c;频率源作为电子系统的 “心脏”&#xff0c;其稳定性与可靠性直接决定着通信、导航、测量等关键领域的性能上限。深度洞察行业需求&#xff0c;重磅推出SYN3627L 型 100MHz 恒温晶振&#xff08;OCXO&#xff09;。这款集高稳定性、低相位噪声…

【android bluetooth 协议分析 01】【HCI 层介绍 27】【LeReadRemoteFeatures命令介绍】

深入理解 LE Read Remote Features 命令与事件响应 在蓝牙低功耗&#xff08;BLE&#xff09;通信中&#xff0c;设备特性&#xff08;LE Features&#xff09;协商是连接过程中的一个关键环节。本文将详细介绍 HCI 层的命令 LE_Read_Remote_Features 及其对应的事件响应 LE_R…

企业架构设计中的CBAM方法深度解析:成本效益驱动的架构决策艺术

目录 CBAM方法概述与核心价值 CBAM核心流程与实施步骤 前期准备与场景确定 成本效益建模与分析 风险调整与决策制定 实施技巧与挑战克服 CBAM实战案例与应用场景 案例一&#xff1a;电商平台促销系统架构选型 案例二&#xff1a;制造业ERP系统云迁移决策 案例三&…

为什么你的vue项目连接不到后端

当你新创建一个vue项目时&#xff0c;你很有可能忘记配置了后端的地址这个时候可以加上这样的配置在 vite.config.js import { fileURLToPath, URL } from node:urlimport { defineConfig } from vite import vue from vitejs/plugin-vue import vueDevTools from vite-plugi…