这是我板子上的RGB灯的引脚图,可以看到对应的引脚配置成0,对应的灯即可亮起
例如:
PB5输出0(其他都不输出或者输出1)那么LED_R就会亮起,RGB灯发出红色的光。
PB0输出0(其他都不输出或者输出1)那么LED_G就会亮起,RGB灯发出绿色的光。
PB1输出0(其他都不输出或者输出1)那么LED_B就会亮起,RGB灯发出蓝色的光。
首先第一步是进行引脚的初始化:
void LED_GPIO_Config(void){
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,ENABLE);
GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN|LED_B_GPIO_PIN|LED_R_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
}
函数第一条程序
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitTypeDef
是一个结构体类型,用于配置 STM32F103 系列芯片的 GPIO 端口。在上述代码中,GPIO_InitStruct
是一个变量,用于保存 GPIO 端口的配置信息。
在使用 GPIO_InitTypeDef
结构体前,你需要先声明一个 GPIO_InitTypeDef
类型的变量(这里声明为GPIO_InitStruct),并填充相应的成员信息来配置 GPIO 端口。
GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
然后,通过调用 GPIO_Init()
函数来将配置应用到相应的 GPIO 端口。
第二条程序
RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,ENABLE);
在这行代码中,RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);
用于使能 STM32F103 系列芯片的 APB2 总线上的 GPIOB 端口的时钟。
RCC
是 STM32F103 系列芯片中的时钟控制寄存器(RCC - Reset and Clock Control),用于配置和控制芯片的时钟。APB2
是 STM32F103 系列芯片的外设总线,其中包含了一些重要的外设如GPIO、USART、SPI、ADC等。
在这行代码中,RCC_APB2PeriphClockCmd()
函数是一个库函数,用于配置 APB2 总线上的外设时钟使能。
LED_G_GPIO_CLK
是一个宏,它表示用于连接绿色LED的GPIO引脚(GPIOB Pin 0)所对应的时钟使能位。
#define LED_G_GPIO_CLK RCC_APB2Periph_GPIOB
RCC_APB2Periph_GPIOB
是一个宏定义,用于表示 STM32F103 系列芯片中的外设总线 APB2 上 GPIOB 端口的时钟使能位。
ENABLE
是一个宏,它表示要使能相关外设的时钟。在使用这个宏时,需要包含相关头文件,例如:#include "stm32f10x_rcc.h"
。
通过调用 RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);
将绿色LED所连接的GPIO引脚的时钟使能,从而使得该GPIO引脚可以正常工作。
需要注意的是,在使用GPIO引脚之前,需要先使能相应GPIO端口的时钟,以便该GPIO端口可以正常工作。否则,如果GPIO端口的时钟未使能,将无法对GPIO进行配置和控制。
GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN|LED_B_GPIO_PIN|LED_R_GPIO_PIN;
在这行代码中,GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN | LED_B_GPIO_PIN | LED_R_GPIO_PIN;
使用了位或(|
)操作符。位或操作符用于将两个二进制数的对应位进行逻辑或运算。
当使用位或操作符 |
将这三个宏的值组合在一起时,对应的位会进行逻辑或运算,形成一个新的二进制数。在这里,结果是将三个LED引脚对应的位设置为1,而其他位保持为0。
最终,将结果赋值给 GPIO_InitStruct.GPIO_Pin
,以便同时配置这三个LED引脚的工作模式。
通过使用位或操作符,我们可以轻松地组合多个引脚,方便一次性配置多个引脚的状态。这在一些情况下非常实用,特别是当多个引脚需要进行相同的配置时。
这里利用我们用|来同时设置多个引脚,一同配置成推挽输出模式,并且输出速度为50MHZ
#define ON 1 //亮输出低电平
#define OFF 0 //灭输出高电平
// \C语言里面的续行符,后面不能有任何东西
#define LED_G(a) if(a) \
GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);\
else GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
这段代码定义了一个宏 LED_G(a)
,用于控制绿色LED引脚的亮灭状态。宏的定义使用了条件编译,通过传入的参数 a
的值来决定是将绿色LED引脚设置为低电平(亮)还是高电平(灭)。
在这段宏定义中,GPIO_ResetBits()
和 GPIO_SetBits()
是 STM32 固件库中的函数,用于控制 GPIO 引脚的状态。
LED_G(a)
: 这是一个宏定义的名称,其中的 a
是传入的参数,用于控制绿色LED引脚的状态。
//int main中这样来赋值
LED_G(ON);
if(a)
: 这是一个条件语句,如果传入的参数 a
是非零(即为真),则执行下面的语句块,否则执行 else
后面的语句块。
GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN)
: 这是一个函数调用,用于将绿色LED引脚的状态设置为低电平,即将引脚置为亮。
GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN)
: 这也是一个函数调用,用于将绿色LED引脚的状态设置为高电平,即将引脚置为灭。
综合来看,宏 LED_G(a)
的作用是根据传入的参数 a
的值,决定将绿色LED引脚设置为亮(低电平)还是灭(高电平)。当传入的参数 a
为真(非零)时,绿色LED亮起;当传入的参数 a
为假(零)时,绿色LED熄灭。
这样,通过调用 LED_G(ON)
和 LED_G(OFF)
宏,可以方便地控制绿色LED的亮灭状态。
类似地,你可以根据需要定义 LED_R(a)
和 LED_B(a)
宏来控制红色和蓝色LED的亮灭状态。
#define LED_R(a) if(a)\
GPIO_ResetBits(GPIOB, LED_R_GPIO_PIN);\
else GPIO_SetBits(GPIOB,LED_R_GPIO_PIN);
#define LED_B(a) if(a)\
GPIO_ResetBits(GPIOB, LED_B_GPIO_PIN);\
else GPIO_SetBits(GPIOB,LED_B_GPIO_PIN);
清除函数
void qc(void){
LED_G(OFF);
LED_R(OFF);
LED_B(OFF);
}
这个函数可以一次性熄灭所有的灯都输出高电平,来让RGB灯处于熄灭状态。
以下是三个完整的程序文件(注意bsp_led.h头文件路径的添加)
main.c
#include "stm32f10x.h"
#include "bsp_led.h"
void delay(uint32_t count)
{
for(;count!=0;count--);
}
int main(void) {
//来到这里的时候,系统时钟已经被配置成72M
LED_GPIO_Config();
qc();
while(1){
LED_R(ON);
delay(0XFFFFF);
qc();
delay(0XFFFFF);
LED_G(ON);
delay(0XFFFFF);
qc();
delay(0XFFFFF);
LED_B(ON);
delay(0XFFFFF);
qc();
delay(0XFFFFF);
}
}
bsp_led.c
//bsp : board support package 板级支持包
#include "bsp_led.h"
void LED_GPIO_Config(void){
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,ENABLE);
GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN|LED_B_GPIO_PIN|LED_R_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
}
void qc(void){
LED_G(OFF);
LED_R(OFF);
LED_B(OFF);
}
bsp_led.h
#ifndef __BSP_LED_H
#define __BSP_LED_H
#include "stm32f10x.h"
#define LED_G_GPIO_PIN GPIO_Pin_0
#define LED_G_GPIO_PORT GPIOB
#define LED_G_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_B_GPIO_PIN GPIO_Pin_1
#define LED_R_GPIO_PIN GPIO_Pin_5
#define ON 1 //亮输出低电平
#define OFF 0 //灭输出高电平
// \C语言里面的续行符,后面不能有任何东西
#define LED_G(a) if(a) \
GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);\
else GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
#define LED_R(a) if(a)\
GPIO_ResetBits(GPIOB, LED_R_GPIO_PIN);\
else GPIO_SetBits(GPIOB,LED_R_GPIO_PIN);
#define LED_B(a) if(a)\
GPIO_ResetBits(GPIOB, LED_B_GPIO_PIN);\
else GPIO_SetBits(GPIOB,LED_B_GPIO_PIN);
void LED_GPIO_Config(void);
void qc(void);
#endif /*__BSP_LED_H*/
//在C语言同一个函数或者变量不能被两次编译所以要用到#ifndef
//使用固件库编程的方式,把剩下的两个灯也点亮,并实现流水灯的形式