STM32学习笔记1:寄存器的学习和使用

本文详细介绍了STM32F103RC单片机的存储器映射,包括ROM和RAM的区分,以及如何通过C语言操作寄存器,如GPIO的配置和位操作。重点讲解了如何使用STM32的标准外设库进行硬件编程,包括外设时钟的开启和GPIO模式的设置。
摘要由CSDN通过智能技术生成

芯片型号:STM32F103RC

软件开发包:标准外设库

一、存储器映射

存储器本身不具有地址信息,它的地址是由芯片厂商和用户分配,给存储器分配地址的过程就称为存储器映射,再分配一个地址叫重映射。

计算机五大基本部分:运算器、控制器、存储器、输入设备和输出设备。运算器和控制器合称为 CPU(中央处理器),而存储器扮演着存储数据和指令的角色。输入输出设备则负责与外部环境进行交互。

而单片机是一种集成了微处理器(通常包括 CPU)、存储器和输入输出设备等基本功能于一块芯片上的微型计算机系统。

存储器有两个重要方面,即存储器的内容和地址。存储器内容是指存储在存储器中的数据或指令,而存储器地址则是唯一标识存储器中特定位置的位置值。

存储器映像

如图,存储器从物理特性和用途方面分成两大类,即 ROM 和 RAM。ROM 是只读存储器,是一种非易失性、掉电不丢失数据的存储器;RAM 是随机存储器,是一种易失性、掉电丢失数据的存储器。

在STM32中,ROM 又分为 3 块。第一块是程序存储器 Flash,也就是主闪存,用于存储编译后的程序,也就是下载程序的位置,相当于电脑的硬盘。运行程序,一般也是从主闪存里面开始运行。第二块是系统存储器,里面存的是自举加载程序(BootLoader),用于串口下载,用户无法修改。第三块是选项字节,主要存储 Flash 的读写保护、看门狗等的配置参数。

RAM 也分为 3 块。第一块是运行内存 SRAM,用于存储运行时的变量和数据,包括在程序中定义的变量、数组和结构体,相当于电脑的内存条。第二块是外设寄存器,用于存储各个外设的配置参数,也就是初始化外设最终所读写的内容。第三块是内核外设寄存器,用于存储内核各个外设的配置参数。

二、寄存器和寄存器映射

寄存器就是有特定功能的内存单元,所以寄存器可以看作是一种特殊的存储器。

给已经分配好地址的具有特定功能的内存单元取别名的过程叫寄存器映射。

三、C语言对寄存器的封装

  1. 找到总外设基地址;
  2. 根据需要,在总外设基地址的基础上,通过偏移量寻址找到对应的总线基地址;
  3. 在总线基地址的基础上,通过偏移量寻址找到对应的外设基地址;
  4. 最后,在外设基地址的基础上通过偏移量寻址找到对应的寄存器基地址。

以 GPIOC 的寄存器为例:

// 1.找到总外设基地址
#define PERIPH_BASE           ((uint32_t)0x40000000)
// 2.找到对应的总线基地址
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
// 3.找到对应的外设基地址
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)
// 4.找到寄存器地址, 强制转换成指针
#define GPIOC_CRL 	*(unsigned int*)(GPIOC_BASE+0x00)
#define GPIOC_CRH 	*(unsigned int*)(GPIOC_BASE+0x04)
#define GPIOC_IDR 	*(unsigned int*)(GPIOC_BASE+0x08)
#define GPIOC_ODR 	*(unsigned int*)(GPIOC_BASE+0x0C)
#define GPIOC_BSRR 	*(unsigned int*)(GPIOC_BASE+0x10)
#define GPIOC_BRR 	*(unsigned int*)(GPIOC_BASE+0x14)
#define GPIOC_LCKR 	*(unsigned int*)(GPIOC_BASE+0x18)

这里只是提供一个大致的思路,与实际的STM32标准库的封装并不完全一致。

四、修改寄存器的位操作方法

4.1 把某位清零
a &=  ~(1 << bitNum);
  • bitNum表示位数,从0位开始,需要对哪一位清零,bitNum就设为该位数。
4.2 对某几个连续位清零
a &= ~(value << bitNum * group);
  • group为组编号(从0开始)
  • bitNum为每组的位数
  • value为组内所有位都为1时的值
4.3 对某位置位
a |= (1 << bitNum);
4.4 对某几位进行置位
a |= (value << bitNum * group);
4.5 对某位取反
a ^= (1 << bitNum);

五、直接操控寄存器配置GPIO

5.1 GPIO输出初始化顺序
  1. 选定具体的GPIO,并打开其对应时钟
  2. 配置GPIO工作模式(CRL和CRH寄存器)
  3. 控制GPIO输出高低电平(ODR、BRR和BSRR)
5.2 开启外设时钟

由于 STM32 的外设很多,为了降低功耗,每个外设都对应着一个时钟,在芯片刚上电的时候这些时钟都是被关闭的,如果想要外设工作,必须把相应的时钟打开。

STM32 的所有外设的时钟由一个专门的外设来管理,叫 RCC(reset and clockcontrol),在这里我们配置的是PC2端口,所有的 GPIO 都挂载到 APB2 总线上,所以我们通过对 RCC 中相应的寄存器赋值来打开对应的时钟。

// 开启 GPIOC 端口 时钟
RCC_APB2ENR |= (1 << 4);

APB2外设时钟使能寄存器

5.3 GPIO模式

每种GPIO都有16个引脚,前8个引脚由端口配置低寄存器 CRL 设置。MODE位用来配置输出的速度, CNF 位用来配置各种输入输出模式。在这里我们把 GPIO 引脚配置为通用推挽输出,输出的速度为 10M。

// 清空控制 PC2 的端口位
GPIOC_CRL &= ~( 0x0F << (4 * 2));
// 配置 PC2 为通用推挽输出,速度为 10M
GPIOC_CRL |= (1 << 4 * 2);

端口配置低寄存器

5.4 控制引脚输出电平

在输出模式时,对端口位设置/清除寄存器 BSRR 寄存器、端口位清除寄存器 BRR 和 ODR 寄存器写入参数即可控制引脚的电平状态,其中操作 BSRR 和 BRR 最终影响的都是 ODR 寄存器,然后再通过 ODR 寄存器的输出来控制 GPIO。为了一步到位,我们在这里直接操作 ODR 寄存器来控制 GPIO 的电平。

// PC2 输出低电平
GPIOC_ODR &= ~(1 << 2);

端口输出数据寄存器

参考视频源于B站up主:野火科技、江协科技
参考文档:《STM32库开发实战指南——基于野火MINI开发板》

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值