背景描述:
最近用32开发遇到问题不得不看寄存器了,就回顾了一下寄存器手册的查看方式和寄存器的使用方法;
上一次这么细致的记录还是在刚学习STM32的时候,之前觉得看寄存器手册以及配置寄存器是有点难度的事情,现在回头看已经是轻舟已过万重山了。**
言归正传:
经常查看的是《STM32F407中文手册》,这个手册很重要!
实验目的:GPIOA_pin6配置为“推挽输出模式+25MHZ”实现LED闪烁效果;
业务流程:
///
一,目的:通过实验学会查看寄存器手册,学会通过寄存器驱动MCU
1)下图是手册中对于GPIO输出的描述
2)在10类GPIO寄存器中选择需要配置的部分
3)注意时钟也要配置
二,实验现象:PA6连接的LED闪烁
三,实验步骤:
1-查看《STM32F407中文手册(完全版) 高清完整pdf版》和《Cortex-M4权威指南(英文版)》
获取以下信息:
1)寄存器映射框图
2)时钟总线框图
3)详细的寄存器地址范围
4)RCC时钟部分的寄存器功能
5)GPIO寄存器部分的功能
2-得到的必要信息
0)配置GPIO之前要开AHB1时钟(GPIOA挂载在AHB1总线下,所以开这个时钟)
1)寄存器映射框图
2)时钟总线框图和内部总线框图
3)详细的寄存器地址范围
4)RCC时钟部分的寄存器功能【重要】
5)GPIO寄存器部分的功能【重要】
a)怎样设置寄存器把PA6设置为输出模式
b)怎样把PA6设置为推挽模式
c)怎样设置速度为25MHZ
d)怎样输出高电平
e)输出低电平
f)电平转换
//代码///
1-用这个函数代替HAL库的GPIOA_pin6的初始化
#define DEBUG_RCC_BASE 0x40023800 //RCC基地址
#define DEBUG_RCCAHB1_Offset 0x30 //AHB1寄存器偏移地址
#define DEBUG_GPIOA_BASE 0x40020000 //GPIOA基地址
#define DEBUG_GPIOA_MODE_Offset 0x00 //GPIOA模式寄存器偏移地址
#define DEBUG_GPIOA_OTYPER_Offset 0x04 //GPIOA输出类型寄存器偏移地址
#define DEBUG_GPIOA_SPEED_Offset 0x08 //GPIOA速度寄存器偏移地址
void DEBUG_GPIOA_INIT(void)
{
//使用寄存器点亮LED
//1-start_AHB1_RCC for GPIOA
//2-set PA6 to output mode
//3-set PA7 to GPIO_MODE_OUTPUT_PP mode
//4-set PA6 to 25MHZ speed
//5-set PA7 to GPIO_PULLUP mode
//6-set PA6 to HIGH level
//注意:这里的地址是0x40023830(单片机不认识这个数字),要强制转化为指针才能识别为地址
unsigned int *P_RCC_AHB1_GPIOA = (unsigned int*)(DEBUG_RCC_BASE + DEBUG_RCCAHB1_Offset);//把数字强制转化为mcu认识的类型
*(P_RCC_AHB1_GPIOA) = *(P_RCC_AHB1_GPIOA) | (1<<0);//0x40023810地址里的bit0的值置为1;
//设置PA6为输出模式
unsigned int *P_GPIOA_MODE = (unsigned int*)(DEBUG_GPIOA_BASE + DEBUG_GPIOA_MODE_Offset);
*(P_GPIOA_MODE) &= ~(0x03 << 12);//输出模式为推挽输出(写零)//0x03:0000 0011;这个操作是把bit12,bit13置为0,
*(P_GPIOA_MODE) = *(P_GPIOA_MODE) | (1<<12);//通用输出模式//bit13,bit12 值为00--->把bit12置为1,---->bit13,bit12 值变为01
//设置PA6的输出模式为推挽输出
unsigned int *P_GPIOA_OTYPER = (unsigned int*)(DEBUG_GPIOA_BASE + DEBUG_GPIOA_OTYPER_Offset);
*(P_GPIOA_OTYPER) &= ~(0x01 << 6);//输出模式为推挽输出(写零)//0x01:0000 0001;这个操作是把bit12置为0,
unsigned int *P_GPIOA_SPEED = (unsigned int*)(DEBUG_GPIOA_BASE + DEBUG_GPIOA_SPEED_Offset);
*(P_GPIOA_OTYPER) &= ~(0x03 << 12);//速度设置为25MHZ(bit12,bit13写零)//0x03:0000 0011;这个操作是把bit12,bit13置为0
}
2-GPIOA_pin6输出高电平
void DEBUG_GPIOA_SET1(void)
{
unsigned int *P_GPIOA_ODR = (unsigned int*)(DEBUG_GPIOA_BASE + 0x14);
*(P_GPIOA_ODR) |= (1<<6);
}
3-GPIOA_pin6输出低电平
void DEBUG_GPIOA_SET0(void)
{
unsigned int *P_GPIOA_ODR = (unsigned int*)(DEBUG_GPIOA_BASE + 0x14);
*(P_GPIOA_ODR) &= ~(1<<6);
}
4-GPIOA_pin6电平反转
void DEBUG_GPIOA_TOGGLE(void)
{
unsigned int *P_GPIOA_ODR = (unsigned int*)(DEBUG_GPIOA_BASE + 0x14);
*(P_GPIOA_ODR) ^= (1<<6);
}
5-整体逻辑
1)main函数中用DEBUG_GPIOA_INIT();代替MX_GPIO_Init();
2)while(1)里添加电平反转,验证LED闪烁的功能;