STM32F429入门(二)

2023-05-16

开始学习嵌入式的第二天,发现昨天学习的东西有些遗漏,今天要做个补充😎。那么就从寄存器那一块开始补学吧,昨天没有那么仔细地去学习这个知识。

(一)学会看丝印:

  • 如果有小圆点在芯片上,则从这个小圆点开始逆时针,就是引脚口从1到最大引脚口。

  • 如果没有小圆点在芯片上,则正看芯片,引脚口1在左上角开始,再逆时针。 

     

(二)芯片和外设之间通过各种总线连接,其中主控线(也就是内核控制的部分)有8条,被控总线有7条,主控总线通过一个总线矩阵来连接被控总线,总线矩阵用于主控总线之间的访问仲裁管理,仲裁采用 循环调度算法。总线之间交叉的时候如果有个圆圈则表示可以通信,没有圆圈则表示不可以通信。

(三)STM32有三种启动方式:

  • 从Flash启动(包含系统存储器)

  • 从内部SRAM启动

  • 从外部RAM启动

    这也可以说明,启动总线与三根被控总线有交叉,也就是再总线接口图中有圆圈,这三种存储器就刚好对应三条总线。

    (四)总线基地址

    片上的外设分为四条总线,根据外设速度不同,不同总线挂载着不同的外设,APB挂载低速外设,AHB挂载高速外设(GPIO为高速外设)。相应总线的最低地址我们陈为总线的基地址。

  •  

如图,0x4002 0000为AHB1总线的基地址。

相对外设基地址的偏移:即该总线地址与“片上外设”基地址 0x4000 0000 的差值。方便对外设进行封装使用。

 

(五)外设基地址

总线上挂载着各种外设,这些外设也有自己的地址范围,特定外设的首个地址称为 “XX 外设基地址”,也叫 XX 外设的边界地址。

对于我的理解就是,在确定总线基地址之后,我们在对总线中的外设进行分配地址,而相对地址的偏移,就是相对于总线地址的偏移。

 

(六)外设寄存器

在 XX 外设的地址范围内,分布着的就是该外设的寄存器。以 GPIO 外设为例,GPIO 是通用输入输出端口的简称,简单来说就是 STM32 可控制的引脚,基本功能是控制引脚输出高电平或者低电平。最简单的应用就是把 GPIO 的引脚连接到 LED 灯的阴极,LED 灯的 阳极接电源,然后通过 STM32 控制该引脚的电平,从而实现控制 LED 灯的亮灭。

GPIO 有很多个寄存器,每一个都有特定的功能。每个寄存器为 32bit,占四个字节, 在该外设的基地址上按照顺序排列,寄存器的位置都以相对该外设基地址的偏移地址来描述。

按照以上几层基地址的层次嵌套,我们使用C语言封装后,可以看到以下:

1 /* 外设基地址 */

 

2 #define PERIPH_BASE ((unsigned int)0x40000000)

4 /* 总线基地址 */

5 #define APB1PERIPH_BASE PERIPH_BASE

6 #define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000)

7 #define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)

8 #define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000)

10 /* GPIO外设基地址 */

11 #define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000)

12 #define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400)

13 #define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800)

14 #define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00)

15 #define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000)

16 #define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400)

17 #define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800)

18 #define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00)

20 /* 寄存器基地址,以GPIOH为例 */

21 #define GPIOH_MODER (GPIOH_BASE+0x00)

22 #define GPIOH_OTYPER (GPIOH_BASE+0x04)

23 #define GPIOH_OSPEEDR (GPIOH_BASE+0x08)

24 #define GPIOH_PUPDR (GPIOH_BASE+0x0C)

25 #define GPIOH_IDR (GPIOH_BASE+0x10)

26 #define GPIOH_ODR (GPIOH_BASE+0x14)

27 #define GPIOH_BSRR (GPIOH_BASE+0x18)

28 #define GPIOH_LCKR (GPIOH_BASE+0x1C)

29 #define GPIOH_AFRL (GPIOH_BASE+0x20)

30 #define GPIOH_AFRH (GPIOH_BASE+0x24)

所以偏移地址的好处就显而易见了,在封装时,在基地址上加入偏移地址就可以了!😎

(七)举个栗子

如果要使PH10实现输出低/高电平,要怎么实现?

step1:确定总线地址

#define PERIPH_BASE ((unsigned int)0x40000000)

#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)

#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00)

#define GPIOH_ODR *(unsignedint*)(GPIOH_BASE+0x14)

step 2 :

//输出低电平

GPIOH_ODR &= ~(1<<10);

以上代码是使1左移10位,后再取反,再与原来的值相与,保存原来的电平状态。如图所示:

 

step 3:

//输出高电平

GPIOH_ODR |= (1<<10);

(八)由于每个寄存器的偏移地址都是4位,类似于结构体的成员,成员地址都是递增的,所以我们使用结构体来封装寄存器列表,也就是上一篇文的所有GPIO寄存器,那就再提及一遍吧:

typedef unsigned int uint32_t; /*无符号32位变量*/

typedef unsigned short int uint16_t; /*无符号16位变量*/

/* GPIO寄存器列表 */

typedef struct {

uint32_t MODER; /*GPIO模式寄存器 地址偏移: 0x00 */

uint32_t OTYPER; /*GPIO输出类型寄存器 地址偏移: 0x04 */

uint32_t OSPEEDR; /*GPIO输出速度寄存器 地址偏移: 0x08 */

uint32_t PUPDR; /*GPIO上拉/下拉寄存器 地址偏移: 0x0C */

uint32_t IDR; /*GPIO输入数据寄存器 地址偏移: 0x10 */

uint32_t ODR; /*GPIO输出数据寄存器 地址偏移: 0x14 */

uint16_t BSRRL; /*GPIO置位/复位寄存器低16位部分 地址偏移: 0x18 */

uint16_t BSRRH; /*GPIO置位/复位寄存器高16位部分 地址偏移: 0x1A */

uint32_t LCKR; /*GPIO配置锁定寄存器 地址偏移: 0x1C */

uint32_t AFR[2]; /*GPIO复用功能配置寄存器 地址偏移: 0x20-0x24 */

} GPIO_TypeDef;

所以我们就可以使用结构体来访问寄存器:

GPIO_TypeDef *GPIOx; //定义一个GPIO_TypeDef类型的结构体指针GPIOx

GPIOx = GPIOH_BASE; //把指针地址设置为宏GPIOH_BASE地址

GPIOx->BSRRL = 0xFFFF; //通过指针访问并修改GPIOH_BSRRL寄存器

GPIOx->MODER = 0xFFFFFFFF; //修改GPIOH_MODER寄存器

GPIOx->OTYPER =0xFFFFFFFF; //修改GPIOH_OTYPER寄存器

uint32_t temp;

temp = GPIOx->IDR; //读取GPIOH_IDR寄存器的值到变量temp中

还有一种更简单的方法,就是定义GPIO端口基地址指针,这种方法比较常见:

/*使用GPIO_TypeDef把地址强制转换成指针*/

#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)

#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)

#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)

#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)

#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)

#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)

#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)

#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE)

定义以上后,我们可以直接”调用寄存器“:

GPIOA->ODR = 0xFF;

GPIOB->ODR = 0xFF;

... ...

那最后做个总结吧,其实封装就是,从内存映射到寄存器(define),之后用结构体封装,最后再用结构体指针指向从而可以直接使用。(个人理解)

以上只是以GPIO为例子来理解这个东西,其实其他外设也是这么封装的,那么今天的学习就到这吧,希望明天课多的我还可以挤出时间来学习!而且学习不敢像第一天这么敷衍了,漏了好多知识点T T。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32F429入门(二) 的相关文章

  • dubbo服务超时导致的异常org.apache.dubbo.remoting.TimeoutException

    1 dubbo服务超时异常提示信息如下 xff1a cause org apache dubbo remoting TimeoutException Waiting server side response timeout by scan
  • 基于TCP/IP实现串口到网络的通讯转换

    工作模式 通过串口服务器 xff0c 采集到天平的称量值发送到PC端 操作步骤 1 软件测试 测试工具 xff1a USR M0 V2 2 5 8 基础设置 xff1a 模块静态IP 设置成服务器IP xff0c HTTP服务端口 设置成4
  • 结构体的对其规则以及为什么要对其

    结构体的内存对齐规则以及为什么要对齐 内存对齐规则 span class token number 1 span 第一个成员在与结构体变量偏移量为 span class token number 0 span 的地址处 span class
  • 宏定义参数

    宏定义的参数以逗号 xff08 作为分隔符 span class token macro property span class token directive keyword include span span class token s
  • [STM32]关于环形队列的实现

    在程序中使用环形队列判断接收数据格式 xff0c 避免在中断中处理造成程序响应速度慢的问题 直接贴代码 xff1a LoopRxCommu h ifndef LOOPRXCOMMU H define LOOPRXCOMMU H includ
  • C#旅程——串口发送数据

    串口发送数据时可以一个byte一个byte的发送数据 xff0c 也可以一次性丢出 xff0c 分多次丢出的话会导致一段数据被分成多段发出 xff0c 中间的延时可能会超过2ms xff0c 与FW通讯时会出现异常 span class t
  • 【记录】一次51单片机串口乱码问题排查

    记录 一次51单片机串口乱码问题排查 项目场景问题描述原因分析解决方案结语 项目场景 在51串口收发仿真实验中使用两个单片机互相通信 xff0c 程序设定A上电1s后通过串口以16进制给B发送AA 直到B收到AA后回复BB xff0c 当A
  • IO流java基础

    二十四 IO流 24 1 File 1 1 File 类概述和构造方法 File 它是文件和目录路径名的抽象表示 文件和目录是可以通过File封装成对象的 对于File而言 其封装的并不是一个真正存在的文件 仅仅是一个路径名而已 它可以是存
  • TX2上布置vins_fusion_gpu指南

    1 参考链接 如果初次安装 xff0c 新的TX2环境 xff0c 请参考文档 https github com arjunskumar vins fusion gpu tx2 nano 2 问题记录 1 xff0c 自己的环境情况 我的环
  • Ubuntu下安装cmake

    Ubuntu下安装cmake 今天因为项目的原因需要将cmake升级一下 xff0c 原来我是按照链接没有卸载旧版本 xff0c 直接升级 但是出现一些问题 xff0c 然后我全部卸载后 xff0c 重新安装 以下就是我的安装步骤 第一步
  • AUTH:basic认证和digest认证

    Http authentication BASIC In the context of an HTTP transaction basic access authentication is a method for a web browse
  • Quick Audience组织和工作空间功能解读

    简介 xff1a Quick Audience完成了权限系统全面升级 xff0c 可以解决集团企业不同品牌 不同运营组织 xff0c 不同消费者运营的诉求 xff0c 精细化保障企业数据访问安全 xff0c 提升管控的灵活度 更多关于数智化
  • Socket编程基础总结,全网最全

    IP地址 xff1a 可以在网络环境中 xff0c 唯一标识一台主机 端口号 xff1a 可以定位网络的一台主机上 xff0c 唯一标识一个进程 ip地址 43 端口号 xff1a 可以在网络环境中 xff0c 唯一标识一个进程 在TCP
  • 嵌入式开发--RS-485通讯的问题

    嵌入式开发 RS 485通讯的问题 RS 485说明接口芯片硬件连接CubeMX设置代码编写引脚定义使能串口中断函数发送数据接收数据 有一个问题 xff0c 多收了一个数数据线上的波形问题分析问题解决 RS 485说明 RS 485一般简称
  • UNIX网络编程卷1(第三版)字节排序函数测试

    内存中存储多字节有两种方法 xff0c 即小端字节序和大端字节序 xff0c Ubuntu10 04 是小端字节序 xff0c 网际协议所用的字节序为大端字节序 内存地址增长方向 低序字节 gt 高序字节 小端字节序 高序字节 gt 低序字

随机推荐

  • android非常好的在线视频播放器源码(包含在线音频播放源码)

    一 在线音频播放器 lt xml version 61 34 1 0 34 encoding 61 34 utf 8 34 gt lt LinearLayout xmlns android 61 34 http schemas androi
  • 深入理解任务堆栈

    先来看这一个小函数 xff0c 猜猜他的运行结果 VC6环境 xff1f include lt stdio h gt void b int data 10 printf 34 helloworld r n 34 data 11 61 5 i
  • Protel99seMEX3

    Protel99se的鼠标增强软件 xff0c 可以实现用鼠标放大与缩小电路图 xff0c 十分方便 xff01 文件 xff1a n459 com file 25127180 478161061 以下内容无关 xff1a 分割线 说起Al
  • 基于C++的http服务端开发

    1 同时支持get post接口请求 2 支持文件流下载接口 完整源代码下载地址 xff1a https download csdn net download GUMU12345 81103130 sample cc Copyright c
  • Psychtoolbox SYNCHRONIZATION FAILURE问题

    参考 xff1a http psychtoolbox org docs SyncTrouble 写这篇文章的原因是自己遇见了这个问题 xff0c 并且换了两台电脑都不行 xff0c 有点烦了 xff0c 决心把它弄清楚是怎么回事 因为我的主
  • vscode写python切换虚拟环境,解释器没有不变的问题

    在用vscode写python代码 xff0c 可以使用anaconda进行虚拟环境的管理 而在vscode中使用Ctrl 43 Shift 43 P的方式调出终端 搜索即可搜索到相关设置 xff0c vscode中的python插件会自动
  • MVVM WPF 绑定颜色

    lt Button Margin 61 34 2 34 Width 61 34 10 34 gt lt Button Background gt lt SolidColorBrush Color 61 34 Binding Path 61
  • Android Handler

    Handler 和 Looper关系 Handler是对我们需要线程执行的一类任务的处理管理类 xff0c 而Looper是android线程所拥有的循环心跳行为的管理类 xff0c 例如主线程就是在一开始就执行了Looper loop x
  • linux 编程 ———网络编程(Socket 编程)客户端与服务端实现源码

    文档声明 xff1a 以下资料均属于本人在学习过程中产出的学习笔记 xff0c 如果错误或者遗漏之处 xff0c 请多多指正 并且该文档在后期会随着学习的深入不断补充完善 感谢各位的参考查看 笔记资料仅供学习交流使用 xff0c 转载请标明
  • 使用vs生成C++动态链接库dll文件----使用C++和C#混合编程

    https blog csdn net qq 30139555 article details 103621955
  • 视觉SLAM作业(四) 相机模型与非线性优化

    视觉SLAM作业 xff08 四 xff09 相机模型与非线性优化 一 图像去畸变 现实生活中的图像总存在畸变 原则上来说 xff0c 针孔透视相机应该将三维世界中的直线投影成直线 xff0c 但是当我们使用广角和鱼眼镜头时 xff0c 由
  • 在TUMVI数据集上测试VINS-Fusion算法

    VINS Fusion算法是一个非常优秀的视觉惯性里程计 但原版VINS Fusion并没有提供与TUM数据集相应的配置文件 因此需要自己进行写yaml文件 修改配置文件 tum mono yaml span class token dir
  • SLAM中的三角测量

    来源 视觉SLAM十四讲 xff0c 作者 高翔 三角测量是SLAM中 xff0c 利用相机运动估计特征点空间位置的过程 本节旨在解决以下问题 xff1a 三角测量的概念三角测量的过程及代码实现 xff1b 三角测量有哪些不确定性如何提高三
  • SLAM 岗位求职与简历书写

    本文学习自B站计算机视觉Life的如何写简历 当前求职背景怎么样 2019计算机直觉算法岗的求职情况为 xff1a 候选人数很多 xff0c 优秀者极少找工作不仅需要实力 xff0c 也需要运气 原因 贸易战影响 xff1a 华为 海康 大
  • SLAM中的后端优化

    本节介绍SLAM中的后端优化过程 一 问题阐述 同时对三维点位置和相机参数进行非线性优化 二 LM法的原理与优势 原理 xff1a 是一种 信赖域 的方法 xff0c 当收敛速度较快时 xff0c 增大信赖域使算法趋向于高斯牛顿法 xff1
  • 运动一致性判断

    直至以来 xff0c SLAM的研究共朝着三个方向努力 xff1a 精度 速度 鲁棒性 尤以鲁棒性居多 通常动态场景中 xff0c 根据IMU测量值与视觉测量值分别进行计算得到的结果会有所不同 因此需要进行一致性的检测 xff0c 以得到真
  • 使用evo工具评测SLAM

    evo是一款用于视觉里程计和slam问题的轨迹评估工具 核心功能是能够绘制相机的轨迹 xff0c 或评估估计轨迹与真值的误差 支持多种数据集的轨迹格式 xff08 TUM KITTI EuRoC MAV ROS的bag xff09 xff0
  • 用VS Code写C语言无法使用`__attribute__(packed)`

    今天 xff0c 在Windows上写C语言程序 xff0c 结果编写的结构体总是无法使用 attribute packed xff0c 导致读取的二进制文件字节对不上 检查CMakeLists txt和代码均没有发现明显错误 typede
  • CURL 基于命令行的浏览器

    CURL 嗯 xff0c 说来话长了 这东西现在已经是苹果机上内置的命令行工具之一了 xff0c 可见其魅力之一斑 1 二话不说 xff0c 先从这里开始吧 xff01 curl http www yahoo com 回车之后 xff0c
  • STM32F429入门(二)

    开始学习嵌入式的第二天 xff0c 发现昨天学习的东西有些遗漏 xff0c 今天要做个补充 x1f60e 那么就从寄存器那一块开始补学吧 xff0c 昨天没有那么仔细地去学习这个知识 xff08 一 xff09 学会看丝印 xff1a 如果