目的:
主要是为了记录LL库和HAL库之间的优缺点,以及我使用时遇到的问题。
LL库
LL库全称叫Low Layer 库,和标准库差不多,是偏底层的一种库,因此用起来和标准库差不了太多。可以用STM32CUBEMX生成外设初始化代码。
优点是因为本身偏底层,所以运行效率很高,寄存器操作也较为直观。
缺点就是一个功能一般需要多个函数来实现,而且有些外设,如USB是没有LL库的,这是一大痛点。
HAL库
我对HAL库相当不满,缺点如下。
一是HAL库封装相当抽象,明明一层封装就足以解决问题,HAL库偏偏封装了好几层,各种函数调用来调用去,效率极其低下。二是HAL库的函数实现过于复杂,比如一个函数就需要操作一个寄存器即可,它非要把参数检查来检查去,把所有参数检查完毕之后再去进行操作,操作十分繁琐,但是可靠性提升却非常有限。
当然HAL库也有优点,在代码本身不复杂,程序运行效率不需要太高的场合,利用HAL库能快速开发程序。
关于HAL库可靠性不高这个问题:
我最近在调试一个SPI借口的SPI程序。总所周知操作屏幕一般只需要用对应的协议向屏幕驱动芯片写数据就行了。后续屏幕所有的操作,如初始化,显示字符这些功能,都是在向屏幕写数据这一个操作的基础上封装而成的。
首先是LL库,我初始化SPI后,使能SPI,以50MB的速度操作这个SPI屏幕显示一幅图片。结果就是屏幕显示非常稳定,没有任何差错。无论我怎样动这个屏幕,怎样碰连接线,其它程序部分怎么变动,屏幕显示没有任何问题。
再此是HAL库,初始化SPI后使能SPI,仍然以50MB的速度操作这个SPI屏幕显示同一幅图片,显示几秒之后图片就会失真。具体伪代码如下:
LCD_Show_Image;
HAL_Delay(N ms);
大约在150ms以上就开始失真延时N个毫秒,N过大时,大约在150ms以上真,屏幕失真。N设为100,碰连接线和屏幕,屏幕失真。连续几次复位,屏幕失真。具体原因位置,估计和HAL库的SPI发送逻辑有很大的关系。调试也不好调试,因为HAL库太过冗杂。
关于STM32库的选择问题:
由于我刚需用STM32的USB HS,而USB只有HAL库,因此我才尝试用HAL库。但发现问题之后,我尝试LL库实现其它外设,HAL库实现USB HS,也就是说HAL库和LL库混用,目前测试来开没有任何问题。因此我认为目前的最优解是,在STM32CUBEMX初始化代码时,有LL库的尽量使用LL库,没有LL库的时候选用HAL库,HAL库效果不理想时有必要直接操作寄存器。