因为官方针对这个HAL还是有不少的例子的,比如官方完整的Demo例子就有HAL的版本,其中涵盖了大多数的函数~

文件夹也有分类的,其中来说Middlewares,Application,Drivers三大类,其中Middlewares,就是中间件,什么是中间件呢,就是不完全底层,不完全上层,属于一个衔接.比如USB库,MSC库,RTOS以及图形库,然后Drivers属于底层,Application自然是上层应用了,上层应用肯定是自己写的.主要从Drivers/BSP/Components先分析,主要关心底层的改变,上层的改变都是我们自己应用层的事情,跟底层并没什么关系的.比如以下片段:
static void I2Cx_Init(void)
{
if(HAL_I2C_GetState(&I2cHandle) == HAL_I2C_STATE_RESET)
{
I2cHandle.Instance = DISCOVERY_I2Cx;
I2cHandle.Init.ClockSpeed = BSP_I2C_SPEED;
I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_2;
I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2cHandle.Init.OwnAddress2 = 0;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
/* Init the I2C */
I2Cx_MspInit(&I2cHandle);
HAL_I2C_Init(&I2cHandle);
}
}
暂且不说I2Cx_MspInit是怎么实现的,而且因为没有HAL前缀,也证明这个东西不是HAL库的,而HAL_I2C_Init才是HAL库的.传入一个结构体,结构体的定义是如下的:
I2C_HandleTypeDef I2cHandle;
换句话说就是I2C_HandleTypeDef,官方文档里就有这个定义了.
而对比没有HAL库的代码:
static void IOE_I2C_Config(void)
{
I2C_InitTypeDef I2C_InitStructure;
/* If the I2C peripheral is already enabled, don't reconfigure it */
if ((IOE_I2C->CR1 & I2C_CR1_PE) == 0)
{
/* IOE_I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
/* Initialize the I2C peripheral */
I2C_Init(IOE_I2C, &I2C_InitStructure);
/* Enable the I2C peripheral */
I2C_Cmd(IOE_I2C, ENABLE);
}
}
对比一看,HAL库只需要写I2C速度,就可以大致计算,而且感觉HAL库更深入底层设置.不过HAL还有个优点,发送I2C再也不用担心不会用了.
(#) Blocking mode functions are :
(++) HAL_I2C_Master_Transmit()
(++) HAL_I2C_Master_Receive()
(++) HAL_I2C_Slave_Transmit()
(++) HAL_I2C_Slave_Receive()
(++) HAL_I2C_Mem_Write()
(++) HAL_I2C_Mem_Read()
(++) HAL_I2C_IsDeviceReady()
(#) No-Blocking mode functions with Interrupt are :
(++) HAL_I2C_Master_Transmit_IT()
(++) HAL_I2C_Master_Receive_IT()
(++) HAL_I2C_Slave_Transmit_IT()
(++) HAL_I2C_Slave_Receive_IT()
(++) HAL_I2C_Mem_Write_IT()
(++) HAL_I2C_Mem_Read_IT()
(#) No-Blocking mode functions with DMA are :
(++) HAL_I2C_Master_Transmit_DMA()
(++) HAL_I2C_Master_Receive_DMA()
(++) HAL_I2C_Slave_Transmit_DMA()
(++) HAL_I2C_Slave_Receive_DMA()
(++) HAL_I2C_Mem_Write_DMA()
(++) HAL_I2C_Mem_Read_DMA()
(#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
(++) HAL_I2C_MemTxCpltCallback()
(++) HAL_I2C_MemRxCpltCallback()
(++) HAL_I2C_MasterTxCpltCallback()
(++) HAL_I2C_MasterRxCpltCallback()
(++) HAL_I2C_SlaveTxCpltCallback()
(++) HAL_I2C_SlaveRxCpltCallback()
(++) HAL_I2C_ErrorCallback()
比如要发送接收都有了,还有非阻塞的,然后通过回调函数来实现功能,真是非常方便的,跟之前说的GPIO中断一样,默认的回调都是weak的,需要你自己额外实现,就可以替换掉这个weak函数了.
__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hi2c);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_I2C_TxCpltCallback could be implemented in the user file
*/
}
这样就容易很多了,再也不用有以前的担心了,而且效率也是更高了哦.所以,HAL库应该是以后的发展方向,当然如果ST官方愿意兼容以前的库,就是名字不要改,这样估计会更多人接收,只是这样的分层管理就显得没有那么的方便了.