STM32标准库/HAL库移植 宏的使用/宏使用技巧

 

目录

 抽象层:(标准库)

方法1: 有参宏

方法2: 简单宏定义

方法3:无参稍微复杂的宏

gpio.h 

main.c:

方法4:带参函数

HAL库中使用要注意:

引脚状态赋值问题:

解决办法:


抽象层:(标准库)

hal库仅部分函数和部分类型不同,后面会介绍

方法1: 有参宏

缺点是:在移植到其他库或者其他种类单片机时,对应函数或参数可能会变化

如果换到一个主频很高的单片机中,需要对软件时序进行延时操作的时候,不太方便修改

/*引脚配置 有参宏 */
#define OLED_W_SCL(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x))
#define OLED_W_SDA(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x))
// 调用
void OLED_I2C_Start(void)
{
	OLED_W_SDA(1);
	OLED_W_SCL(1);
	OLED_W_SDA(0);
	OLED_W_SCL(0);
}

方法2: 简单宏定义

方法3:无参稍微复杂的宏

gpio.h 

main.c:

下面使用的时候,不是以函数形式调用,而是直接写语句!!

这样进行类比,还可以在程序中写出反转,锁等操作,其他的类似!!

方法4:带参函数

解决了宏定义的问题,方便理解还便于根据情况修改延时

//编写:
void MyI2C_W_SCL(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);		//根据BitValue,设置SCL引脚的电平
	Delay_us(10);					//延时10us,防止时序频率超过要求
}
void MyI2C_W_SDA(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValue);		//根据BitValue,设置SDA引脚的电平,BitValue要实现非0即1的特性
	Delay_us(10);					//延时10us,防止时序频率超过要求
}
/*

函数的第三个形参是枚举类型,要强制类型转换
需要高/低电平时,不可以直接写0或1,需要强制类型转换,将1和0类型转换为BitAction的枚举类型。
BitAction可以理解为如果数据是0x00那就转化为0,非零就转化1.

*/
//调用:
void MyI2C_Start(void)
{
	MyI2C_W_SDA(1);							//释放SDA,确保SDA为高电平
	MyI2C_W_SCL(1);							//释放SCL,确保SCL为高电平
	MyI2C_W_SDA(0);							//在SCL高电平期间,拉低SDA,产生起始信号
	MyI2C_W_SCL(0);							//起始后把SCL也拉低,即为了占用总线,也为了方便总线时序的拼接
}
void MyI2C_Stop(void)
{
	MyI2C_W_SDA(0);							//拉低SDA,确保SDA为低电平
	MyI2C_W_SCL(1);							//释放SCL,使SCL呈现高电平
	MyI2C_W_SDA(1);							//在SCL高电平期间,释放SDA,产生终止信号
}

HAL库中使用要注意:

引脚状态赋值问题:

使用这个引脚配置函数HAL_GPIO_WritePin参照前面的写法会出现问题,如下:

void MyI2C_W_SCL(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);	//枚举类型转换有问题
}

标准库中的没问题是因为,标准库中有这个,而HAL库中没有:

GPIO_WriteBit 函数的第三个参数要求是 BitAction 枚举类型(定义通常为 typedef enum {Bit_RESET = 0, Bit_SET} BitAction;),而你传入的 BitValue 是 uint8_t 类型。通过 (BitAction)BitValue 进行显式类型转换后,将 uint8_t 强制转换为枚举类型 BitAction,符合函数参数的类型要求,从而避免了 “枚举类型与其他类型混合” 的警告。

会报警告:warning: #188-D: enumerated type mixed with another type

指示在代码的某处将枚举类型与另一种类型混合使用,这种警告通常在将枚举类型与其他类型进行操作或赋值时出现

HAL_GPIO_WritePin 函数的原型是:

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

其中第三个参数 PinState 是一个枚举类型(GPIO_PinState),定义为:

typedef enum
{
  GPIO_PIN_RESET = 0,
  GPIO_PIN_SET
}GPIO_PinState;

传入的参数 x 可能是 uint8_tbool 或其他类型,而不是 GPIO_PinState 枚举类型,导致类型不匹配。

解决办法:

方法一:直接使用枚举值

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);   // 置高
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET); // 置低

方法二:类型转换 (GPIO_PinState)(x)

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, (GPIO_PinState)(x))

/*引脚配置*/
#define OLED_W_SCL(x)		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, (GPIO_PinState)(x))
#define OLED_W_SDA(x)		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, (GPIO_PinState)(x))

方法三:若需要用变量 x 控制(假设 x 为 0 或非 0):

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, (x ? GPIO_PIN_SET : GPIO_PIN_RESET));

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值