STM32红牛开发板上的5个LED,接在GPIOF6~10脚,输出低电平时,LED亮。这样我们设置GPIOF的相关寄存器,让其输出低电平就可以让LED亮。因为没有用到ST提供的固件库,所以是直接对寄存器的内存地址读写,即对一个指向该地址的指针变量进行读写。并且该变量必须为易变型的,即用volatile定义,这样是为了告诉编译器不要去优化这个变量,导致其它一些寄存器的数据变化。GPIOx是挂载在APB2高速外设总线上的,最大频率是72MHZ,所以我们除了了打开HSE(外部高速时钟)并关闭内部高速时钟(开机默认选择了HSI)外,还要打开APB2总线的时钟。
一、 寄存器地址映射
外设的基址PERIPH_BASE 为0x40000000,APB1外设在前面,所以基址APB1PERIPH_BASE等于PERIPH_BASE,APB2外设基址APB2PERIPH_BASE为PERIPH_BASE + 0x10000,最后AHB基址是PERIPH_BASE + 0x20000.
GPIOx是挂载在APB2总线了的,从(APB2PERIPH_BASE + 0x0800)开始,每0x400字节空间为一组IO口的寄存器。所以GPIOF_BASE为(APB2PERIPH_BASE + 0x1C00)。结合芯片手册,GPIOF各寄存器地址如下:
/***********GPIOF外设寄存器地址映射********************/
#define GPIOF_CRL (*(volatile unsigned long *) (GPIOF_BASE + 0x00))
#define GPIOF_CRH (*(volatile unsigned long *) (GPIOF_BASE + 0x04))
#define GPIOF_IDR (*(volatile unsigned long *) (GPIOF_BASE + 0x08))
#define GPIOF_ODR (*(volatile unsigned long *) (GPIOF_BASE + 0x0C))
#define GPIOF_BSRR (*(volatile unsigned long *) (GPIOF_BASE + 0x10))
#define GPIOF_BRR (*(volatile unsigned long *) (GPIOF_BASE + 0x14))
#define GPIOF_LCKR (*(volatile unsigned long *) (GPIOF_BASE + 0x18))时钟控制寄存器基址RCC_BASE 为(AHBPERIPH_BASE + 0x1000),由同样方法可以得出RCC各寄存器地址如下:
/****************RCC寄存器地址映射*******************/
#define RCC_CR (*(volatile unsigned long *) (RCC_BASE + 0x00))
#define RCC_CFGR (*(volatile unsigned long *) (RCC_BASE + 0x04))
#define RCC_CIR (*(volatile unsigned long *) (RCC_BASE + 0x08))
#define RCC_APB2RSTR (*(volatile unsigned long *) (RCC_BASE + 0x0C))
#define RCC_APB1RSTR (*(volatile unsigned long *) (RCC_BASE + 0x10))
#define RCC_AHBENR (*(volatile unsigned long *) (RCC_BASE + 0x14))
#define RCC_APB2ENR (*(volatile unsigned long *) (RCC_BASE + 0x18))
#define RCC_APB1ENR (*(volatile unsigned long *) (RCC_BASE + 0x1C))
#define RCC_BDCR (*(volatile unsigned long *) (RCC_BASE + 0x20))
#define RCC_CSR (*(volatile unsigned long *) (RCC_BASE + 0x24))至此,得到上面数据,对这些寄存器操作,我们就可以控制红牛开板的上的5个LED了。
二、 程序编写
1、 启动代码
启动代码直接使用ST提供的默认启动代码,由于我的开发板是大容量FLASH的STM32F103ZET6,所以用的启动代码是startup_stm32f10x_hd.s。
2、 时钟配置RCC_Configuration
跳转到MAIN函数后,程序第一件要做的事情就是配置系统时钟。由HSE直接作为系统时钟。
Void RCC_Configuration()
{
RCC_CR |= (1<<16); // HSE振荡器开启
RCC_CR &= ~(1<<0); // HSI振荡器关闭
RCC_CFGR |= (1<<2); // HSE作为系统时钟
RCC_APB2ENR |= (1<<7); //打开GPIOF端口时钟
}3、 GPIOF配置
GPIOF配置成通用开漏输出模式,代码如下:
void GPIO_Configuration()
{
GPIOF_CRH = 0x11111111; //GPIO 15~8
GPIOF_CRL = 0x11111111; //GPIO 7 ~0
}
4、 GPIO置位/复位
置位/复位功能通过对端口位设置/清除寄存器(GPIOx_BSRR)操作实现,代码如下:
void GPIO_SetBits( u16 GPIO_Pin)
{
GPIOF_BSRR = GPIO_Pin;
}
void GPIO_ResetBits(u16 GPIO_Pin)
{
GPIOF_BSRR = GPIO_Pin<<16;
}三、 总结
此程序只是用来演示脱离ST提供的固件库控制GPIO口输出。通过此程序来入门非固件库的STM32程序设计。
这篇博客介绍了如何在STM32红牛开发板上,不使用ST的固件库,直接通过寄存器操作来控制GPIOF6~10脚上的LED。首先,博主详细讲解了GPIO和RCC寄存器的地址映射,然后提供了时钟配置和GPIO配置的代码,最后通过置位/复位寄存器实现LED的开关控制。

1818

被折叠的 条评论
为什么被折叠?



