STM32学习3 寄存器映射和GPIO寄存器编程

STM32学习3 寄存器映射和GPIO寄存器编程

  • 一、STM32外设内存空间
    • 1. 内存空间划分
    • 2. 区域功能说明
      • (1)block0
      • (2)block1
      • (3)block2
      • (4)block3~4
      • (5)block5
      • (6)block6
      • (7)block7
    • 3. APB总线
    • 4. AHB总线
  • 二、寄存器映射与位带操作
    • 1. 寄存器映射
    • 2. 位带操作
  • 三、寄存器映射操作步骤
    • 1. 找到外设基地址
    • 2. 找到 GPIOC 的地址
    • 3. GPIO的寄存器
    • 4. 设置GPIO口工作模式
    • 5. 开启时钟
    • 6. 寄存器映射示例

本文通过介绍GPIO寄存器,介绍寄存器编程方法,实现与前一章库函数编程类似的控制功能。
本系列源码地址: https://gitee.com/xundh/stm32_arm_learn

一、STM32外设内存空间

1. 内存空间划分

STM32 的4G地址空间以512M为单位划分为8个地址区域:
在这里插入图片描述

2. 区域功能说明

以下是8个区域每个区域的功能描述:

(1)block0

block 0 是Flash的第一块,它是Flash存储器的重要部分,主要有以下作用:

  • 让Bootloader可以在不同地址上运行,从而实现不同的启动方式和功能;
  • 片内Flash:0x08000000~0x0807FFFF 512K容量 ;
  • System momory:存储bootloader,0x1FFF F000~0x1FFF F7FF;
  • Option Bytes:存储启动方式 、读保护设置 、写保护设置 、时钟源选择、唯一设备标识信息等 ;

在这里插入图片描述

(2)block1

block1 也是Flash存储器的区块,用来设计片内SRAM。

(3)block2

通常用于存储片内外设的配置信息、参数设置 以及其它相关数据,这是寄存器编程控制外设的重点,下表是STM32外设空间映射表:
### (1)

(4)block3~4

用于配置和设置外部存储器接口FSMC(Flexible Static Memory Controller)。
在这里插入图片描述

(5)block5

也是用于FSMC。在这里插入图片描述

(6)block6

预留 。

(7)block7

ARM内部使用。

3. APB总线

在STM32微控制器中,APB(Advanced Peripheral Bus)是一种总线结构,用于连接微控制器内部的外设。STM32微控制器通常具有两个或多个APB总线,包括APB1、APB2等。这些总线的作用是连接微控制器的核心部件(如CPU、存储器等)与外设之间,以实现外设的控制和数据传输。

  • APB1总线主要用于连接一些低速外设,前表从TIM2~DAC的部分;
  • APB2总线则用于连接一些高速外设,前表从AFIO~ADC3。

4. AHB总线

AHB(Advanced High-performance Bus)总线是STM32微控制器中的一种高性能总线,通常有更高的带宽和速度。
AHB总线被分为主AHB总线和备用AHB总线。

AHB的外设从前表的 SDIO~CRC。

二、寄存器映射与位带操作

1. 寄存器映射

寄存器映射是一种将硬件设备内部的控制寄存器映射到处理器的内存地址空间中的技术(即对内存单元取一个别名),使得处理器可以通过读写这些特定的内存地址来控制和配置硬件设备的功能和参数。
寄存器映射使用#define

2. 位带操作

位带操作是一种针对特定位进行操作的技术,它可以在单条指令中对某个位进行设置、清除或者翻转,从而实现对寄存器中的单个位的操作,而不影响寄存器中的其他位。

三、寄存器映射操作步骤

1. 找到外设基地址

假设找GPIOC的第 0 管脚 , 首先,要通过手册知道GPIOC挂在APB2上,总线的基地址如下:

总线名称基地址相对APB地址
APB10x4000 00000x0
APB20x4001 00000x0001 0000
AHB0x4001 80000x0001 8000

C定义:

//  外设基地址
#define PERIPH_BASE ((unsigned int)0x40000000)
// APB2 总线基地址
#define APB2PERIPH_BASE ((PERIPH_BASE + 0x00010000)

2. 找到 GPIOC 的地址

0x4001 1000~ 0x4001 13FF
在这里插入图片描述
C 定义:

#define GPIOC_BASE (AHB2PERIPH_BASE + 0x1000)

在 stm32f10x.h 里可以找到它的定义:
在这里插入图片描述

3. GPIO的寄存器

GPIOC的寄存器偏移根据手册查询:

寄存器地址相对GPIOC基址的偏移
GPIOC_CRL0x4001 10000x00
GPIOC_CRH0x4001 10040x04
GPIOC_IDR0x4001 10080x08
GPIOC_ODR0x4001 100C0x0C
GPIOC_BSRR0x4001 10100x10
GPIOC_BRR0x4001 10140x14
GPIOC_LCKR0x4001 10180x18

C 定义:

typedef struct
{__IO uint32_t CRL;__IO uint32_t CRH;__IO uint32_t IDR;__IO uint32_t ODR;__IO uint32_t BSRR;__IO uint32_t BRR;__IO uint32_t LCKR;
} GPIO_TypeDef;
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)

这样使用 GPIOC->CRL 就可以操作对应的寄存器。

4. 设置GPIO口工作模式

根据前一章的介绍,GPIO的CRL和 CRH是工作模式寄存器。如果要设置推挽输出,可以使用:

    GPIOC->CRL = 0x33333333; // 配置低八位引脚为推挽输出模式GPIOC->CRH = 0x33333333; // 配置高八位引脚为推挽输出模式

5. 开启时钟

在 STM32 中,每个外设都需要时钟信号来工作,在使用外设之前需要先打开对应外设的时钟。

RCC 寄存器中的 RCC_APB2ENR 用于控制 APB2 总线上的外设时钟使能。寄存器编程时,使用宏定义:RCC_APB2ENR_IOPCEN 用来让 GPIOC 的时钟使能位,它对应于 RCC_APB2ENR 寄存器中的 GPIOC 时钟使能位。

以下是 RCC_APB2ENR 寄存器中常用的一些位定义:

  • Bit 0: AFIOEN,用于使能 AFIO 外设的时钟。
  • Bit 2: IOPAEN,用于使能 GPIOA 外设的时钟。
  • Bit 3: IOPBEN,用于使能 GPIOB 外设的时钟。
  • Bit 4: IOPCEN,用于使能 GPIOC 外设的时钟。
  • Bit 5: IOPDEN,用于使能 GPIOD 外设的时钟。
  • Bit 6: IOPEEN,用于使能 GPIOE 外设的时钟。
  • Bit 7: IOPFEN,用于使能 GPIOF 外设的时钟。
  • Bit 8: IOPGEN,用于使能 GPIOG 外设的时钟。
  • Bit 11: ADC1EN,用于使能 ADC1 外设的时钟。

编程时,使用 |= 运算符把相应位置为 1,如:RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

6. 寄存器映射示例

#include "stm32f10x.h"// GPIO配置函数
void GPIO_Configuration(void)
{// 开启GPIOC的时钟RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;// 设置GPIOC的模式为推挽输出GPIOC->CRL = 0x33333333; // 配置低八位引脚为推挽输出模式GPIOC->CRH = 0x33333333; // 配置高八位引脚为推挽输出模式
}// 延时函数
void delay(uint32_t i)
{while (i--) //当i不为0时,持续减1,实现延时;
}// 打开指定位置的LED
void on(int position)
{GPIOC->BSRR = (1 << position); // 设置对应的位,输出低电平
}// 关闭指定位置的LED
void off(int position)
{GPIOC->BRR = (1 << position); // 清除对应的位,输出高电平
}// 主函数
int main(void)
{GPIO_Configuration(); //调用GPIO配置函数int j;while (1) //无限循环{for (j = 0; j < 8; j++) //遍历0到7号位{on(j); //打开j号位的LEDdelay(0xfffff); //延时off(j); //关闭j号位的LEDdelay(0xfffff); //延时}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

UE4 材质多张图片拼接成一张图片(此处用2×2拼接)

UE4 材质多张图片拼接成一张图片&#xff08;此处用22拼接&#xff09; //TexCoord,TextureA,TextureB,TextureC,TextureDfloat3 ReturnTexture TextureA; if(TexCoord.x < 0.5 && TexCoord.y < 0.5) {ReturnTexture TextureA; } else if(TexCoord.x > 0.5…

对Redis锁延期的一些讨论与思考

上一篇文章提到使用针对不同的业务场景如何合理使用Redis分布式锁&#xff0c;并引入了一个新的问题 若定义锁的过期时间是10s&#xff0c;此时A线程获取了锁然后执行业务代码&#xff0c;但是业务代码消耗时间花费了15s。这就会导致A线程还没有执行完业务代码&#xff0c;A线程…

vue中循环多个li(表格)并获取对应的ref

有种场景是这样的 <ul><li v-for"(item,index) in data" :key"index" ref"???">{{item}}</li> </ul> //key值在项目中别直接用index&#xff0c;最好用id或其它关键值const data [1,2,3,4,5,6]我想要获取每一个循环并…

华为云是什么

公有云配置 区域&#xff1a; 同一个区域中的云主机是可以互相连通的&#xff0c;不通区域云主机是不能使用内部网络互相通信的 选择离自己比较近的区域&#xff0c;可以减少网络延时卡顿 华为云yum仓库&#xff1a;https://repo.huaweicloud.com/rockylinux/ 首先完成跳板机的…

【linux进程信号(一)】信号的概念以及产生信号的方式

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; 进程信号 1. 前言2. 信号的基…

亿道推出重磅加固平板!为行业发展注入新动力

随着科技生产力的不断发展&#xff0c;各行各业都得到质的飞跃。产品的迭代速度也大大加快&#xff0c;作为全球领先的加固行移动终端一站式提供商&#xff0c;亿道信息跟紧时代潮流&#xff0c;推出EM-I10J、EM-I20J两款均衡型加固平板&#xff0c;为行业发展注入新动力。 接地…

YOLOv8 DeepSORT实现智能交通监控-改进yolo单目测距及速度测量-流量计数

YOLOv8&#xff1a;目标检测算法详解 YOLO&#xff08;You Only Look Once&#xff09;系列是一种单阶段、实时的目标检测框架&#xff0c;其最新迭代版本YOLOv8继承并优化了前代YOLO在速度与精度上的优势。YOLOv8的核心思想在于将整幅图像一次性输入到神经网络中&#xff0c;直…

dpdk协议栈之udp架构优化

dpdk优势 传统网络架构与 DPDK&#xff08;Data Plane Development Kit&#xff09;网络架构之间存在许多区别&#xff0c;而 DPDK 的优势主要体现在以下几个方面&#xff1a; 数据包处理性能&#xff1a;传统网络架构中&#xff0c;网络数据包的处理通常由操作系统的网络协议…

【学习笔记】Serdes中的高速接口设计

参考文献&#xff1a; 一、绪论 1.1 背景 “串行替代并行”&#xff1a; 串行传输使用差分信号传输以传输更长距离&#xff1b; 并行传输因串扰无法长距离传输&#xff1b;并行线路对信号偏斜量的要求&#xff0c;限制了最大的传输速率。 SerDesSerializer Deserializer S…

2024程序员容器化上云之旅-第2集-Ubuntu-WSL2-Windows11版:接近深洞

故事梗概 Java程序员马意浓在互联网公司维护老旧电商后台系统。 渴望学习新技术的他在工作中无缘Docker。 他开始自学Vue3并使用SpringBoot3完成了一个前后端分离的Web应用系统&#xff0c;并打算将其用Docker容器化后用K8s上云。 3 挑选工具 马意浓画好架构图后&#xff…

基于yolov5的行人跌倒检测,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的行人跌倒检测系统&#xff0c;支持图像检测&#xff0c;视屏检测和摄像头检测_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的行人跌倒检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的项目&#xff0c;包括代…

蜣螂优化算法DBO求解不闭合SD-MTSP,可以修改旅行商个数及起点(提供MATLAB代码)

一、蜣螂优化算法&#xff08;Dung beetle optimizer&#xff0c;DBO&#xff09; 蜣螂优化算法&#xff08;Dung beetle optimizer&#xff0c;DBO&#xff09;由Jiankai Xue和Bo Shen于2022年提出&#xff0c;该算法主要受蜣螂的滚球、跳舞、觅食、偷窃和繁殖行为的启发所得…

vue2、vue3各自的响应式原理

查看本专栏目录 关于作者 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#x…

.[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞

有朋友oracle数据库所在机器被加密,扩展名为&#xff1a;.[hudsonLcock.li].mkp,数据文件类似&#xff1a; 通过专业工具分析,确认这次运气非常好,每个文件就加密破坏前面31个block 通过研发的Oracle数据文件勒索恢复工具进行恢复 顺利数据库并且导出数据 mkp勒索病毒预…

R绘图 | 单列数据的分布图,对A变量分bin求B变量的平均值

问题1&#xff1a;单个向量的 density 分布图&#xff1f; (1) 模拟数据 set.seed(202402) datdiamonds[sample(nrow(diamonds), 1000),]> head(dat) # A tibble: 6 10carat cut color clarity depth table price x y z<dbl> <ord> &l…

★【递归】【构造二叉树】Leetcode 106.从中序与后序遍历序列构造二叉树

★【递归】【构造二叉树】Leetcode 106.从中序与后序遍历序列构造二叉树 105. 从前序与中序遍历序列构造二叉树 106.从中序与后序遍历序列构造二叉树:star:思路分析递归解法 105. 从前序与中序遍历序列构造二叉树递归解法 ---------------&#x1f388;&#x1f388;题目链接&a…

python Matplotlib Tkinter-->tab切换3

环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 pillow 10.1.0 import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk import tkinter as tk import tkinter.messagebox as messagebox import …

学成在线_课程计划查询_前端页面无法跳转

问题描述 在进行课程计划查询的接口开发时通过了http-client测试但点开课程修改界面后点击保存并进行下一步时无法跳转到修改课程计划查询的页面。 问题原因 课程信息修改的Controller层没有实现 QAQ&#xff08;可能是老师在讲这一块的时候没有提这一点&#xff08;我也记…

数据脱敏(八)静态脱敏

HuggingFists低代码平台提供Mysql,Postgresql,Oracle,ClickHouse等多种数据库连接插件及配套读写算子。提供ftp,sftp,百度盘&#xff0c;阿里云文件系统&#xff0c;腾讯文件系统等多种文件系统连接插件及配套读写算子。满足用户静态脱敏场景下各种数据源要求。 静态脱敏-数据库…

6.Z字形变换

题目&#xff1a;s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 "PAYPALISHIRING" 行数为 3 时&#xff0c;排列如下&#xff1a; 之后&#xff0c;你的输出需要从左往右逐行读取&#xff0c;产生出一个新的字符串&a…