寄存器:
软件控制硬件(在程序中操作对应控制器),通过寄存器,就是 寄存器(可以存放数据),但是其中的数据具有特定的硬件含义(查看芯片手册),设置寄存器的值,对应的控制器就执行对应的工作。相当于寄存器就是控制器硬件留给软件的接口
具体操作:
-
寄存器是硬件与软件的接口:
- 寄存器本质上是一个特定地址上的存储单元,它能够存储数据,并且这些数据代表特定的硬件状态或控制指令。硬件厂商在设计芯片时,会为各种外设(如GPIO、UART、SPI等)设计一系列寄存器,每个寄存器内的每一位(bit)或一组位(bits)都具有特定的意义和功能。
- 软件程序通过读写这些寄存器中的数据,控制或获取硬件的状态。
-
寄存器的具体意义由芯片手册定义:
- 芯片手册(例如STM32的参考手册)详细描述了每个寄存器的功能、地址、位的意义以及如何通过设置寄存器来控制硬件的行为。
- 例如,对于STM32中的GPIO寄存器,设置某个位可以使一个引脚工作在输出模式或者输入模式,写入一个寄存器的特定位可以控制引脚的电平高低。
-
寄存器映射到特定的内存地址:
- 在微控制器中,寄存器通常是映射到一个特定的内存地址范围,这称为寄存器地址映射。这些地址通常是固定的,程序通过访问这些地址来读写寄存器。
- 例如,在STM32中,GPIOA端口的寄存器可能映射到内存地址
0x40010800
处。程序可以通过指针或者宏定义访问这些地址。
-
通过寄存器配置控制器:
- 控制器硬件的行为通过寄存器的设置来控制。例如:
- 配置引脚为输入或输出模式(通过GPIO的MODER寄存器)。
- 启动或关闭某个外设(例如通过使能寄存器使能定时器、ADC等)。
- 设置通信协议的波特率、时钟频率等。
通过编写软件来修改寄存器的内容,程序可以控制硬件如何工作。比如:
- 控制GPIO引脚的高低电平,驱动外部LED开关。
- 通过修改ADC配置寄存器,启动模数转换并获取数据。
- 通过USART寄存器,设置串口通信参数并发送数据
- 控制器硬件的行为通过寄存器的设置来控制。例如:
下面以 STM32F103RCT6为例子:
在STM32F103RCT6中,GPIO端口的配置主要通过两个寄存器来控制,分别是GPIO_CRL(低寄存器)和GPIO_CRH(高寄存器)。每个寄存器的每4位对应一个引脚的具体配置,其中包括两位用于设置引脚的模式(MODE),两位用于设置引脚的配置(CNF)。
-
CNFy[1:0](引脚的配置位,分别控制浮空、上拉、开漏等模式):
-
位31:30、27:26、23:22、19:18、15:14、11:10、7:6、3:2:分别对应端口的第7到第0位的配置。
-
这些位的具体配置如下:
-
在输入模式(MODEy[1:0] = 00)下:
- 00:模拟输入模式。
- 01:浮空输入模式(复位后的默认状态)。
- 10:上拉/下拉输入模式(具体选择上拉或下拉取决于GPIO_ODR寄存器)。
- 11:保留(不使用)。
-
在输出模式(MODEy[1:0] > 00)下:
- 00:通用推挽输出模式。
- 01:通用开漏输出模式。
- 10:复用功能推挽输出模式。
- 11:复用功能开漏输出模式。
-
-
-
MODEy[1:0](引脚的模式位,分别控制引脚是输入、输出及输出速度):
-
位29:28、25:24、21:20、17:16、13:12、9:8、5:4、1:0:分别对应端口的第7到第0位的模式。
-
这些位的具体配置如下:
- 00:输入模式(复位后的默认状态)。
- 01:输出模式,最大输出速度为10 MHz。
- 10:输出模式,最大输出速度为2 MHz。
- 11:输出模式,最大输出速度为50 MHz。
-
当然,这只是配置了对应的GPIO模式,并不能设置值,设置值需要通过端口输入数据寄存器(GPIOx_IDR) 端口输出数据寄存器(GPIOx_ODR)
例子:配置 STM32F103 的 PC1 引脚为输入模式,并读取其电平状态;
1. 配置 PC1 为浮空输入模式,并读取电平状态。
步骤:
- 配置 PC1 引脚为浮空输入模式。
- 读取 GPIOC_IDR(输入数据寄存器)的相应位来判断 PC1 引脚的电平状态。
// 配置 PC1 为浮空输入模式
GPIOC->CRL &= ~(0xF << 4); // 清除PC1的 CNF1 和 MODE1 位 (位4~7)
GPIOC->CRL |= (0x4 << 4); // 设置PC1为浮空输入模式 (CNF1 = 01, MODE1 = 00)
// 读取 PC1 的输入电平
uint32_t pc1_state = (GPIOC->IDR & (1 << 1)); // 读取 PC1 的电平状态
if (pc1_state) {
// PC1 是高电平
} else {
// PC1 是低电平
}
- GPIOC->CRL &= ~(0xF << 4);:首先清除 CRL 寄存器中 PC1 引脚的位(第 4 到第 7 位),因为 PC1 对应的是 CNF1 和 MODE1(在 GPIOC_CRL 寄存器中)。
- GPIOC->CRL |= (0x4 << 4);:设置 CNF1[1:0] = 01(浮空输入)和 MODE1[1:0] = 00(输入模式),完成浮空输入模式配置。
- GPIOC->IDR & (1 << 1):读取 GPIOC_IDR 寄存器中 PC1 的状态(第 1 位),如果为 1,表示 PC1 是高电平;如果为 0,表示 PC1 是低电平。
下面用二进制来进行解释:
我们知道:
- 0x4 是十六进制,转换为二进制是
0100
。 - << 4 表示左移 4 位,即将
0100
左移 4 位。
首先,解释 0x4 的具体含义:
- 0x4 的二进制是
0100
,对应的值表示 CNF1[1:0] = 01(浮空输入模式),MODE1[1:0] = 00(输入模式)。
1. 0x4 转换为二进制:
0x4
的二进制形式是:0x4 = 0100(二进制)
左移四位:
0000 0100 << 4 = 0100 0000
假设原来的 GPIOC->CRL 寄存器的二进制值为:
0000 0000 0000 0000 0000 0000 0000 0000
现在我们要将 0100 0000 (即 0x40)按位或到它上面:
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0100 0000 |
=0000 0000 0000 0000 0000 0000 0100 0000
通过左移操作,0x4 被移到了 PC1 对应的位(4-7 位),然后通过按位或将它与 GPIOC_CRL 合并,确保其他位不受影响