目录
1、原理图

如图知,拉低为点亮
-
LED
灯 引脚 状态 D3红 PB5 输出, 拉低为亮 D3绿 PB0 输出, 拉低为亮 D3蓝 PB1 输出, 拉低为亮
2、文件结构

3、使用寄存器模式点亮
3.1、什么是寄存器
寄存器是微控制器(MCU)内部的一种特殊存储器,用于存储配置参数、状态信息或控制信号。每个寄存器通常有固定的地址,并且每一位或一组位对应特定的功能。
3.2、寄存器开发的本质
寄存器开发的本质是直接与硬件交互,绕过高级库(如 HAL 库或标准库)的封装,直接操作底层硬件。
STM32 的寄存器开发是通过直接读写寄存器来实现对外设的控制。
3.3、寄存器开发步骤
(1) 查找寄存器地址
- 根据 STM32 的参考手册(Reference Manual),找到目标外设的寄存器地址。
- 每个外设(如 GPIO、TIMER、USART 等)都有一组寄存器,用于配置和控制其行为。
(2) 配置寄存器
- 通过指针操作或直接访问寄存器地址,向寄存器写入特定的值,以配置外设的工作模式、中断、时钟等。
(3) 读取寄存器
- 通过读取寄存器的值,获取外设的状态信息(如标志位、数据等)。
3.4、主要源码
3.4.1、main.c
c
#include "drv_gpio.h"
// SysTick 初始化
void SysTick_Init(void)
{
SysTick->LOAD = 72000000 / 1000 - 1; // 1ms 延时
SysTick->VAL = 0; // 清空当前值
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk;
}
// 精确延时函数(单位:ms)
void Delay_ms(uint32_t ms)
{
for (uint32_t i = 0; i < ms; i++)
{
while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk))
;
}
}
int main()
{
// 初始化 SysTick
SysTick_Init();
// 初始化 RGB LED
RGB_Init();
while (1)
{
RGB_RedOn();
Delay_ms(500); // 延时 500ms
RGB_RedOff();
RGB_GreenOn();
Delay_ms(500); // 延时 500ms
RGB_GreenOff();
RGB_BlueOn();
Delay_ms(500); // 延时 500ms
RGB_BlueOff();
}
}
3.4.2、drv_gpio.h
c
#ifndef _DRV_GPIO_H_
#define _DRV_GPIO_H_
//ARM提供的,有所有外设寄存器的信息
#include "stm32f10x.h"
void RGB_Init(void);
void RGB_RedOn(void);
void RGB_RedOff(void);
void RGB_GreenOn(void);
void RGB_GreenOff(void);
void RGB_BlueOn(void);
void RGB_BlueOff(void);
#endif
3.4.3、drv_gpio.c
c
#include "drv_gpio.h"
void RGB_Init(void)
{
// 1.配置RCC
RCC->APB2ENR |= (1 << 3);
// 2.配置PB5的功能
// bit 20~23 全部置为0
// bit 20 置为1
//pb5
GPIOB->CRL &= (uint32_t)(~(0xF << 20));
GPIOB->CRL |= (uint32_t)(1 << 20); //配置为通用推挽输出模式(0b0001)
//pb0
GPIOB->CRL &= (uint32_t)(~(0xF));
GPIOB->CRL |= (uint32_t)(1);
//pb1
GPIOB->CRL &= (uint32_t)(~(0xF << 4));
GPIOB->CRL |= (uint32_t)(1 << 4);
// 3.将pb5、pb0、pb1的初始值改为1,防止配置完就亮灯
GPIOB->ODR |= (1 << 5);
GPIOB->ODR |= 1;
GPIOB->ODR |= (1 << 1);
}
void RGB_RedOn(void)
{
// 3.拉低PB5对应的ODR寄存器地址
GPIOB->ODR &= ~(1 << 5);
}
void RGB_RedOff(void)
{
GPIOB->ODR |= (1 << 5);
}
void RGB_GreenOn(void)
{
GPIOB->ODR &= ~(1);
}
void RGB_GreenOff(void)
{
GPIOB->ODR |= 1;
}
void RGB_BlueOn(void)
{
GPIOB->ODR &= ~(1 << 1);
}
void RGB_BlueOff(void)
{
GPIOB->ODR |= (1 << 1);
}
3.4.4、使用BSRR和BRR影子寄存器优化drv_gpio.c
由于对
ODR
直接操作, 可能有意无意修改到其他引脚的状态
c
#include "drv_gpio.h"
void RGB_Init(void)
{
// 1.配置RCC
RCC->APB2ENR |= (1 << 3);
// 2.配置PB5的功能
// bit 20~23 全部置为0
// bit 20 置为1
//pb5
GPIOB->CRL &= (uint32_t)(~(0xF << 20));
GPIOB->CRL |= (uint32_t)(1 << 20); //配置为通用推挽输出模式(0b0001)
//pb0
GPIOB->CRL &= (uint32_t)(~(0xF));
GPIOB->CRL |= (uint32_t)(1);
//pb1
GPIOB->CRL &= (uint32_t)(~(0xF << 4));
GPIOB->CRL |= (uint32_t)(1 << 4);
// 3.将pb5、pb0、pb1的初始值改为1,防止配置完就亮灯
GPIOB->ODR |= (1 << 5);
GPIOB->ODR |= 1;
GPIOB->ODR |= (1 << 1);
}
void RGB_RedOn(void)
{
// 3.拉低PB5对应的ODR寄存器地址
//GPIOB->ODR &= ~(1 << 5);
GPIOB->BRR &= (1 << 5);// 直接将PB5拉低,同时不影响其他位
}
void RGB_RedOff(void)
{
//GPIOB->ODR |= (1 << 5);
GPIOB->BSRR |= (1 << 5); //直接拉高,并不影响
}
void RGB_GreenOn(void)
{
//GPIOB->ODR &= ~(1);
GPIOB->BRR &= (1);
}
void RGB_GreenOff(void)
{
//GPIOB->ODR |= 1;
GPIOB->BSRR |= (1);
}
void RGB_BlueOn(void)
{
//GPIOB->ODR &= ~(1 << 1);
GPIOB->BRR &= (1 << 1);
}
void RGB_BlueOff(void)
{
//GPIOB->ODR |= (1 << 1);
GPIOB->BSRR |= (1 << 1);
}
3.4.5、效果演示

4、使用标准库模式点亮
4.1、使用标准库模式的好处
标准库封装了底层寄存器的操作,提供了易于理解的API函数,开发者无需直接读写寄存器。
4.2、主要源码
4.2.1、main.c
c
#include "drv_gpio.h"
// SysTick 初始化
void SysTick_Init(void)
{
SysTick->LOAD = 72000000 / 1000 - 1; // 1ms 延时
SysTick->VAL = 0; // 清空当前值
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk;
}
// 精确延时函数(单位:ms)
void Delay_ms(uint32_t ms)
{
for (uint32_t i = 0; i < ms; i++)
{
while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk))
;
}
}
int main()
{
// 初始化 SysTick
SysTick_Init();
// 初始化 RGB LED
RGB_Init();
while (1)
{
RGB_RedOn();
Delay_ms(500); // 延时 500ms
RGB_RedOff();
RGB_GreenOn();
Delay_ms(500); // 延时 500ms
RGB_GreenOff();
RGB_BlueOn();
Delay_ms(500); // 延时 500ms
RGB_BlueOff();
RGB_WriteOn();
Delay_ms(500); // 延时 500ms
RGB_WriteOff();
}
}
4.2.2、drv_gpio.h
c
#ifndef _DRV_GPIO_H_
#define _DRV_GPIO_H_
//使用gpio标准库
#include "stm32f10x_gpio.h"
#define RGB_Port GPIOB
#define RGB_Pin_R GPIO_Pin_5
#define RGB_Pin_G GPIO_Pin_0
#define RGB_Pin_B GPIO_Pin_1
void RGB_Init(void);
void RGB_RedOn(void);
void RGB_RedOff(void);
void RGB_GreenOn(void);
void RGB_GreenOff(void);
void RGB_BlueOn(void);
void RGB_BlueOff(void);
void RGB_WriteOn(void);
void RGB_WriteOff(void);
#endif
4.2.3、drv_gpio.c
c
#include "drv_gpio.h"
void RGB_Init(void)
{
// 1.RCC配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// 2、配置红、绿、蓝灯输出
GPIO_InitTypeDef gpio_initStruct = {0};
gpio_initStruct.GPIO_Pin = RGB_Pin_R | RGB_Pin_G | RGB_Pin_B;
gpio_initStruct.GPIO_Speed = GPIO_Speed_50MHz;
gpio_initStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(RGB_Port, &gpio_initStruct);
GPIO_SetBits(RGB_Port, RGB_Pin_R | RGB_Pin_G | RGB_Pin_B);
}
void RGB_RedOn(void)
{
// 3.拉低PB5对应的ODR寄存器地址
GPIO_ResetBits(RGB_Port, RGB_Pin_R);
}
void RGB_RedOff(void)
{
GPIO_SetBits(RGB_Port, RGB_Pin_R);
}
void RGB_GreenOn(void)
{
GPIO_ResetBits(RGB_Port, RGB_Pin_G);
}
void RGB_GreenOff(void)
{
GPIO_SetBits(RGB_Port, RGB_Pin_G);
}
void RGB_BlueOn(void)
{
GPIO_ResetBits(RGB_Port, RGB_Pin_B);
}
void RGB_BlueOff(void)
{
GPIO_SetBits(RGB_Port, RGB_Pin_B);
}
void RGB_WriteOn(void)
{
GPIO_ResetBits(RGB_Port, RGB_Pin_R | RGB_Pin_G | RGB_Pin_B);
}
void RGB_WriteOff(void)
{
GPIO_SetBits(RGB_Port, RGB_Pin_R | RGB_Pin_G | RGB_Pin_B);
}
4.2.4、效果演示多了白灯
