HAL库学习——点亮发光二极管
一、GPIO控制多路发光二极管
1、配置GPIO
按照上一篇文章介绍的方法,将PB0~PB7配置为输出功能(GPIO_Output)
根据原理图配置PB0~PB7的详细信息(在用户标识"User Label“我将PB0~PB7分别命名为LED0~LED7),如下图所示配置
2、代码修改
前面配置硬件时,给PB0~PB7的用户标识(UserLabel)分别起了名字LED0~LED7。可以打开main. h文件,看一下这些标识是如何定义的:
/* Private defines -----------------------------------------------------------*/ #define LED0_Pin GPIO_PIN_0 #define LED0_GPIO_Port GPIOB #define LED1_Pin GPIO_PIN_1 #define LED1_GPIO_Port GPIOB #define LED2_Pin GPIO_PIN_2 #define LED2_GPIO_Port GPIOB #define LED3_Pin GPIO_PIN_3 #define LED3_GPIO_Port GPIOB #define LED4_Pin GPIO_PIN_4 #define LED4_GPIO_Port GPIOB #define LED5_Pin GPIO_PIN_5 #define LED5_GPIO_Port GPIOB #define LED6_Pin GPIO_PIN_6 #define LED6_GPIO_Port GPIOB #define LED7_Pin GPIO_PIN_7 #define LED7_GPIO_Port GPIOB
这里用了16个#define宏定义,根据用户标识对8个LED引脚的端口和引脚号进行了定义。以PB0引脚为例,PB0为GPIOB端口的第1个引脚,这里将LED0的引脚号(LED0_Pin)定义为GPIO_PIN_0(此为十六进制无符号数0x0001) ,将LEDO所属端口(LED0_GPIO_Port)定义为GPIOB。
编写程序,让8个发光二极管同时闪烁。注意,要将代码放到注释对中。
编写代码如下:
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin); HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin); HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin); HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin); HAL_GPIO_TogglePin(LED5_GPIO_Port,LED5_Pin); HAL_GPIO_TogglePin(LED6_GPIO_Port,LED6_Pin); HAL_GPIO_TogglePin(LED7_GPIO_Port,LED7_Pin); HAL_Delay(500); } /* USER CODE END 3 */
写好之后编译下载程序
3、库函数分析
(1)HAL_GPIO_TogglePin()函数
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
HAL_GPIO_TogglePin()函数有两个参数,第一个参数是GPIOx,另外一个参数是GPIO_Pin。注意,GPIO_Pin的类型是uint16_t ,即无符号十六进制数,是一个数字。
实际上,HAL_GPIO_TogglePin()函数实现的是让I/O输出状态翻转。警如,执行当前HAL_ GPIO_ TogglePin()语句后I/O状态变为0,发光二极管的灯亮,随后延时500 ms;程序继续循环执行,下一次执行HAL_GPIO_TogglePin()语句后,该I/O状态翻转为1,发光二极管灯灭,再延时500ms因此,发光二极管一亮一灭的总时间也是1s,闪烁频率为1Hz。
(2)HAL_GPIO_WritePin()函数
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
HAL_GPIO_WritePin()函数有三个参数,第一个参数是GPIOx,第二个参数是GPIO_Pin,另外一个参数是PinState(引脚状态)。
引脚状态有两个,一个是GPIO_PIN_RESET,被赋值为0;另一个是GPIO_PIN_SET,被赋值为1。
HAL_GPIO_WritePin()函数是直接控制引脚输出高低电平。
所以上述例程可以改为
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(LED4_GPIO_Port,LED4_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(LED5_GPIO_Port,LED5_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(LED6_GPIO_Port,LED6_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(LED7_GPIO_Port,LED7_Pin,GPIO_PIN_RESET); HAL_Delay(500); HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED4_GPIO_Port,LED4_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED5_GPIO_Port,LED5_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED6_GPIO_Port,LED6_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED7_GPIO_Port,LED7_Pin,GPIO_PIN_SET); HAL_Delay(500); } /* USER CODE END 3 */
二、流水灯控制
1、依次点亮发光二极管
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ uint8_t led_num = 0x01; for(uint8_t i=0;i<8;i++) { HAL_GPIO_WritePin(GPIOB,led_num,GPIO_PIN_RESET); HAL_Delay(500); HAL_GPIO_WritePin(GPIOB,led_num,GPIO_PIN_SET); HAL_Delay(500); led_num<<1; } /* USER CODE END 3 */
编译、下载后,运行程序,可以看到8个发光二极管实现了依次闪烁的效果。
注意,GPIO_Pin的类型是uint16_t ,即无符号十六进制数,是一个数字,所以可将led_num当作引脚号,由于只需要控制8个IO口,所以led_num只要8位就行。
另外注意0号引脚是0x01。
#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */ #define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */ #define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */ #define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */ #define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */ #define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */ #define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */ #define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */ #define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */ #define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */ #define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */ #define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */ #define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */ #define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */ #define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */ #define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */ #define GPIO_PIN_All ((uint16_t)0xFFFF) /* All pins selected */