您的位置:首页 > 其它

stm32.cube(十)——单HAL模块的结构

2015-06-25 09:22 218 查看

一、接口函数

对于linux驱动来说,基本的操作函数有Open、Close、Read、Write、Ioctrl,这是在OS的驱动层对外设进行操作的一套规范化的接口。对于更底层的硬件抽象层来说,上层的Open和Close意味着对外设的初始化设置和反初始化设置(回复到未被使用前的状态)。如果外设的作用是实现一个通讯传输,那么上层的Read、Write也要同样对应外设的发送和接收。若外设不是一个传输设备,那么就要有对应的I/O control函数来控制它。同时HAL还要提供取得外设状态的接口,以及外设的中断处理函数。所以一个HAL模块的函数结构基本上是这样的:



通讯外设的接口函数

在TRANSFER这里,大部分实现通信协议的外设都可以由普通方式、中断方式、DMA方式来进行收发。普通方式和中断方式有相应的callback函数和中断处理函数,DMA方式也有相应的DMA控制函数。依据不同的通讯协议,不同的通讯外设的传输函数也会有许多区别。

CAN模块里有sleep和wakeup函数。

I2C模块分了Master、Slave和Mem三种模式,每种模式都由对应的读写函数。

SPI模块里有全双工模式下用的同时读写的函数。



非通讯外设的接口函数

非通讯外设的CONTROL部分中,不同的外设有不同的操作函数。比如 对于Rtc来说,需要能够取得当前的时间的操作函数。对于看门狗来说,要有喂狗的操作函数。

二、数据结构

Init结构体

每个外设都有相应的Init结构体类型,如ADC_InitTypeDef、CAN_InitTypeDef、DMA_InitTypeDef等等,结构体里的每个成员都代表要初始化的外设的属性。我找一个最简单的来说明:

/**
* @brief  IWDG Init structure definition
*/
typedef struct
{
uint32_t Prescaler;  /*!< Select the prescaler of the IWDG.
This parameter can be a value of @ref IWDG_Prescaler */

uint32_t Reload;     /*!< Specifies the IWDG down-counter reload value.
This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */

}IWDG_InitTypeDef;


IWDG_InitTypeDef里包含看门狗时钟的预分频量和喂狗时送的基础数值。

Handle结构体

之前有说过,Handle结构体相当于一个外设类的实例。

/**
* @brief  IWDG Handle Structure definition
*/
typedef struct
{
IWDG_TypeDef                 *Instance;  /*!< Register base address    */

IWDG_InitTypeDef             Init;       /*!< IWDG required parameters */

HAL_LockTypeDef              Lock;       /*!< IWDG Locking object      */

__IO HAL_IWDG_StateTypeDef   State;      /*!< IWDG communication state */

}IWDG_HandleTypeDef;


这个结构体通常包含一个Init结构体,指向寄存器地址的指针,一个HAL锁和一个标记状态的变量。由于IWDG模块相对简单,所以没有函数指针表,也没有标记错误的变量。

几乎所有的模块里的函数都会以指向这个结构体的指针作为参数。

三、小结

stm32cube里的HAL层在接口函数的设计上趋向于简单和标准化。只要理解外设的工作原理,使用对应模块的接口函数将不会付出很多学习成本。

当我们使用任意外设的时候,要提前创建一个该外设的Handle结构体,然后将Handle结构体里的Init结构体的成员都按照需要进行赋值。在调用该模块的Init()函数进行初始化之后,就可以使用控制函数来对外设进行行为级的操作了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: