目录
一、GPIO端口初始化
(一)寄存器
STM32给不同的寄存器分配了不同的地址,在《STM32中文参考手册》中查找地址。
- 找到GPIOX端口的起始地址
由于STM32的每个IO都需要4个位来配置,所以一个32位的寄存器最大只能配置8个IO(32位的单片机的寄存器就是32位的)。STM32中,用端口配置低寄存器(GPIOx_CRL)来配置引脚Px0-Px7, 用端口配置高寄存器(GPIOx_CRH)来配置引脚Px8-Px15。
本次验采用通用推挽输出模式,最高输出时钟频率2Mhz。分别用到A12、B1、C14三个引脚。其中B1属于端口配置低寄存器偏移地址为0x00,C14、A12属于端口配置高寄存器偏移地址为0x04。
- 找到GPIO寄存器中的端口配置低寄存器(GPIOx_CRL) 控制端口低八位IO
- 找到GPIO寄存器中的端口配置高寄存器(GPIOx_CRH) 控制端口高八位IO
- 寄存器配置
//----------------GPIOA配置寄存器 ------------------------
#define GPIOA_CRH *((unsigned volatile int*)0x40010804)
#define GPIOA_ODR *((unsigned volatile int*)0x4001080C)
//----------------GPIOB配置寄存器 ------------------------
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
#define GPIOB_ODR *((unsigned volatile int*)0x40010C0C)
//----------------GPIOC配置寄存器 ------------------------
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
#define GPIOC_ODR *((unsigned volatile int*)0x4001100C)
- 输出模式
GPIOA_CRH&=0xFFF0FFFF; //设置位 清零
GPIOA_CRH|=0x00020000; //PA12推挽输出
GPIOB_CRL&=0xFFFFFF0F; //设置位 清零
GPIOB_CRL|=0x00000020; //PB1推挽输出
GPIOC_CRH&=0xF0FFFFFF; //设置位 清零
GPIOC_CRH|=0x02000000; //PC14推挽输出
(二)使能时钟
- 找到时钟使能寄存器映射基地址
- 找到端口偏移地址以及对应端口所在位置
//----------------APB2使能时钟寄存器 ---------------------
#define RCC_AP2ENR *((unsigned volatile int*)0x40021018)
RCC_AP2ENR|=1<<2; //APB2-GPIOA外设时钟使能
RCC_AP2ENR|=1<<3; //APB2-GPIOB外设时钟使能
RCC_AP2ENR|=1<<4; //APB2-GPIOC外设时钟使能
二、代码
(一)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);
}
}
(二) 接线:
- USB转TTL模块GND接最小系统板的地
- USB转TTL模块的3v3接最小系统板3v3
- USB转TTL模块的TXD接最小系统板的PA10
- USB转TTL模块的RXD接最小系统板的PA9
- 最小系统板的PA12、PB1、PC14分别接红、黄、绿LED灯的正极,LED灯的负极接地。
如图:
下载hex文件需要注意
关于BOOT0、BOOT1引脚的不同组合方式有多种下载方式
BOOT1=x | BOOT0=0 | 从用户闪存启动,这是正常的工作模式。 |
BOOT1=0 | BOOT0=1 | (ISP方式)从系统存储器启动,这种模式启动的程序功能由厂家设置。 |
BOOT1=1 | BOOT0=1 | 从内置SRAM启动,这种模式可以用于调试. |
三、烧录程序
四、实验成果
STM32寄存器的简介、地址查找,与直接操作寄存器_geekYatao-CSDN博客_stm32寄存器
基于汇编和C语言STM32流水灯依次闪烁_Laul Ken-Yi的博客-CSDN博客
STM32从地址到寄存器_geekYatao-CSDN博客_stm32寄存器地址