大家好,我是鼎!
前言
点亮LED对于任何控制来说,都是基础中的基础,就像编程中的HELLO WORLD,但是从便于移植,逻辑清晰的角度来讲,写好它还是需要一定的功力的。这一篇也是借鉴硬石的代码,进行剖析,转化!
.h文件编写与分析
1.首先进行IO部分宏定义,方便以后移植与更换IO(为避免不必要的重复,只放了LED1部分,LED2和LED3类似)
#define LED1_RCC_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
#define LED1_GPIO_PIN GPIO_PIN_9
#define LED1_GPIO GPIOH
#define LED1_ON HAL_GPIO_WritePin(LED1_GPIO,LED1_GPIO_PIN,GPIO_PIN_SET)
// 输出高电平
#define LED1_OFF HAL_GPIO_WritePin(LED1_GPIO,LED1_GPIO_PIN,GPIO_PIN_RESET)
// 输出低电平
#define LED1_TOGGLE HAL_GPIO_TogglePin(LED1_GPIO,LED1_GPIO_PIN)
// 输出反转
2.定义一个枚举类型,定义控制LED变化状态,这里我们只定义了LED开(1),LED关(0),LED翻转(2)三种形态
typedef enum//定义LED状态
{
LED_OFF = 0,
LED_ON = 1,
LED_TOGGLE = 2,
}LEDState_TypeDef;
3.加入一个宏定义,作为LED状态的合法检测,应用了带参数的宏定义
#define IS_LED_STATE(STATE) (((STATE) == LED_OFF) || ((STATE) == LED_ON) || ((STATE) == LED_TOGGLE))
4.定义一个uint8_t,置1代表LED配置标志(作用看后续说明)
#define LED1 (uint8_t)0x01 // 00000001
#define LED2 (uint8_t)0x02//00000010
#define LED3 (uint8_t)0x04//00000100
5.加入一个宏定义,作为LED的合法检测,应用了带参数的宏定义
#define IS_LED_TYPEDEF(LED) (((LED) == LED1) || ((LED) == LED2) || ((LED) == LED3))
.c文件编写与分析
1.此处代码是对LED对应IO的配置(为避免不必要的重复,此处只放了LED1)
void LED_GPIO_Init(void)
{
/* 定义IO硬件初始化结构体变量 */
GPIO_InitTypeDef GPIO_InitStruct;
/* 使能(开启)LED引脚对应IO端口时钟 */
LED1_RCC_CLK_ENABLE();
LED2_RCC_CLK_ENABLE();
LED3_RCC_CLK_ENABLE();
/* 配置LED1引脚输出电压 */
HAL_GPIO_WritePin(LED1_GPIO, LED1_GPIO_PIN, GPIO_PIN_RESET);
/* 配置LED2引脚输出电压 */
HAL_GPIO_WritePin(LED2_GPIO, LED2_GPIO_PIN, GPIO_PIN_RESET);
/* 配置LED3引脚输出电压 */
HAL_GPIO_WritePin(LED2_GPIO, LED3_GPIO_PIN, GPIO_PIN_RESET);
/* 设定LED1对应引脚IO编号 */
GPIO_InitStruct.Pin = LED1_GPIO_PIN;
/* 设定LED1对应引脚IO为输出模式 */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
/* 设定LED1对应引脚IO操作速度 */
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
/* 初始化LED1对应引脚IO */
HAL_GPIO_Init(LED1_GPIO, &GPIO_InitStruct);
}
2.此处代码为设置LED的代码,里面的思想很重要
函数功能: 设置板载LED灯的状态
输入参数: LEDx:其中x可甚至为(1,2,3)用来选择对应的LED灯
state:设置LED灯的输出状态。
可选值: LED_OFF:LED灯灭
LED_ON:LED灯亮
LED_TOGGLE:反转LED
void LEDx_StateSet(uint8_t LEDx,LEDState_TypeDef state)
{
/* 检查输入参数是否合法 */
assert_param(IS_LED_TYPEDEF(LEDx));
assert_param(IS_LED_STATE(state));
/* 判断设置的LED灯状态,如果设置为LED灯灭 */
if(state==LED_OFF)
{
if(LEDx & LED1)
LED1_OFF;/* LED1灭 */
if(LEDx & LED2)
LED2_OFF;/* LED2灭 */
if(LEDx & LED3)
LED3_OFF;/* LED3灭 */
}
else if(state==LED_ON) /* 设置LED灯为亮 */
{
if(LEDx & LED1)
LED1_ON;/* LED1亮 */
if(LEDx & LED2)
LED2_ON;/* LED2亮 */
if(LEDx & LED3)
LED3_ON;/* LED3亮 */
}
else
{
if(LEDx & LED1)
LED1_TOGGLE;/* 设置引脚输出反转 */
if(LEDx & LED2)
LED2_TOGGLE;/* 设置引脚输出反转 */
if(LEDx & LED3)
LED3_TOGGLE;/* 设置引脚输出反转 */
}
}
总结:其实还是模仿了stm公司标准库的写法,条例清晰,便于扩展!