如下图:
从中可以看出link.sct文件,意思就是链接时,扩展出了SRAM2的内存地址 。
这是文件本身的描述:主要是初始化代码。
MSP,全称为 MCU support package,函数名字中 带有 MspInit 的函数,它们的作用是进行 MCU 级别硬件初始化设置,并且它们通常会被上一层的初始化函数 所调用,这样做的目的是为了把 MCU 相关的硬件 初始化剥夺出来,方便用户代码在不同型号的 MCU 上移植。
stm32l4xx_hal_msp.c 文件定义了两个函数 HAL_MspInit 和 HAL_MspDeInit。这两个函数分别被文件 stm32l4xx_hal.c 中的 HAL_Init 和 HAL_DeInit 所调用。
HAL_MspInit 函数的主要作用是进行 MCU相关的硬件初始化操作。例如我们要初始化某些硬件,我们可以硬件相关的初始化配置 写在HAL_MspDeinit 函数中。这样的话,在系统启动后调用了 HAL_Init 之后,会自动调用硬件初始化函数。
实际上,我们在工程模板中直接删掉 stm32l4xx_hal_msp.c 文件也不会对程序运行产生任何影响。
其实,就是将STM32USB口视为一个串口。CSDN原理参考
实现:
1、CubeMX就能快速生成USB工程了
步骤:
->RCC里高速和低速时钟都选择外部晶振Crystal
->Connectivity-USB勾线Device(FS),端口默认PA12(USB_DP),PA11(USB_DM)
->Middleware-USB-DEVICE里Class For FS IP选择Communication Device Class(Virtual Port Com)
->生成代码后,
->电脑端要安装驱动,如下图:
->识别为了串口,就可写些收发程序了
虚拟串口主要用到usbd_cdc_if.c里的两个缓存数组和收发函数。
uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];//接收缓存 uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];//发送缓存 static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t Len)//接收回调函数 uint8_t CDC_Transmit_FS(uint8_t Buf, uint16_t Len)//发送函数
CDC_Transmit_FS是发送函数,指定数据首地址和字节长度,数据就会发送到串口,底层是USB库实现的。
用官方DEMO,就可以找到并且用libraries下文件复制到这个位置,就可解决这个问题。
刚移植时,只是修改了ENV生成的样本工程的配置:如下图:
唯一的就是这个启动文件没有修改过来,经过几天的折腾,终于找到脚本的修改位置:
修改过这里,一切都转到L431芯片配置下,一切OK!
可以说代码很简单,之前的相同的程序都能过了,不知道怎么这次就是通过不了。单步跟踪后发现,在跟踪到rt_device_open时,发现返回值是0,但多走一步,就会变成0xFFFFFFF1(保持默认的串口配置)或0xFFFFFFF8(执行rt_device_control,更改了串口配置)。如下,在device.c文件中rt_device_open:
百思不得其解?偿试将之前调试通过的代码复制到此文件中,也是一样的问题。
经过一段时间的调试,发现不用这个文件,而是用之前调通的文件,然后将此文件的逻辑在调通的文件中添加和更改。就可以顺利的打开串口设备。
调试过程中,偶尔按ctrl+shift+F在全工程文件中搜(lpuart1)时,在搜到的结果中,点击会出现此错误。
遇到不正确的参数”。keil官网给出的信息是:
原因
μVision5调试器目前无法处理包含带有UTF-8字符的文件夹或文件名的DWARF调试信息。
解决方法
请勿在项目的文件夹和文件名以及所有源文件和库中使用非ASCII字符。
此问题可能会在5.25以后的MDK版本中修复。
虽然在原先调通的文件中调试就没这个问题了,但通过这个调的过程,也发现了一个KEIL的BUG还有对中文支持不好.这个过程是痛苦的,甚至怀疑过人生,想过要不要放弃。
还好,找到问题后,果断将系统默认输入法改成英语,以后再遇到就知道怎么弄了。
问题就出在了,函数参数上。初始化函数,不需要传入参数。
解决:
将输入参数改成void;警告就没有了。如图所示:static int spk_thread_init(void)
解决:看官网上有人遇到一样的问题。
INIT_DEVICE_EXPORT(stm32_pwm_init);这个函数是自动初化的。
更新了下项目,但没有输出PWM???
经过查找为HAL_TIM_PWM_Init()这个函数调用了wake声明的函数HAL_TIM_PWM_MspInit(htim);,而没使用cubeMX生成的同名函数。这就造成了定时器时钟没有启动,所以不会有PWM输出。
解决也很简单,复制一下函数名到出错的位置,覆盖掉原来的即可,虽然是一样的,但编辑器会重新编译新覆盖的部分代码,不得不说,MDK优化掉了本该识别的__weak.造成识别出问题。
具体解决方式:F:\SixBirld\rtOS\bsp\myOS\sixBand\ports\fal
将画圈的部分去掉后,编译通过。
查找哪个功能的管脚在此输入即可,如下图:
仔细看了一下之前开发的程序,之前lpuart波特率时钟源使用的是外部的32768,所以设置9600时没有问题。但这次由于用不到rtc所以,没用32768而cubx直接默认的是80M系统时钟,所以会有问题。原因如下:
LPUART的时钟不能超过fck must be in the range [3 x baud rate, 4096 x baud rate].系统时钟是80M, 80M/4096 =19531,也就是在使用80M系统时钟作为LPUART的时钟基准时,波特率最小可以设置为19531远远大于9600,所以出错。将时钟设置为内置HSI即可。
这个纯属粗心造成的,没有按照demo的cumx文件重新配置管脚,而是新生了一个文件将cumx文件替换,这个cumx文件,配置时,外设单独生成一个文件,造成初始化不了串口。如下图所示:
另一个是,新生成的stm32l4xx_hal_msp.c,因为rtt其实就用了这一个文件,会提示: Error_Handler();无定义问题。所以要包含进#include "board.h"这个问题解决。
解决:1. 先看下工程路径是不是有中文。
2. 将编译目录下所有的.o.d文件全部删除,重新编译生成即可以解决。
右击.ioc的工程文件,选择用笔记本打开,找到ProjectManager.MainLocation=Src,去掉src前的core目录即可。