Simulink开发STM32环境配置注意事项,自动生成代码无法正常实现功能分析
最近做PIL,记录一些过程,备忘
1.环境配置的注意事项
- 需要的软件包括
MATLAB ,我的是2018b
STM32MAT
Java
STM32CubeMX,我下载的是5.3版本
STM32F1库,注意是用于STM32CubeMX,不是Keil,可以在软件中自动下载,但速度呵呵,还没有断点续传功能…,所以,还是在ST官网注册帐号下载吧
Keil v5 - STM32CubeMX建立的项目文件不要位于中文目录下,否则无法生成keil项目
- Simulink文件最好与STM32CubeMx文件放于同一目录下
- 在Simulink的仿真设置中选择Custom Processor,否则会报Invalid path
2.自动生成代码无法正常实现功能分析
搭建完环境后,首先进行测试,按照https://blog.csdn.net/leonsust/article/details/81908255的简单教程,结果没有输出正确结果,一步一步在Keil中调试,
- 在进入while循环后,程序停止在if (remainAutoReloadTimerLoopVal_S == 0) 处,变量remainAutoReloadTimerLoopVal_S一直等于1,只有当这个变量等于0后,后面的具体算法才会执行
if (remainAutoReloadTimerLoopVal_S == 0) {
- 在main.c中,发现在void HAL_SYSTICK_Callback(void)函数中,对该变量进行了操作,使其减1,因此,正常情况下应在某个地方调用了这个函数
void HAL_SYSTICK_Callback(void)
{
/* For TIME OUT processing */
HAL_IncTick();
/* Manage nb of loop before interrupt has to be processed */
if (remainAutoReloadTimerLoopVal_S) {
remainAutoReloadTimerLoopVal_S--;
}
}
- 在文件stm32f1xx_hal_cortex.c,void HAL_SYSTICK_IRQHandler(void)函数调用了void HAL_SYSTICK_Callback(void),另外,在void HAL_SYSTICK_IRQHandler(void)的下方还有一个__weak void HAL_SYSTICK_Callback(void),__weak修饰的函数表示在用户没有自己定义void HAL_SYSTICK_Callback(void)时,会调用__weak后面的函数。
void HAL_SYSTICK_IRQHandler(void)
{
HAL_SYSTICK_Callback();
}
- 再次查找,发现文件中没有调用的void HAL_SYSTICK_IRQHandler(void)的地方
- 从名称上看,void HAL_SYSTICK_IRQHandler(void)应该与STM32的Systick中断有关,调试程序,发现程序配置了系统时钟,同时开启了中断,然而,原始的Systick中断函数为
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
看来,似乎应该在这个函数中干点事。
7. 百度一下,发现在一些STM32CubeMX的代码中,SysTick_Handler函数中调用了void HAL_SYSTICK_IRQHandler,因此,将其添加进去
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
// HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
编译,仿真,IO口成功输出方波信号。
系统调用Systick主要是作为时基,这个时基大概与Simulink中设置的仿真步长有关,因为,在Simulink模型中我设置的方波周期为1s,高电平占比为50%,仿真步长设置的是0.001s,在生成的代码的算法部分,有
test_B.PulseGenerator = ((test_DW.clockTickCounter < 500) &&
(test_DW.clockTickCounter >= 0));
if (test_DW.clockTickCounter >= 999) {
test_DW.clockTickCounter = 0;
} else {
test_DW.clockTickCounter++;
}
Systick每中断一次,将remainAutoReloadTimerLoopVal_S设置为自动重装载值autoReloadTimerLoopVal_S,然后执行一次xx_step()算法,然后不断重复。
但是,为什么软件没有生成正确代码,仍未找到原因。