在学习完GPIO的基本知识我们就可以点一个灯了。
之前学的似懂非懂,没关系,只要学习代码对照之前的知识就能容易理解了。
这里LED时选择推挽模式
下面对代码写下我的理解。
1.设置LED.H
/* 引脚 定义 */
#define LED0_GPIO_PORT GPIOB
#define LED0_GPIO_PIN GPIO_PIN_5
#define LED0_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 */
#define LED1_GPIO_PORT GPIOE
#define LED1_GPIO_PIN GPIO_PIN_5
#define LED1_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0) /* PE口时钟使能 */
解析:这一部分重新定义宏名称,把GBIO引脚
和时钟重新命名,在led.c文件中就可以用新名称。
/* LED端口定义 */
#define LED0(x) do{ x ? \
HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_RESET); \
}while(0) /* LED0翻转 */
#define LED1(x) do{ x ? \
HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \
}while(0) /* LED1翻转 */
解析:这个代码把宏 HAL_GPIO_WritePin()直接定义成LED()
,这样我们在主函数中只需要用LED(0)
和LED(1)
来控制LED亮灭,大大缩短了代码量。
/* LED取反定义 */
#define LED0_TOGGLE() do{ HAL_GPIO_TogglePin(LED0_GPIO_PORT, LED0_GPIO_PIN); }while(0) /* 翻转LED0 */
#define LED1_TOGGLE() do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0) /* 翻转LED1 */
解析:这里使用也是把取反宏HAL_GPIO_TogglePin直接定义成LED0_TOGGLE()
,减少代码量。
2.设置led.c
先看一下led.c的整体代码
void led_init(void)
{
GPIO_InitTypeDef gpio_init_struct;//创建结构体
LED0_GPIO_CLK_ENABLE();//LED0时钟使能
LED1_GPIO_CLK_ENABLE(); //LED1时钟使能
gpio_init_struct.Pin = LED0_GPIO_PIN;//LED0引脚
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出
gpio_init_struct.Pull = GPIO_PULLUP;//上拉(无效)
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(LED0_GPIO_PORT, &gpio_init_struct);//初始化LED0引脚
gpio_init_struct.Pin = LED1_GPIO_PIN;//LED1引脚
HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);//初始化LED1引脚
LED0(1);//关闭LED0
LED1(1);//关闭LED1
}
在建立led函数模块时,有必备的两个步骤
1.给对应的引脚时钟使能。
2.设置工作模式,设置引脚,创建结构体,给结构体赋值,初始化工作模式,这样对应的引脚就能工作。
解析:这个代码首先给led0和led1时钟初始化,使之能执行指令
(使用宏LED0_GPIO_CLK_ENABLE()定义
)
然后创建一个结构体,用结构体设置led0和led1的工作模式
(使用宏HAL_GPIO_Init()定义
)。
3.设置主函数
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟,72M */
delay_init(72); /* 初始化延时函数 */
led_init(); /* 初始化LED */
while(1)
{
LED0(0); /* LED0 亮 */
LED1(1); /* LED1 灭 */
delay_ms(500);
LED0(1); /* LED0 灭 */
LED1(0); /* LED1 亮 */
delay_ms(500);
}
}
由于在led.h
把宏定义成简单的模式,所以在主函数中不仅更加容易看懂,而且代码量大大减少。
PGIO我目前就学到这里了,下面我就学习中段方面的知识了。