STM32英文参考手册网盘分享下载:
链接:https://pan.baidu.com/s/10sdOCdVg3AMlXQWM0Cl7TA 提取码:uz52
STM32中文参考手册网盘分享下载:
链接:https://pan.baidu.com/s/1FxLw8jBavi9g4d1EQsnENA 提取码:kf5x

正题引入:

在这里就不去介绍具体的GPIO的原理了,具体的可以下载上述参考手册自己查阅,下面就直接进入正题,控制LED灯,首先确定LED属于输出信号,需要开发板输出电平来对LED灯进行控制,那么我们需要做的分为以下几步:
  1. 首先查看开发板原理图,确定你所需要控制的LED灯位于哪个引脚(当然如果使用的是发光二极管等外部设备呢,也同样是对引脚进行设置)。

从下图可以得到LED1-8的引脚分别为PC0-PC7

esp32dowd_gpio


从下图看出LED需要低电平才可以被点亮

esp32dowd_stm32_02

  1. 查看好所需要配置的GPIO引脚后,再确定引脚所需要的工作模式。例如:是需要输出电平呢,还是推挽输出呢,还是悬空输入呢。这里的LED灯显而易见,肯定是需要开发板给予高低电平才可以使其工作,并且我们这里给其配置为带数字推挽输出。其实这个地方已经可以实现对LED灯进行点亮或者熄灭设置。
    下面分别是GPIOx_CRH和GPIOx_CRL的寄存器原理图
    可以以配置PC0为例:这里是需要给LED配置带数字推挽输出,那么则需要将GPIOx_CRL的MODE0[1:0]=01即输出模式,最大速率为10MHz
    CNF0[1:0]=00 即推挽输出模式
  2. esp32dowd_嵌入式_03

    esp32dowd_stm32_04

  3. 接下来就是需要对上面两步进行程序化,也就是化成程序,比如这个地方需要程序化:
    LED_Init()// 初始化函数
    初始化首先需要开启相应引脚时钟:这里LED对应的是PC引脚,那么需要使能PC引脚的时钟
  4. esp32dowd_arm_05


  5. esp32dowd_嵌入式_06

  6. LED_Control(para1,para2)//LED控制函数
  7. 最后就是应用层main.c的编写,根据需求去完成。

这里分别以HAL库函数版和寄存器版进行举例

HAL库函数版:

LED.c如下(.h文件由自己发挥):

void LED_Init(void) // LED初始化
{
		GPIO_InitTypeDef GPIO_InitStructure ={0};
			
		__HAL_RCC_GPIOC_CLK_ENABLE();
	
		GPIO_InitStructure.Pin = LED1_Pin ;  // LED1_Pin 相当于 PC0
		GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 设置为推挽输出
		GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; // 低速
			
		HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStructure);	
		HAL_GPIO_WritePin(LED_GPIO_Port, LED1_Pin, GPIO_PIN_SET); // 默认输出低电平
		
}
void Led_Ctrl(int No, LED_Staus staus)
{
		switch(No)
		{
			case 1:
			{
				if(staus == LED_ON)  // 开灯
				{
							HAL_GPIO_WritePin(GPIOB, LED_Pin, GPIO_PIN_RESET);
				}
				else                 // 关灯
				{
							HAL_GPIO_WritePin(GPIOB, LED_Pin, GPIO_PIN_SET);
				}	
				break;
			}
			default:
				break;
		}
}

寄存器版:

LED.c如下(.h文件由自己发挥):

void LED_Init(void) // LED初始化
{
		RCC->APB2ENR |= (1 << 4); // 需要左移几位具体需要看前面,寄存器原理图引脚所对应为第几位
								  // 这里PC对应第四位,所以这里左移4
		GPIOC->CRL &= ~ (0xF << 0); // 置为前先清零,养成好习惯,需要左移几位同样是看引脚对应为第几位
		GPIOC->CRL |= 1 << 0; // 设置为推挽输出模式
		GPIOC->BSRR = 1 << 0; // 默认输出高电平	
}
void Led_Ctrl(int No, LED_Staus staus)
{
		switch(No)
		{
			case 1:
			{
				if(staus == LED_ON)  // 开灯
				{
							GPIOC->BRR = 1 << 0; // 开灯
				}
				else                 // 关灯
				{
							GPIOC->BSRR = 1 << 0; // 关灯
				}	
				break;
			}
			default:
				break;
		}
}
需要的函数都写好过后,main.c就由自己组装了,由于不同单片机移植的系统不同,main.c的书写不一样,这里就不一一举例了。是不是看起来很容易理解呢!到这里,关于LED的控制也算是详细的介绍完了,可以相应地增加功能函数来更好的控制LED灯(例如:闪烁多久熄灭灯等,都可以去自己摸索),自己摸索的过程还是很美好的呀!
一起加油吧,有问题都可以在评论区留言呀,会及时回复的!