社区导航

 
快捷导航
  • 首页
  • 论坛
  • 查看新帖
  • 最新回复
  • 社区活动
  • 联系管理员
  • 消灭零回复
  • E金币兑换
  • 干货
搜索
查看: 1743|回复: 3

[讨论] HAL_Init()还需要其它初始化工作吗?

[复制链接]

1万

TA的帖子

33

TA的资源

版主

Rank: 6Rank: 6

发表于 2017-1-12 18:05:29 | 显示全部楼层 |阅读模式
用STM32CubeMX生成STM32项目,发现端口的初始化工作并没有做完, ----怀疑

-------------- ST给的例程也是这样:

a1.jpg



在HAL_Init()里,没有发现某些端口的进一步设置,如AF功能设置等,而在 xxxxx(芯片型号)_hal_msp.c中却发现所用端口的初始化函数。

用 go to definition of ..... 跟踪到的HAL_MspInit()函数是在 xxxxx(芯片型号)_hal . c中的__weak void HAL_MspInit(void){}

在xxxxx(芯片型号)_hal_msp.c也有个这样的函数却跟踪不到它。但这个函数仍然没有详细的端口初始化功能。


我现在的问题多了,重要的放前面吧:




1、HAL_Init()中是否需要加入端口的初始化函数?

2、需要改到xxxxx(芯片型号)_hal_msp.c中的void HAL_MspInit(void)函数吗?

3、__weak 在这里起到什么作用?
此帖出自stm32/stm8论坛


回复

使用道具 举报

4164

TA的帖子

9

TA的资源

五彩晶圆(高级)

Rank: 9Rank: 9Rank: 9

测评达人

发表于 2017-1-12 22:18:01 | 显示全部楼层
1、我个人的回答是不需要。2、也不需要改;
3、__weak的含义是弱定义。一般出现弱定义的地方,函数体内部都是空的。
如下,我以STM32CubeMX生成的MDK5.16的STM32L432的工程做为说明。(我的例程是关于串口的一个例子)。


A、首先,HAL_Init()都干了一些什么事情呢?
这个可以根据这个函数上面的注释看到:
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

这个就是初始化一些外设,flash相关及滴答定时器相关。
我们调到HAL_Init()这个函数中去看
  1. HAL_StatusTypeDef HAL_Init(void)
  2. {
  3.   /* Configure Flash prefetch, Instruction cache, Data cache */
  4.   /* Default configuration at reset is:                      */
  5.   /* - Prefetch disabled                                     */
  6.   /* - Instruction cache enabled                             */
  7.   /* - Data cache enabled                                    */
  8. #if (INSTRUCTION_CACHE_ENABLE == 0)
  9.    __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
  10. #endif /* INSTRUCTION_CACHE_ENABLE */

  11. #if (DATA_CACHE_ENABLE == 0)
  12.    __HAL_FLASH_DATA_CACHE_DISABLE();
  13. #endif /* DATA_CACHE_ENABLE */

  14. #if (PREFETCH_ENABLE != 0)
  15.   __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
  16. #endif /* PREFETCH_ENABLE */

  17.   /* Set Interrupt Group Priority */
  18.   HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

  19.   /* Use SysTick as time base source and configure 1ms tick (default clock after Reset is MSI) */
  20.   HAL_InitTick(TICK_INT_PRIORITY);

  21.   /* Init the low level hardware */
  22.   HAL_MspInit();

  23.   /* Return function status */
  24.   return HAL_OK;
  25. }
复制代码
初始化了,systick的中断优先级分组,CACHE等(至于初始化哪些寄存器,你可以跟进去看,这个里面有说明初始化的是哪个寄存器的)和HAL_MspInit。

B、至于HAL_MspInit这个函数,跟进去发现在stm32l4xx_hal.c这个C文件中,这个函数是弱定义。而且函数体是空的。
  1. /**
  2.   * [url=home.php?mod=space&uid=159083]@brief[/url]  Initialize the MSP.
  3.   * @retval None
  4.   */
  5. __weak void HAL_MspInit(void)
  6. {
  7.   /* NOTE : This function should not be modified, when the callback is needed,
  8.             the HAL_MspInit could be implemented in the user file
  9.    */
  10. }
复制代码
而在stm32l4xx_hal_msp.c中,可以看到设置了一堆的NVIC
  1. void HAL_MspInit(void)
  2. {
  3.   /* USER CODE BEGIN MspInit 0 */

  4.   /* USER CODE END MspInit 0 */

  5.   __HAL_RCC_SYSCFG_CLK_ENABLE();

  6.   HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

  7.   /* System interrupt init*/
  8.   /* MemoryManagement_IRQn interrupt configuration */
  9.   HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
  10.   /* BusFault_IRQn interrupt configuration */
  11.   HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
  12.   /* UsageFault_IRQn interrupt configuration */
  13.   HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
  14.   /* SVCall_IRQn interrupt configuration */
  15.   HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0);
  16.   /* DebugMonitor_IRQn interrupt configuration */
  17.   HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
  18.   /* PendSV_IRQn interrupt configuration */
  19.   HAL_NVIC_SetPriority(PendSV_IRQn, 0, 0);
  20.   /* SysTick_IRQn interrupt configuration */
  21.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

  22.   /* USER CODE BEGIN MspInit 1 */

  23.   /* USER CODE END MspInit 1 */
  24. }
复制代码
这些都是MX工具在配置的时候,已经设置好了的。
所以在main.c中在main后面
  1.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  2.   HAL_Init();

  3.   /* Configure the system clock */
  4.   SystemClock_Config();

  5.   /* Initialize all configured peripherals */
  6.   MX_GPIO_Init();
  7.   MX_USART2_UART_Init();
复制代码

想必你看名字就知道了,初始化外设等后,之后,设置系统时钟,然后初始化gpio,初始化uart。基本都是这些套路。

还有需要注意的一点:建议所有的函数体,或者宏定义,变量的定义,宏定义等等,都写在类似,这个begin和end的中间
  1. /* USER CODE BEGIN 1 */

  2.   /* USER CODE END 1 */
复制代码
如此以来,你在MX导入后缀名为.ioc的MX工具的文件再次设置你的外设啊之类的东西的时候,你之前的代码在再次生成工程的时候,不会丢失

还有附上一些有关cube库结构的介绍和F4的HAL库的说明手册以供楼主参考。毕竟标准外设库是先入为主,熟悉新的HAL库的时候,确实需要花费时间的。

STM32 Cube introduction-lesson 1.pdf (2.22 MB, 下载次数: 22)

评分

1

查看全部评分



回复

使用道具 举报

3454

TA的帖子

11

TA的资源

五彩晶圆(高级)

Rank: 9Rank: 9Rank: 9

发表于 2017-1-12 22:30:10 | 显示全部楼层
1.      HAL_Init(),  先看它的功能,它复位了所有外设,初始化flash接口。。。。         加不加看具体情况。程序启动后,除了具有断电保存功能的存储器外,其他的寄存器啥的,都是默认值。再重置一次也没关系。  看你后面的应用程序用到了哪些外设,接口啥的。你完全可以不管这个函数,在它后面某个位置自己写一个初始化函数,只对你后面需要操作的外设等,进行初始化。作用和它这个函数是一样的。
2.  不用改。         不用理他。  当然,你要想在 HAL_Init()进行相关的初始化操作。你就在自己的文件里,实现HAL_MspInit(void),一旦你实现了这个函数,编译器编译HAL_Init()时,就以你写的HAL_MspInit(void)为准,忽略他自己的。为什么。 他自己的函数是weak的。     这是一个弱化符号。其他地方如果定义了这个函数,最后编译,就以其他地方定义的为准,忽略自己的,因为自己是弱的。其他地方没有的话,还是以自己原有为准。
3.已回答。


最简单的, 就是看你要操作哪些外设,在 HAL_Init()后,找个合适的位置,自己写一个函数,根据需求,对相关外设啥的,进行初始化。   完事了。  后面就看主函数了。

评分

1

查看全部评分



回复

使用道具 举报

1万

TA的帖子

15

TA的资源

版主

Rank: 6Rank: 6

发表于 2017-1-13 09:30:46 | 显示全部楼层
__weak在回调函数的时候经常用到。好处是,系统默认定义了一个空的回调函数,保证编译器不会报错。同时如果用户自己定义用户回调函数,那么只需重新定义及可,而不必考虑函数已经定义过了。这样十分方便。在HAL里__weak大量应用
http://shop34182318.taobao.com/


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2018-6-22 09:23 , Processed in 0.402481 second(s), 18 queries , Gzip On, Redis On.

快速回复 返回顶部 返回列表