你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于HAL库中stm32f1xx_hal_msp.c文件的认知(新手贴)

[复制链接]
stm8s003 发布时间:2019-5-29 16:35

# r6 a0 b5 M' B2 `/ \
关于HAL库中stm32f1xx_hal_msp.c文件的认知(新手贴)
9 g( K" D' P7 f: l$ g- {2 ]
要熟练使用STM32CUBEMX这个软件,首先就要熟悉HAL库。俺以前用的片子基本都是51核心的,都是直操寄存器的,后来用STM8的片子,用的是库,感觉用起来很方便。随着项目的不断扩充和客户要求的提高,用到了STM32F103的片子,想想自己关于STM32的认知水平还在6年前3.5版本的库,感觉应该有点落后了,于是上网找找最新版本的库,好做项目设计准备。就在这时候发现了STM32CUBEMX的这个软件以及HAL库,看了相关介绍后,瞬间觉得自己完全落伍了,学习,学习,再学习......
+ J- O' Y* D7 r) g3 H& |+ O3 F: G
网上好多关于HAL库和标准库优劣的探讨,俺再这就不多说了,俺认为只要能满足项目需要就行,就好像筷子和刀叉的关系,只要能把饭吃到嘴里就行。俺为啥选择学HAL库?因为俺以前啥也不会,要学当然选最新的方向学习了。
8 k! E2 s' a  l3 F) y9 P) P! H
言归正传

4 D8 V0 ]3 _- Y9 s% J
学习HAL库,首先是对这个库的各个文件仔细研究,每个文件的大概功能、在整个库中所起到的作用、文件与文件之间引用关系、文件与文件之间的层级关系都要做到心中有数,这样在使用库做项目的时候才不至于逻辑混乱,减少调试时间。对整个库的研究需要狠下功夫,对库中文件的作用和关系了解透彻了,也就能明白了HAL的编程思想精髓,结合STM32CUBEMX,可以随心应手操刀自己的设计。
) `3 \; U: h6 {& s
在HAL库中有一个stm32f1xx_hal_msp.c的文件,这个文件的作用就是根据用户所提供的具体的MCU型号以及硬件配置,对HAL库进行初始化设置操作。所以这个文件是就HAL库与MCU结合的纽带(不知这样描述是否恰当)。

* q! b6 i( `% \1 j* L" I
以下是个打比方说明方式(欢迎指正):

6 m4 e, s; _. v# t& ?# }
首先把每个片上外设看成一个功能元件,把有关所有外设的记录合起来就是一个表格(BOM表)。
/ ~" d; B2 T* j) Y& s# _1 l- I
  • 好比F1系列的HAL库是对F1系列所有型号MCU功能BOM的集合。
  • 现在要使用一个F1系列的单片机,型号就叫作A1。
  • 在CUBEMX中,设置单片机型号为A1
  • 那么CUBEMX就会根据A1这个关键字去配置相应的功能BOM表。并一起把相应具体的用户硬件设置写到stm32f1xx_hal_msp.c中(完成了对HAL库的初始化,注:这个初始化着重的硬件电气上的初始化,就是确定用哪个引脚,什么样高低电平、多大的频率等等)。

    $ [1 t' m: t% x/ T
# j8 g% \+ W. Z& }- E2 ~
那么stm32f1xx_hal_msp.c中的设置是怎么调用和被调用的呢?
; A8 N; d8 c' S% E  S* ?
1.在stm32f1xx_hal_msp.c内包含了头文件stm32f1xx_hal.h。(可以认为stm32f1xx_hal.h是stm32f1xx_hal_msp.c的头文件,同样也是stm32f1xx_hal.c的头文件)
       2.在stm32f1xx_hal.h中声明了HAL_MspInit(void)函数。1 r6 ^& C: `8 e. _" A+ d. g
       3.在stm32f1xx_hal_msp.c内定义了HAL_MspInit(void)函数
) d& Q/ A0 X% |
, q3 B6 H' X! K  A
(也就是间接的通过stm32f1xx_hal.h文件先声明了HAL_MspInit(void)函数,再接着对其进行具体的定义,为什么要在stm32f1xx_hal.h中先声明,是因为还要在stm32f1xx_hal.c中还进行了弱定义)。

" E# R' v' Q7 t: u( P% a  ^3 b
4.stm32f1xx_hal.c内弱定义了 __weak void HAL_MspInit(void)。
, m0 w7 u% i1 b: {  a1 S
5.stm32f1xx_hal_msp.c中的函数定义相对stn32f1xx_hal.c中的同名函数定义具有优先权,如果在tm32f1xx_hal_msp.c没有定义某外设函数,则使用stn32f1xx_hal.c中的定义的那个函数。
2 w" y" s6 g/ ?: i, [9 d" ]
6.用户可通过重新定义stm32f1xx_hal_msp.c内的函数,实现对函数的操作。
% {+ C, V8 Z- e% i1 {# K+ \3 k( T5 d
7.stm32f1xx_hal_msp.c中的函数通过stm32f1xx_hal.h头文件引用。(也就是stm32f1xx_hal_msp.c中具体定义的函数都先在stm32f1xx_hal.h中被预先声明了)。
$ [9 s2 M/ U3 m' L
       通过上面可以了解到,用户对MCU与外设配置写在stm32f1xx_hal_msp.c内,作为回调函数被HAL库中的其他文件使用。
; c  C% r( K. t; ]
      

+ O" `( u8 Z+ c3 Q! K. q0 e
下面是根据网上大师们和大咖们的教导结合自己的认知写的总结,仅供参考。
$ M5 H. X" X  S7 y- D3 Y* c
英文翻译,不知道那个对,俺也不敢说:
2 l8 a* a( h2 b. X0 i: u8 C+ ^
MSP  MCU Specific Package   MCU 特征 包、MCU 具体实例化 包
7 M) n0 D  e. `, C3 B  V
MSP  MCU Support package   MCU 支持 包
- j  a/ E" X. ^  d) w: I
作用和目的:

1 B  Q: W# x+ A
根据具体的MCU型号,对片上外设进行初始化设置。
: P3 K3 P* e. m& v, ~8 Z
这样做的目的是因为从以下几个方面考虑的:
7 E( h& {6 m( S# v
1、所有的同一类型的外设被抽象成通用的封装,即同类型的外设在不同的MCU上的特征属性和API接口都是一样和相同的。
! c6 [* c  C4 B( s3 w4 L/ z
2、相同内核但不同型号的MCU(比如STM32F103C8T6和 STM32F103ZET6都是M3内核)的引脚数量、顺序、资源、内存空间以及片上外设种类数量存在不同。

4 B8 Z  S% P( d7 S
3、为了使HAL库对具有相同内核但资源不同的MCU有较强兼容性,特增加了此文件,让用户根据每款MCU在硬件上具体区别,初始化和配置外设的IO引脚、外设的工作时钟以及外设的中断与MCU内核寄存器的对应关系。
/ X0 p" l$ }7 _. K  Q9 o. u2 [
4、此文件是对MCU硬件上的初始化设置(一些协议、数据格式等等上层的内容一般不涉及),把具体的硬件配置抽象,形成符合HAL库要求的、具有统一格式的和属性种类的结构体。此文件由用户进行编程初始化和配置。该文件内的初始化过程强调的是外设最底层硬件上的初始化。
  I7 T0 J' R2 Q" b
举例:如果存在某个外设PPP
: C  I' {% e/ J6 m* _+ J; z
那么HAL_PPP_MSP_Init() 函数是对外设PPP硬件上的具体设置。

/ y6 k. L* p/ @/ i* o$ V+ \: ~
HAL_PPP_MSP_Init()这个函数又进一步被PPP_Init()外设初始化函数调用。
. b  [  J- @/ L  \, H$ j
HAL_PPP_MSP_Init()是做为一个回调函数被用户配置,HAL库回调使用,从而使HAL库在整体架构上做到统一和兼容。
" B9 G" E( j. i4 `/ h9 a* I+ Q7 O5 m
就是说MSP的作用是把某个外设的接口资源给具体化了,比如对于串口外设,就是指定串口具体的接口引脚状态(包含引脚的位置、电气属性等等)以及外设与CPU的接口(外设与CPU的接口就是特殊功能寄存器的映射地址,也就是告诉CPU要操作哪个外设只要操作相应地址的寄存器就可以了)。
3 Q% ^* e1 B. d: I
俺是新手,欢迎大家留言斧正。
" Y7 ?9 |' T- r4 I4 m# {, F
赞 收藏 评论1 发布时间:2019-5-29 16:35

举报

1个回答
STMCU-管管 回答时间:2019-6-3 15:29:57
付费主题的话,可能会让大家望而却步哦
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版