一、了解寄存器
(1)什么是寄存器
????????寄存器是 CPU 内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的指令、数据和地址。就是一种常用的时序逻辑电路 ,但这种时序逻辑电路只包含存储电路。寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器能存储1位二进制数,所以由N个锁存器或触发器可以构成N位寄存器。
(2)什么是寄存器映射
?????????由于存储器本身没有地址,给存储器分配地址的过程就叫存储器映射,在存储器Block2 这块区域,设计的是片上外设,它们以四个字节为一个单元,共32bit,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以找到每个单元的起始地址,然后通过C 语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
二、配置GPIO端口
(1)配置时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //打开外设GPIOB的时钟
(2)GPIO初始化结构体
????????库函数中提供了一个结构体来配置GPIO端口的 输入输出模式设置 、 最大速率设置等
如下
typedef struct
{
uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
(3)配置为通用推挽输出,输出速度为2M
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //输出模式为通用推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1 ; //选定端口为GPIO_Pin_1
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz; //输出速度为2M
GPIO_Init(GPIOB,&GPIO_InitStruct);
?三、简易流水灯设计
(1)代码设计
main.c
#define RCC_AP2ENR *((unsigned volatile int*)0x40021018)
//----------------GPIOA配置寄存器 ------------------------
#define GPIOA_CRH *((unsigned volatile int*)0x40010804)
#define GPIOA_ORD *((unsigned volatile int*)0x4001080C)
//----------------GPIOB配置寄存器 ------------------------
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
#define GPIOB_ORD *((unsigned volatile int*)0x40010C0C)
//----------------GPIOC配置寄存器 ------------------------
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
#define GPIOC_ORD *((unsigned volatile int*)0x4001100C)
//-------------------简单的延时函数-----------------------
void Delay_ms( volatile unsigned int t)
{
unsigned int i;
while(t--)
for (i=0;i<800;i++);
}
//------------------------主函数--------------------------
int main()
{
int j=100;
RCC_AP2ENR|=1<<2; //APB2-GPIOA外设时钟使能
RCC_AP2ENR|=1<<3; //APB2-GPIOB外设时钟使能
RCC_AP2ENR|=1<<4; //APB2-GPIOC外设时钟使能
//这两行代码可以合为 RCC_APB2ENR|=1<<3|1<<4;
GPIOA_CRH&=0xFFF0FFFF; //设置位 清零
GPIOA_CRH|=0x00020000; //PA12推挽输出
GPIOA_ORD|=1<<12; //设置初始灯为亮
GPIOB_CRL&=0xFFFFFF0F; //设置位 清零
GPIOB_CRL|=0x00000020; //PB1推挽输出
GPIOB_ORD|=1<<1; //设置初始灯为灭
GPIOC_CRH&=0xF0FFFFFF; //设置位 清零
GPIOC_CRH|=0x02000000; //PC14推挽输出
GPIOC_ORD|=1<<14; //设置初始灯为灭
while(j)
{
GPIOA_ORD=0x1<<12; //PA12高电平
Delay_ms(3000000);
GPIOA_ORD=0x0<<12; //PA12低电平
Delay_ms(3000000);
GPIOB_ORD=0x1<<1; //PB1高电平
Delay_ms(3000000);
GPIOB_ORD=0x0<<1; //PB1低电平
Delay_ms(3000000);
GPIOC_ORD=0x1<<14; //PC14高电平
Delay_ms(3000000);
GPIOC_ORD=0x0<<14; //PC14低电平
Delay_ms(3000000);
}
}
(2) 开发板线路连接
- USB转TTL模块GND接最小系统板的地
- USB转TTL模块的3v3接最小系统板3v3
- USB转TTL模块的TXD接最小系统板的PA10
- USB转TTL模块的RXD接最小系统板的PA9
- 最小系统板的PA12、PB1、PC14分别接红、黄、绿LED灯的正极,LED灯的负极接地。
?(3)烧录程序
?下面就是流水灯成功gif图片
?四、参考文献
?STM32寄存器流水灯_zxp_124的博客-CSDN博客
?stm32花式点流水灯_星&&河的博客-CSDN博客
STM32寄存器的简介、地址查找,与直接操作寄存器_geekYatao-CSDN博客_stm32寄存器?
STM32从地址到寄存器_geekYatao-CSDN博客_stm32寄存器地址?
|