1. 中断函数不要随意使用prinf()函数
记调试步进电机加速减速过程的一次大坑。
2. 使用HAL库的时候不要在中断中使用HAL_Delay()函数
HAL库的HAL_Delay()函数是通过Systick定时器的1ms中断实现的,一般情况下Systick定时器的优先级设置为最低,因此在更高优先级的中断触发后导致HAL_Delay()函数uwtick值无法更新,因此程序会卡死在HAL_Delay()函数中。
3.注意STM32库在配置串口字长时是包含校验位的字长,而一般上位机配置的串口字长是不包含校验位的。
这点在配置使用校验时是非常重要的,如果配置出错会导致通讯不正常。
4.使用不同的开发板的时候一定要注意不同板子上的晶振可能是不一样的
之前用的板子是8M的晶振,配置好了可以正常使用。后面换了板子是25M晶振的。只修改了SystemClock_Config()函数中的因子,忘记修改晶振配置的值,导致时钟频率一直不对。晶振不同时,一定要到stm32xxxx_hal_conf.h中修改HSE_VALUE为相应的晶振值
5.移植FreeRTOS,让stm32hal和freeRTOS共用SYSTICK,程序全速运行会卡死在hardfault中断,但单步调试可以运行过去
在之前的板子上可以运行,但在后面新作的板子上出现了这个问题。(这一点感觉好奇怪)
systick中断代码:
void SysTick_Handler(void)
{
HAL_IncTick();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
#endif /* INCLUDE_xTaskGetSchedulerState */
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
#endif /* INCLUDE_xTaskGetSchedulerState */
}
在stm32f4xx_it.c文件中一定要包含FreeRTOS.h头文件,否则会导致上述函数中条件编译的宏不会生效,导致在还没开启任务调度时,触发SysTick中断后会直接进入xPortSysTickHandler()函数,导致触发了hardfault中断。
6. STM32F429使用TIM2和TIM5的的注意事项
TIM2和TIM5是32位定时器,TIM2和TIM5产生PWM并通过DMA传输时必须按32位传输(即DMA设置的长度位32位)且用于为输出比较寄存器赋值的数组也必须为32为的(在使用TIM2和定时器5驱动WS2812时一定要注意)。
-
注:移植之前的ws21812灯珠驱动程序(之前用的是TIM3属于16位寄存器),改到TIM2来驱动用逻辑分析仪一直没有测到输出波形,又测试了TIM5也是这样还以为TIM2和TIM5的PWM不能够通过DMA传输呢!这个事情告诉我们一定要认真读手册
7. STM32F429不能够通过PA1和PA2输出PWM
https://blog.csdn.net/xiaoyuanwuhui/article/details/109597401中有记录
8. STM32的部分外设在初始化初始化函数只能执行1次!!!
在使用STM32ADC外设时,红外测距模块和电流采样模块都用到了ADC,因而在两个模块分别初始化的时候调用了两次ADC初始化的函数bsp_adc1Init(),导致电流检测数据不正常(实际硬件测量没有电压,但ADC的采样值却有500多的值(实际应该在10左右))。在屏蔽掉红外测距模块的初始化函数后,数据便恢复正常了。
解决方法:仿照crazyfile代码中硬件外设初始化的方法,定义一个isInit的变量用于指示当前外设初始化函数是否执行过,如果执行过则直接跳出。
static bool isInit = false;
void bsp_adc1Init(void) {
if(isInit) {
return;
}
/* init adc module */
//...
isInit = ture;
}
采用上述方式,可以防止adc外设被重复初始化,因此可以避免上面出现的问题,又可以很好的保证红外测距模块和电流采样模块的独立性和完整性。
1. 中断函数不要随意使用prinf()函数
记调试步进电机加速减速过程的一次大坑。
2. 使用HAL库的时候不要在中断中使用HAL_Delay()函数
HAL库的HAL_Delay()函数是通过Systick定时器的1ms中断实现的,一般情况下Systick定时器的优先级设置为最低,因此在更高优先级的中断触发后导致HAL_Delay()函数uwtick值无法更新,因此程序会卡死在HAL_Delay()函数中。
3.注意STM32库在配置串口字长时是包含校验位的字长,而一般上位机配置的串口字长是不包含校验位的。
这点在配置使用校验时是非常重要的,如果配置出错会导致通讯不正常。
4.使用不同的开发板的时候一定要注意不同板子上的晶振可能是不一样的
之前用的板子是8M的晶振,配置好了可以正常使用。后面换了板子是25M晶振的。只修改了SystemClock_Config()函数中的因子,忘记修改晶振配置的值,导致时钟频率一直不对。晶振不同时,一定要到stm32xxxx_hal_conf.h中修改HSE_VALUE为相应的晶振值
5.移植FreeRTOS,让stm32hal和freeRTOS共用SYSTICK,程序全速运行会卡死在hardfault中断,但单步调试可以运行过去
在之前的板子上可以运行,但在后面新作的板子上出现了这个问题。(这一点感觉好奇怪)
systick中断代码:
void SysTick_Handler(void)
{
HAL_IncTick();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
#endif /* INCLUDE_xTaskGetSchedulerState */
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
#endif /* INCLUDE_xTaskGetSchedulerState */
}
在stm32f4xx_it.c文件中一定要包含FreeRTOS.h头文件,否则会导致上述函数中条件编译的宏不会生效,导致在还没开启任务调度时,触发SysTick中断后会直接进入xPortSysTickHandler()函数,导致触发了hardfault中断。
6. STM32F429使用TIM2和TIM5的的注意事项
TIM2和TIM5是32位定时器,TIM2和TIM5产生PWM并通过DMA传输时必须按32位传输(即DMA设置的长度位32位)且用于为输出比较寄存器赋值的数组也必须为32为的(在使用TIM2和定时器5驱动WS2812时一定要注意)。
-
注:移植之前的ws21812灯珠驱动程序(之前用的是TIM3属于16位寄存器),改到TIM2来驱动用逻辑分析仪一直没有测到输出波形,又测试了TIM5也是这样还以为TIM2和TIM5的PWM不能够通过DMA传输呢!这个事情告诉我们一定要认真读手册
7. STM32F429不能够通过PA1和PA2输出PWM
https://blog.csdn.net/xiaoyuanwuhui/article/details/109597401中有记录
8. STM32的部分外设在初始化初始化函数只能执行1次!!!
在使用STM32ADC外设时,红外测距模块和电流采样模块都用到了ADC,因而在两个模块分别初始化的时候调用了两次ADC初始化的函数bsp_adc1Init(),导致电流检测数据不正常(实际硬件测量没有电压,但ADC的采样值却有500多的值(实际应该在10左右))。在屏蔽掉红外测距模块的初始化函数后,数据便恢复正常了。
解决方法:仿照crazyfile代码中硬件外设初始化的方法,定义一个isInit的变量用于指示当前外设初始化函数是否执行过,如果执行过则直接跳出。
static bool isInit = false;
void bsp_adc1Init(void) {
if(isInit) {
return;
}
/* init adc module */
//...
isInit = ture;
}
采用上述方式,可以防止adc外设被重复初始化,因此可以避免上面出现的问题,又可以很好的保证红外测距模块和电流采样模块的独立性和完整性。
举报