STMCUBE-MX HAL库的学习之Demonstrations粗分析

/ 0评 / 0

因为官方针对这个HAL还是有不少的例子的,比如官方完整的Demo例子就有HAL的版本,其中涵盖了大多数的函数~
QQ截图20160115141012
文件夹也有分类的,其中来说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,官方文档里就有这个定义了.
QQ截图20160115142617
而对比没有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官方愿意兼容以前的库,就是名字不要改,这样估计会更多人接收,只是这样的分层管理就显得没有那么的方便了.

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注