目录
一、使用的硬件开发板
开发板名称(硬件平台):FS-MP1A (STM32MP157AAA开发板套件)
主控制器:STM32MP157AAA3 = Cortex-A7 * 2 + Cortex-M4 ———— 异构核
CPU主频:Cortex-A7最高650MHz Cortex-M4最高209MHz
硬盘:eMMC(4G) TF卡(32G)
DDR3:512MB
网卡:千兆网卡
屏幕:5寸、7寸、HDMI屏幕
摄像头:OV5640
1、核心板
2、拓展板
二、分析芯片手册
1、框图分析
2、MP157芯片内部框图
3、物理地址隐射表
1)查找物理内存映射表
物理地址也就是物理硬件内存地址,想要查找物理地址隐射表,我们就得先找到哪个章节是关于物理内存的,查看目录我们可以发现第2章节(Memory and bus architecture)是关于内存和片内总线架构的,再看到第二章的第五节,是内存结构,这里面就是物理地址隐射表了
2)分析物理内存结构
3)分析物理内存映射表
4、RCC章节
1)查找对应的RCC寄存器
RCC寄存器是用来管理外部设备管理器寄存器组的时钟使能的,只有用RCC寄存器使能了对应寄存器组的时钟后,才可以操作这个寄存器组。
仿照芯片手册中存在的寄存器名字,可以得到初步的RCC寄存器名字 - RCC_MP_AHB4ENSETR
2)操作寄存器使能时钟
5、GPIO章节
打开数据手册,看目录可以找到专门将GPIO的章节,也就是第13章节
1)GPIO介绍
GPIO口的八种工作模式:
输入模式
1. 浮空输入(Floating Input) FI 无内部上拉 / 下拉,电平由外部电路决定,易受干扰
2. 上拉输入(Pull-Up Input) PU 内部接拉电阻到 VDD,无外部信号时默认输出高电平
3. 下拉输入(Pull-Down Input) PD 内部接拉电阻到 GND,无外部信号时默认输出低电平
4. 模拟输入(Analog Input) AI 引脚直接连接 ADC,用于采集模拟电压信号,不进行数字电平检测
输出模式
5. 推挽输出(Push-Pull Output) PP 可输出高 / 低电平,驱动能力强,适合直接驱动 LED、继电器等
6. 开漏输出(Open-Drain Output) OD 仅能输出低电平,高电平需外部上拉电阻,适合电平转换、总线通信(如 I²C)
7. 复用推挽输出(Alternate Push-Pull) AF_PP 引脚功能复用为外设(如 UART_TX、SPI_MOSI),输出结构为推挽
8. 复用开漏输出(Alternate Open-Drain) AF_OD 引脚功能复用为外设(如 I²C_SDA/SCL),输出结构为开漏
2)上拉电阻
电路的悬空状态(高阻态):当前电路的阻值无限大,并不清楚当前电路处于高电平状态还是低电平状态
上拉电阻就是由一个电阻和电源相连
悬空状态的电路,存在不清楚是高电平还是低电平的问题,当外接上拉电阻以后,可以稳定当前电路处于高电平状态
3)下拉电阻
下拉电阻就是一个电阻与GND相连接
当一个电路处于悬空状态时,外接一个下拉电阻,可以时当前电路处于稳定的低电平状态,用于保护电路
4)推挽输出
使用推挽输出时
GPIO外设控制器中的N-MOS管和P-MOS管都可以正常工作
可以正常的输出高电平信号和低电平信号
5)开漏输出
使用开漏输出时
GPIO外设控制器中的P-MOS管不工作,N-MOS管正常工作
无法输出高电平信号,可以输出低电平信号
如果一定要用开漏输出模式输出高电平,可以外接上拉电阻
这样在GPIO口悬空时会被上拉电阻拉到高电平
6)GPIO内部框图输出分析
7)GPIO内部框图输入分析
8)配置使能GPIO的寄存器
根据上图中,数据手册的描述,我们可以得知用于硬件初始化的寄存器有:
GPIOx_MODER寄存器 用于选择GPIO的工作模式(输入、输出、复用、模拟)
GPIOx_OTYPER寄存器 用于选择GPIO的输出模式(推挽、开漏)
GPIOx_OSPEEDR寄存器 用于选择GPIO输出速率(低速、中速、高速、超高速)
GPIOx_PUPDR寄存器 用于选择GPIO是否外接上拉/下拉电阻
(1)GPIOx_MODER(工作模式)
(2)GPIOx_OTYPER(输出模式)
(3)GPIOx_OSPEEDR(输出速率)
(4)GPIOx_PUPDR(上拉/下拉电阻)
9)存储GPIO读写值的寄存器
根据上图中,数据手册的描述,我们可以得知可以存储读GPIO写值的寄存器有:
GPIOx_IDR寄存器 ———— 这是一个只读寄存器 ———— 用于存储被输入的(读取到的)数据
GPIOx_ORD寄存器 ———— 这是一个读写寄存器 ———— 用于存储要输出的数据
(1)GPIOx_IDR(输入寄存器)
(2)GPIOx_ODR(输出寄存器)
6、总结初始化GPIO的流程
- 在片内总线中找到要操作的寄存器组的地址区间;
- 在要操作的寄存器的介绍章节,找到要操作的寄存器的地址偏移量,以及寄存器的功能;
- 根据寄存器组地址 加上 寄存器的地址偏移量,向地址写入寄存器的功能码,操作对应的寄存器;
- 操作RCC寄存器组中RCC_MP_AHB4ENSETR寄存器,使能想要操作的GPIO寄存器组的时钟;
- 操作GPIOx_MODER寄存器,设置GPIOx指定引脚的工作模式(输入、输出);
- 操作GPIOx_OTYPER寄存器,设置GPIOx指定引脚的输出模式(推挽,开漏);
- 操作GPIOx_OSPEEDR寄存器,设置GPIOx指定引脚的输出速率;
- 操作GPIOx_PUPDR寄存器,设置GPIOx指定引脚是否上拉下拉。
- 操作GPIOx_IDR和GPIOx_ODR寄存器,控制寄存器读写。
三、汇编指令编写代码读写寄存器
四、C语言编写代码读写寄存器
1、工程基本架构
02-led-c
├── common ----- 公共文件目录
├── include ----- 自定义的头文件目录(需要使用到的)
├── main.c ----- 主函数(需要使用到的)
├── Makefile ----- 工程管理文件
├── map.lds ----- 链接脚本文件
├── src ----- 自定义的源文件目录(需要使用到的)
└── start ----- 启动目录(存在一个start.s启动文件)
需要编写3个文件:
led.h // 头文件
led.c // 源文件
main.c // 执行逻辑主函数
2、初始化要使用的寄存器组的地址
初始化要使用的寄存器组的地址,可以方便后续的使用,结构体中的成员必须和寄存器组中寄存器连续一一对应。
3、使能RCC寄存器组中关于GPIOx的时钟
4、初始化要使用的GPIOx的引脚
5、编写调用外部设备的函数
6、主函数
五、烧入ARM汇编/C语言代码
1、打开SecureCRT烧入软件
2、连接ST-LINK
3、将程序烧入到开发板中