【STM32】【CubeMX】引脚GPIO输出操作点亮一颗LED

本文介绍STM32微控制器的LED控制方法,包括使用HAL库进行GPIO操作、按键消抖处理及通过按键控制LED灯的开关等功能实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

原理图

标准库代码

函数说明

HAL库 --- 硬件抽象层

学习视频:

CubeMx时钟树的配置:

按键

蓝桥杯嵌入式组点灯大师

LED控制函数

main函数


原理图

R1是限流电阻

PB5引脚 输出低电平0,相当于接地了,LED导通->发光二极管发光

不同的发光二极管压降也不同

发光二极管包括可见光、不可见光、激光等不同类型,这里只用到可见光发光二极管。发光二极管的发光颜色决定于所用材料,目前有红、绿、黄、橙等色,可以支撑各种形状,如长方形、圆形等。

发光二极管也具有单向导电性。只有外加的正向电压使得正向电流足够大时才发光,它的开启电压比普通二极管大,红色的在1.6~1.8V之间,绿色的约为2V,正向电流愈大,发光愈强。使用时,应特别注意不要超过最大功耗、最大正向电流和反向击穿电压等极限参数。

发光二极管因驱动电压低、功耗小、寿命长、可靠性高等优点广泛应用于显示电路中。目前已有高强度、颜色可变的新产品,用于装饰、显示屏、汽车尾灯、照明,等等。

根据编程习惯,先创建LED.c  LED.h文件

LED.c 存放在 Public\src文件中

LED.h 存放在  Public\inc文件中


标准库代码

#include "LED.h"

void LED_Init(void)
{
	//点亮PB5	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitTypeDef GPIO_InitStructure;	//初始化结构体
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_ResetBits(GPIOB, GPIO_Pin_5);	//置低电平
}

void LED_onoff(void)
{
	GPIO_ResetBits(GPIOB, GPIO_Pin_5);//低电平,亮
	
	// GPIO_SetBits(GPIOB, GPIO_Pin_5);//低电平,灭
	
}

函数说明

HAL库 --- 硬件抽象层

先掌握两个GPIO输出的HAL库函数

void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

GPIO电平输出HAL库函数

void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

理解三个参数:

1 - GPIOx:目标引脚的端口号

2 - GPIO_Pin:目标引脚的引脚号

3 - PinState:高电平GPIO_PIN_SET;低电平GPIO_PIN_RESET

例:将PC13引脚输出高电平。

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);

例:将PC13引脚输出低电平。

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);

GPIO电平翻转HAL库函数

void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

例:将PC13引脚输出电平翻转。

HAL_GPIO_TogglePin(GPIOC,  GPIO_PIN_13);        //翻转PC13

HAL_GPIO_TogglePin(GPIOA,  GPIO_PIN_0);          //翻转PA0

PC13引脚是STM32F103C8T6最小系统上靠近电源指示灯的另一个LED

不用接其他外设就可以看到现象


学习视频:

【【小蜜蜂笔记】基于STM32CubeMX的嵌入式开发基础教程】 STM32的按键开发基础_哔哩哔哩_bilibili

GPIO电平输入HAL库函数

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

例:判断PA5引脚的输入信号,若位低电平,则...

if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET)    //PA5按键 = 0

{}

用按键控制LED灯的开关

CubeMx时钟树的配置:

按键

然后写一个很Low的阻塞性延时按键消抖的函数

unsigned char Key_GetNum(void)
{
	unsigned char KeyNum = 0;
	
	if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET)	//PB1按键 = 0
	{
		
		HAL_Delay(20);
		while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET);
		HAL_Delay(20);
		KeyNum = 1;
	}
	
	if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_RESET)	//PB1按键 = 0
	{
		
		HAL_Delay(20);
		while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_RESET);
		HAL_Delay(20);
		KeyNum = 2;
	}
	
	if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET)	//PB1按键 = 0
	{
		
		HAL_Delay(20);
		while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET);
		HAL_Delay(20);
		KeyNum = 3;
	}
	
	return KeyNum;
}

在while(1)里判断是哪个按键按下,然后执行对应的电平翻转函数

KeyNumber = Key_GetNum();

	if (KeyNumber == 1)
	{
	//		  HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);		//翻转PC13
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
	}
	else if (KeyNumber == 2)
	{
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
	}
	else if (KeyNumber == 3)
	{
		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);		//翻转PC13
	}

温馨提示:不要用中文命名工程的名字,CubeMx对中文的兼容不好,路径也不可以出现中文和空格,不然就会出现莫名其妙的报错


蓝桥杯嵌入式组点灯大师

LED控制函数

//函数调用,传入的形参,那一位给1哪一位就点亮,state=0x00就是全灭
void LED_Disp(uchar state)
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All, GPIO_PIN_SET);	//全部拉高
	HAL_GPIO_WritePin(GPIOC, state<<8, GPIO_PIN_RESET);		//state左移8位,就是PC8~PC15,正好是8个LED,低电平点亮
	
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);		//锁存器置高,使能
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);	//锁存器置低,失能
}

main函数

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
  
	LED_Disp(0x00);		//LED初始化
	LCD_Init();			//LCD初始化
	
	
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	LCD_DisplayStringLine(Line0, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line1, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line2, (uint8_t *)"      LCD Test      ");
	LCD_DisplayStringLine(Line3, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line4, (uint8_t *)"                    ");
	
	LCD_SetBackColor(White);
	LCD_SetTextColor(Blue);

	LCD_DisplayStringLine(Line5, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line6, (uint8_t *)"       HAL LIB      ");
	LCD_DisplayStringLine(Line7, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line8, (uint8_t *)"         @80        ");
	LCD_DisplayStringLine(Line9, (uint8_t *)"                    ");
	
	
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  //LED_Disp(0x01);	//点亮第一个LED
	  //HAL_Delay(500);
	  //LED_Disp(0x00);	//熄灭第一个LED
	  //HAL_Delay(500);
	  
	//LED左右流水
		for (unsigned char i = 0; i < 8; i ++)
		{
		  LED_Disp(0x01 << i);	
		  HAL_Delay(100);
		}
		for (unsigned char i = 0; i < 8; i ++)
		{
		  LED_Disp(0x80 >> i);	
		  HAL_Delay(100);
		}

		//积累流水灯,向左
		for(unsigned char i = 0; i < 8; i ++)
		{
			for (unsigned char j = 0; j < 8-i; j++)
			{
				LED_display =  0x01 << j;
				LED_display |= ( 0xFF << (8-i) );
				LED_Disp(LED_display);	
				HAL_Delay(200);
			}
		}

		//LED左右流水
		for (unsigned char i = 0; i < 8; i ++)
		{
			LED_Disp(0x01 << i);	
			HAL_Delay(100);
		}
		for (unsigned char i = 0; i < 8; i ++)
		{
			LED_Disp(0x80 >> i);	
			HAL_Delay(100);
		}

		//积累流水灯,向右
		for(unsigned char i = 0; i < 8; i ++)
		{
			for (unsigned char j = 0; j < 8-i; j++)
			{
			  LED_display =  0x80 >> j;
			  LED_display |= ( 0xFF >> (8-i) );
			  LED_Disp(LED_display);	
			HAL_Delay(200);
			}
		}
		LCD_SetBackColor(Blue);
		LCD_SetTextColor(White);
		sprintf(LCD_Show_text, "Number:%d   ", numLED);
		LCD_DisplayStringLine(Line3, (uint8_t *)LCD_Show_text);
		numLED++;
		
  }
  /* USER CODE END 3 */
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北国无红豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值