stm32 U5 IAP 写 flash 进入 HardFault_Handler

需求 在用 stm32u5 芯片,调试 iap 的时候,在写 flash 的过程中,进入了 hardfault. 解决 因为 STM32U5 没有官方的 IAP demo,所以使用的是 STM32F4 的 IAP 移植过来的。 经过调试和查资料,发现 STM32U5 在写 flash 的时候,只支持 quad word, 而 STM32F4 是直接写 word, 所以所有涉及到 flash 的写入,数量计算,循环次数等等,从前到后,全部需要按照 quad 来进行修改才行。 参考 STM32 写Flash进入HardFault_Handler,一次解决经验分享 STM32 FLASH error: FLASH_FLAG_PGPERR & FLASH_FLAG_PGSERR

<span title='2024-02-07 17:13:00 +0800 CST'>2024-02-07</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;44 words&nbsp;·&nbsp;RamLife

stm32 rtc 设置数据不正常

需求 stm32 使用 hal 设置 rtc 时间之后,再读出来发现,年的数据不对,其他数据是正常的。 解决 经过多次调试,发现问题是出现在 weekend 的设置上面。如果不设置 weekend,会导致随即值在左移的时候,会干扰的年份。 在寄存器中 weekend 只有3位,如果 weekend 中的随即值超过 8,就会干扰年份了。 解决的方法也很简单,要不就是用公式计算出 weekend,要不就是直接设置 weekend 为 0 即可。 参考 stm32 - HAL_SetDate 将年份设置为错误的值 使用HAL的RTC库出现年、小时不准确的问题 关于HAL库读写RTC——时间错乱问题整改

<span title='2023-12-30 14:33:00 +0800 CST'>2023-12-30</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;31 words&nbsp;·&nbsp;RamLife

stm32u5 qspi 读写 w25q128 timeout

需求 使用 STM32U575 主控芯片,使用 QSPI 读写 W25Q128,简单的读写测试没有问题。但是在后面调试中发现,当按照 11 个字节一组进行读写,从 4352 这个地址开始写,写入到 4605 的时候,就超时状态了。 HAL_OSPI_STATE_ERROR 然后我单独从 4605 写入 11 个字节,确实会超时,但是前面写入并没有超时,很奇怪。 然后,我测试了一下,从0开始写,每次写 11 个字节,当从 1023 开始写入 11 个字节会超时。感觉好像是在 256字节的页边界出写入会出问题,但是又不是每个 256 边界都会出问题。 解决 先使用 16个字节为一组进行测试,没有跨界问题。然后又使用了4字节写入,写入了 400多万组,也没有任何问题。 这基本就说明了,是软件或者库的某个层面,因为32位对齐产生的这个 bug. 解决的方法也很简单,我原来写入 11 个字节是对结构体使用了 pragma pack(1) ,只要不用这个字节对齐命令,编译器会自动进行 32位对齐,重新测试,数据就可以正常读写,没有问题了。 参考 stm32: QSPI flash driver concurrent access issue STM32L4使用QSPI驱动spiFLASH(W25Q64) {SPI/QSPI} 正确理解STM32H7驱动QSPI W25Q手册中时钟后缀1-2-2,1-4-4等代表的含义 AN4760 Quad-SPI interface on STM32 microcontrollers and microprocessors HAL_QSPI_AutoPolling() fail when polling the SR of NOR flash in QPI mode Stm32h7 Hal qspi autpolling timeout stm32u575rit6 qspi driver ST external loader learning w25q flash series part 8 quadspi external loader

<span title='2023-12-28 16:47:00 +0800 CST'>2023-12-28</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;94 words&nbsp;·&nbsp;RamLife

stm32 rtc 读取数据不正常

需求 stm32 使用 hal 读取 rtc 数据时,发现数据读取要不是 0,要不就不变,比较奇怪。 解决 经过多次调试并查看源码,才发现,API的注释里面写了,需要先调用 HAL_RTC_GetTime, 再调用 HAL_RTC_GetDate, 才行,否则就不行。因为先读取 time 可以解锁读取。 =You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values in the higher-order calendar shadow registers to ensure consistency between the time and date values.= 参考 HAL库使用RTC设置时间显示日期不符的解决办法 STM32】HAL库 STM32CubeMX教程十三—RTC时钟 STM32电子万年历制作详解(RTC实战) 【经验分享】STM32实例-RTC实时时钟实验③-RTC设置日期时间函数 【STM32】HAL库 STM32CubeMX教程十三—RTC时钟 STM32H750中RTC简介及使用方法 STM32CubeMX学习笔记——STM32H743_RTC

<span title='2023-12-12 17:44:00 +0800 CST'>2023-12-12</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;51 words&nbsp;·&nbsp;RamLife

STM32 DMA2D 使用

需求 stm32 使用 dma2d 来加速显示 解决 DMA2D 的优点 主要就是图像中的局部矩形区域的硬件数据传输。比 DMA 的好处,就是局部矩形区域中,换行的时候,自动计算地址,并转到局部区域第二行的首地址。 其他的就是颜色格式转换和透明度混合。 DMA2D 加速 lcd 显示 DMA2D 加速 LCD 显示的前提是,LCD 的驱动是硬件驱动,比如说,使用 FMC 或者 LTDC 之类的硬件驱动 LCD,程序只需要向地址写入数据,就可以显示。 能够加速的主要是: 图像数据,直线,清屏等。主要需要实现的其实就是两个函数: Dma2dCopy, Dma2dFill. // fill color void Dma2dFill(void * dest, uint32_t width, uint32_t height, uint32_t line_offset, uint32_t color, uint32_t pixel_format) { DMA2D->CR = DMA2D_R2M;//0x00030000UL | (1 << 9); DMA2D->OCOLR = color; DMA2D->OMAR = (uint32_t)dest; DMA2D->OOR = line_offset; DMA2D->OPFCCR = pixel_format; //LTDC_PIXEL_FORMAT_RGB565; DMA2D->NLR = (uint32_t)(width << 16) | (uint16_t)height; DMA2D->CR |= DMA2D_CR_START; while (DMA2D->CR & DMA2D_CR_START) {} } // copy color data void Dma2dCopy(void * dest, const void * src, uint32_t width, uint32_t height, uint32_t dest_line_offset, uint32_t src_line_offset, uint32_t pixel_format) { DMA2D->CR = DMA2D_M2M;//0x00000000UL | (1 << 9); DMA2D->FGMAR = (uint32_t)src; DMA2D->OMAR = (uint32_t)dest; DMA2D->FGOR = src_line_offset; DMA2D->OOR = dest_line_offset; DMA2D->FGPFCCR = pixel_format; //LTDC_PIXEL_FORMAT_RGB565; DMA2D->OPFCCR = pixel_format; //LTDC_PIXEL_FORMAT_RGB565; DMA2D->NLR = (uint32_t)(width << 16) | (uint16_t)height; DMA2D->CR |= DMA2D_CR_START; while (DMA2D->CR & DMA2D_CR_START) {} } DMA2D 加速显存 主要是用在实现各种 gui 的接口函数,实现中用于加速内存复制和颜色混合。...

<span title='2023-11-22 18:59:00 +0800 CST'>2023-11-22</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;167 words&nbsp;·&nbsp;RamLife

stm32使用FMC控制 LCD 时,图像不正常

需求 stm32 使用 fmc 来控制 Lcd 显示时,碰到了两个问题: 图像变小了,并且是双份显示 屏幕只显示了 4/5,最下面花屏 解决 经过网络搜索和反复的调试,终于找到问题。 图像变小 这个是 fmc 的时序配置有问题,导致使用 DMA2D 进行数据传输时,lcd 会丢数据,然后图像就变小了。这个解决只需要对照 lcd 的芯片中的时间参数,重新设置 fmc 的时序参数即可解决。 图像只显示 4/5 这个是 FMC 的地址线的问题。 我们需要重新考虑一下为什么可以使用 fmc 来控制 lcd 显示,理论上来说, DMA2D 写入数据的时候,地址是自动增长的啊! 其实因为我们只使用了一根地址线,那么写入数据的时候,这个地址线的低位就算增长也没有关系,毕竟我们只使用了最高位作为地址线,只要使用 DMA2D 写入的数据不会超过最高位,那么就不会有影响。 所以这次的错误就是 DMA2D 在全屏写入的时候, 320*240 = 76800, 而当前的地址线使用的是 A16,那么能够提供的空间只有 2的16次方 = 65536,已经溢出了。解决的方法也很简单,使用 A17 地址线即可。 参考 DMA2D skips pixels when sending directly to display over FMC STM32 FMC Display STM32的FSMC时序解析 【12】、STM32F767——————>FMC之LCD屏 STM32H755BIT DMA2D + FMC + External SRAM Write Issue

<span title='2023-11-22 18:59:00 +0800 CST'>2023-11-22</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;76 words&nbsp;·&nbsp;RamLife

stm32 串口帧空闲中断接收大量数据

需求 串口使用普通的接收中断 HAL_UART_Receive_IT 在接收比较少的字节,并且中断处理非常简单的情况下还行,一旦需要接收大量的数据,并且中断处理稍微复杂一些,就会造成丢数据的情况。需要解决这个情况。 解决 解决的办法就是使用帧空闲中断 HAL_UARTEx_ReceiveToIdle_IT 来接收一大堆数据,配套的 callback 函数是 HAL_UARTEx_RxEventCallback. void MainInit() { HAL_UARTEx_ReceiveToIdle_IT(&huart2, uart_web.get_rx_buf(), UartWeb::kRxBufLength); } void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (huart->Instance == USART2) { LOGD("HAL_UARTEx_RxEventCallback: USART2"); if (uart_web.Receive(Size)) { main_status = kMainWebReceive; } //HAL_UART_Receive_IT(&huart2, &uart_web_tmp, 1); HAL_UARTEx_ReceiveToIdle_IT(&huart2, uart_web.get_rx_buf(), UartWeb::kRxBufLength); } } 参考 stm32 HAL库 笔记——HAL_UARTEx_ReceiveToIdle_IT STM32 非阻塞HAL_UART_Receive_IT解析与实际应用 【STM32】HAL库 STM32CubeMX教程四—UART串口通信详解 STM32CubeMX——串口数据收发基础(HAL 库)

<span title='2023-05-24 17:13:00 +0800 CST'>2023-05-24</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;56 words&nbsp;·&nbsp;RamLife

stm32 使用 flash 保存数据

需求 需要使用 stm32 内置的 flash 来保存数据. 解决 最快的方法就是参考官方例程,默认是在用户目录下面的 STM32Cube/Repository, 可以参考这个的例子去写。基本就分为 擦除,写入,读取 这三块。 注意: 擦除和写入都需要先 unlock, 操作完成之后,再 lock 一下。 注意: 需要更加手册确定好使用芯片的 flash sector 的排布,修改相关的宏定义,才能正常的操作。 参考 STM32 HAL库手册获取和查阅方法以及查看官方例程 STM32用HAL库写内部FLASH 【STM32+cubemx】0015 HAL库开发:内部flash读写 STM32系列(HAL库)——内部FLASH读写实验 STM32系列(HAL库)——内部FLASH读写实验_简约版 STM32 实现内部Flash的读写(HAL库版)

<span title='2023-05-24 17:13:00 +0800 CST'>2023-05-24</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;33 words&nbsp;·&nbsp;RamLife

stm32 在其他中断中使用 HAL_Delay

需求 因为 485 总线控制的时候,需要考虑在收发转换的时候,不能直接切换,应该让状态再保持一段时间,比如 2ms ,然后再进行切换,这样通讯会更加稳定。这就需要再收发中断里面使用延时,而最简单的延时就是 systick 的延时。但是实际上使用起来,这个延时工作不正常。 解决 出问题的原因也很简单,因为 st 默认让 systick 的中断优先级是最低,所以导致在其他中断中,使用 HAL_Delay, 内部的数值不变,所以一直困在中断里面。解决的方法也很简单,就是重新配置中断优先级,把 systick 的优先级提高到高于通信中断的优先级即可。 参考

<span title='2023-05-24 17:13:00 +0800 CST'>2023-05-24</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;19 words&nbsp;·&nbsp;RamLife

stm32 HAL_SYSTICK_Callback 生效

需求 今天调试的时候,发现通过 systick 的 callback 并没有被调用到,这个有问题。 解决 整体的调用流程是: SysTick_Handler -> HAL_SYSTICK_IRQHandler -> HAL_SYSTICK_Callback, 但是在最新生成的库函数中, SysTick_Handler 中没有默认调用 HAL_SYSTICK_IRQHandler, 所以需要手动在 HAL_IncTick 后添加。 void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ HAL_SYSTICK_IRQHandler(); /* USER CODE END SysTick_IRQn 1 */ } 参考 STM32 HAL_SYSTICK_Callback() 失效 无效

<span title='2023-05-21 17:13:00 +0800 CST'>2023-05-21</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;59 words&nbsp;·&nbsp;RamLife