标签 STM32 下的文章

stm32f429使用 stm32cube 自动生成 eth 代码的时候,运行出现 FLASH_FLAG_PGSERR 错误。 见过调试发现,MX_ETH_Init 中没有对指针进行赋值,就直接写入了,所以出错。 进行下面的修改。

/* USER CODE BEGIN 0 */
static uint8_t macAddr[6];
void MX_ETH_VarInit(void)
{
    heth.Init.MACAddr = macAddr;
}
/* USER CODE END 0 */
/* USER CODE BEGIN Prototypes */
void MX_ETH_VarInit(void);
/* USER CODE END Prototypes */
  /* USER CODE BEGIN SysInit */
  MX_ETH_VarInit();
  /* USER CODE END SysInit */

stm32cubeide 是基于 eclipse 开发的软件,所以修改和 eclipse 类似,只要在 window --> perference --> keys 里面把 content assist 这个功能绑定到自己喜欢的按键即可。默认是 ctrl + space,我比较喜欢替换为 alt + /, 因为 alt + / 这个是 word completion,感觉比较鸡肋,所以直接替换掉。

首先正常安装芯片包,然后在设置里面找到当前包存放的位置,默认是: C:\Users\Administrator\STM32Cube\Repository

然后解压 更新包,把更新包里面的文件覆盖到 C:\Users\Administrator\STM32Cube\Repository 这个里面,重新打开 cubemx,就可以看到显示的是新的芯片包了。

今天使用 systick 的时候,只使用了头文件 core_cm4.h,结果就报错了,原因是 __FPU_PRESENT 没有定义,这个定义其实在 stm32f4xx.h 里面。所以如果要解决这个错误,有两种方法:

  1. 只使用 core_cm4.h,然后碰到所有未定义的,都手动定义,或者添加相应的头文件。
  2. 不使用 core_cm4.h,使用 stm32f4xx.h。

比较起来,1 需要包含的头文件比较少,但是操作比较繁琐,2 需要的操作比较少,相应包含的头文件就比较多了。

使用 stm32f4 调试uart 接收, 使用 空闲中断,dma 双缓冲模式,有以下几点需要注意的。

  1. 调试的时候断点不要打在 if (USART_GetITStatus(USART6, USART_IT_IDLE) != RESET) 这种语句上面,要打在 if 的代码块里面。mdk 调试的时候,会出现一些 bug,当在 if (USART_GetITStatus(USART6, USART_IT_IDLE) != RESET) 断点的时候,能够看到 idle 信号出现,但是只要向下执行,不管是单步还是怎样,下一步的时候 idle 标志位就会消失。导致进不了空闲中断处理语句。但是如果断点打在代码块里面,就能够正常进入了。

  2. 使用双缓冲的时候, DMA_DoubleBufferModeConfig, DMA_DoubleBufferModeCmd 需要放在 DMA_Cmd 前面,还有别忘了 开启 circular 模式。

  3. 接收的时候,已经接收的字节数,等于 buffersize - ndtr 的结果。

  4. 开启双缓冲的时候,可以不用 disable dma,只需要在 空闲中断里面,识别出 ndtr 和 ct,然后经过计算得出本次传送的数据个数,并把本次开始的地址和数据个数记录下来,就可以由非中断部分程序来读取这一帧接收的数据。

  1. 按键和 IO 之间连接一个 1K 电阻,可以防止当 IO 被配置为高电平输出的时候,按下按键,导致 VDD 和 GND 直接连通。

stm32h7xx_hal_conf.h 中需要注意的几个地方:

  1. HSE_VALUE 这个外接晶振的频率

  2. TICK_INT_PRIORITY 这个 tick 的中断优先级,因为 HAL_DELAY 这个函数是基于这个 tick 的中断的,所以如果有其他高优先级的中断中调用了 HAL_DELAY 函数,会造成 tick 的中断一直进不来。这样的话 HAL_DELAY 也会一直卡住,这个高优先级的中断也会一直卡在这里。

  3. 断言的参考实现函数。

    /* 
    ********************************************************************************************************* 
    *  函 数 名: assert_failed 
    *  形    参:file : 源代码文件名称。关键字__FILE__表示源代码文件名。 
    *        line :代码行号。关键字 __LINE__ 表示源代码行号 
    *  返 回 值: 无 
    ********************************************************************************************************* 
    */ 
    void assert_failed(uint8_t* file, uint32_t line) 
    {  
    /*  
    用户可以添加自己的代码报告源代码文件名和代码行号,比如将错误文件和行号打印到串口 
    printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 
    */ 
    
    /* 这是一个死循环,断言失败时程序会在此处死机,以便于用户查错 */ 
    while (1) 
    { 
    } 
    } 
  4. HAL 库不像之前的标准库,在系统启动函数 SystemInit 里面做了 RCC 初始化,HAL 库是没有做的,所以进入到 main 函数后,系统还在用内部高速时钟 HSI,对于 H7 来说,HSI 主频是 64MHz。

  5. HAL_MspInit 和 HAL_MspDeInit 在 stm32h7xx_hal_msp.c 里面做具体实现。

  6. PA0_C 这类的引脚只有在 TFBGA240+25 ballout 这种封装上面才有。

  7. LSE Bypass 和 LSE On 之间的切换,必须要先关闭 LSE 才行。同样 HSE Bypass 和 HSE On 之间的切换,也必须先关闭 HSE 才行。

  8. HAL_RCC_OscConfig 会更新全局变量 SystemCoreClock 的主频值,并且会再次调用函数 HAL_InitTick 更新系统滴答时钟。