主要针对 stm32f103RGB初始化程序(1)优化了:
在lec.c中RGB对应引脚的初始化函数,将三个函数合为一个。
在led.h中添加了三个引脚对应的枚举值。
在led.h中新增了一些宏。
修改了函数名,以及使用方法。
脱离了硬件层,实现软件层编程。
增加了代码的可读性,可移植性。
main.c
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
int main(void) {
//来到这里的时候,系统时钟已经被配置成72M
RGB_GPIO_Config(RGB_R); // 初始化红色 LED
RGB_GPIO_Config(RGB_G); // 初始化绿色 LED
RGB_GPIO_Config(RGB_B); // 初始化蓝色 LED
RGB_ON(RGB, RED);
RGB_OFF(RGB,RED);
RGB_ON(RGB,BLUE);
RGB_OFF(RGB,BLUE);
RGB_ON(RGB,GREEN);
// RGB_OFF(RGB,GREEN);
}
led.h
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
#define RED GPIO_Pin_5
#define BLUE GPIO_Pin_1
#define GREEN GPIO_Pin_0
#define RGB GPIOB
#define RGB_ON(Port, color) GPIO_ResetBits(Port, color)
#define RGB_OFF(Port, color) GPIO_SetBits(Port, color)
/*
#define LED_OFF(A, B) GPIO_ResetBits(A, B)
#define LED_OFF(GPIOx, GPIO_PIN) GPIO_ResetBits(GPIOx, GPIO_PIN)
都可以,效果一样,前后对应即可
#define LED_OFF(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
这个不行,要改成下面这个
#define LED_OFF(GPIOx, GPIO_Pin) GPIO_ResetBits(GPIOx, GPIO_Pin
在这个宏定义中,我们去掉了参数列表中的类型声明,只保留了参数名。
这样做是因为在宏定义中,我们只需要指定参数的名字而不需要具体的类型。
参数的类型应该在调用宏的地方指定。
请注意,宏定义中的参数名 GPIOx 和 GPIO_Pin 只是标识符,
用于在宏调用时接收传递的实际参数。
在调用宏的时候,你需要传递正确的参数,即正确的 GPIO 引脚和引脚编号。
*/
/*#define: 这是宏定义的关键字,它告诉编译器后面是一个宏定义。
LED_OFF: 这是宏的名称,你可以根据需要给宏取一个有意义的名称。
在这个例子中,我们将宏定义为 LED_OFF,表示用于熄灭 LED。
(A, B): 这是宏的参数列表,宏可以接受多个参数,用逗号分隔。
在这个例子中,宏有两个参数 A 和 B。这些参数是占位符,
用于在宏被调用时接收传递的实际参数。
GPIO_ResetBits(A, B): 这是宏的替换文本。宏在被调用时,
会将参数 A 和 B 替换到这里。
在这个例子中,GPIO_ResetBits(A, B) 表示调用了 GPIO_ResetBits 函数,
其中 A 和 B 分别替换为宏被调用时传递的实际参数。
通过这个宏定义,你可以在代码中使用 LED_OFF(GPIOx, GPIO_Pin)
来熄灭 LED。在实际调用宏时,
预处理器会将 GPIOx 和 GPIO_Pin 替换为宏定义中的 A 和 B 参数,
然后展开成 GPIO_ResetBits(GPIOx, GPIO_Pin),
从而实现了简便的 LED 熄灭操作。
*/
typedef enum {
RGB_R,
RGB_G,
RGB_B,
// 可以添加其他 LED 类型
} RGB_Type;
void RGB_GPIO_Config(RGB_Type RGBType);
#endif /*__BSP_LED_H*/
关于:
typedef enum {
RGB_R,
RGB_G,
RGB_B,
// 可以添加其他 LED 类型
} RGB_Type;
这段代码定义了一个枚举类型 RGB_Type
,用于表示不同颜色的 RGB LED 类型。枚举类型是一种用户自定义的数据类型,它允许你在代码中使用易读的符号来代表特定的值。在这个特定的情况下,RGB_Type
枚举用于区分不同颜色的 RGB LED。
在定义中,RGB_R
、RGB_G
和 RGB_B
是枚举的三个值,分别表示红色、绿色和蓝色的 LED 类型。你可以通过这些符号来指定你希望初始化和控制的不同颜色的 RGB LED。这样,当在代码中使用 RGB_R
时,实际上代表的是数字 0(默认从 0 开始递增),当你使用 RGB_G
时,代表的是数字 1,以此类推。
通过使用枚举类型,可以提高代码的可读性和易用性,因为使用可读的符号比使用数字更加直观和易于理解。在这种情况下,RGB_Type
枚举可以帮助识别和区分不同颜色的 RGB LED,使代码更具有可维护性。
led.c
#include "led.h"
void RGB_GPIO_Config(RGB_Type RGBType) {
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
if (RGBType == RGB_R) {
GPIO_InitStruct.GPIO_Pin = RED;
} else if (RGBType == RGB_G) {
GPIO_InitStruct.GPIO_Pin = GREEN;
} else if (RGBType == RGB_B) {
GPIO_InitStruct.GPIO_Pin = BLUE;
}
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
RGB_OFF(RGB,GPIO_InitStruct.GPIO_Pin);// 电路原因,让灯不会因为 GPIO 引脚初始化而亮
}
这里主要讲解led.c里面的内容
这段代码用于初始化不同颜色的 RGB LED,并在初始化后将其熄灭。下面是代码的逐步解释:
void RGB_GPIO_Config(RGB_Type RGBType) {
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
这部分代码定义了一个函数 RGB_GPIO_Config
,它接受一个参数 RGBType
,表示要初始化的 RGB LED 类型。然后创建了一个名为 GPIO_InitStruct
的结构体,用于配置 GPIO 引脚。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
这行代码开启了 GPIOB 的时钟,以便在初始化时使用。
if (RGBType == RGB_R) {
GPIO_InitStruct.GPIO_Pin = RED;
} else if (RGBType == RGB_G) {
GPIO_InitStruct.GPIO_Pin = GREEN;
} else if (RGBType == RGB_B) {
GPIO_InitStruct.GPIO_Pin = BLUE;
}
这一部分根据传递给函数的 RGBType
参数,设置了对应颜色的引脚。假设 RED
、GREEN
和 BLUE
分别表示红色、绿色和蓝色的引脚。
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
这部分配置了 GPIO 引脚的模式为推挽输出(GPIO_Mode_Out_PP
)和输出速度为 50MHz。然后使用 GPIO_Init
函数将配置应用于 GPIOB 引脚。
RGB_OFF(RGB, GPIO_InitStruct.GPIO_Pin); // 电路原因,让灯不会因为 GPIO 引脚初始化而亮
}
最后,这行代码调用了 RGB_OFF
宏来将初始化后的引脚熄灭。这里的 RGB_OFF
宏与led.h定义的宏相对应,用于将指定的颜色引脚设置为低电平,以避免初始化引脚时灯亮起。
总的来说,lec.c里代码的作用是根据传入的 RGB 类型初始化对应颜色的 LED 引脚,然后将引脚设置为熄灭状态。