13527|3

1万

帖子

28

TA的资源

裸片初长成(高级)

楼主
 

HAL_Init()还需要其它初始化工作吗? [复制链接]

用STM32CubeMX生成STM32项目,发现端口的初始化工作并没有做完, ----怀疑

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





在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论坛

最新回复

__weak在回调函数的时候经常用到。好处是,系统默认定义了一个空的回调函数,保证编译器不会报错。同时如果用户自己定义用户回调函数,那么只需重新定义及可,而不必考虑函数已经定义过了。这样十分方便。在HAL里__weak大量应用  详情 回复 发表于 2017-1-13 09:30
点赞 关注
 

回复
举报

4177

帖子

9

TA的资源

五彩晶圆(高级)

沙发
 
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, 下载次数: 74)

STM32 Cube introduction-lesson 2.pdf (766.49 KB, 下载次数: 68)

F4 HAL驱动详解.pdf (4.48 MB, 下载次数: 116)

以上,希望可以帮助到楼主


此帖出自stm32/stm8论坛

赞赏

1

查看全部赞赏

 
 

回复

3471

帖子

11

TA的资源

五彩晶圆(高级)

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


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

赞赏

1

查看全部赞赏

 
 

回复

1万

帖子

16

TA的资源

版主

4
 
__weak在回调函数的时候经常用到。好处是,系统默认定义了一个空的回调函数,保证编译器不会报错。同时如果用户自己定义用户回调函数,那么只需重新定义及可,而不必考虑函数已经定义过了。这样十分方便。在HAL里__weak大量应用
此帖出自stm32/stm8论坛
 
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表