打印
[STM32F4]

使用串口DMA更新W25Q28利用Half中断(STM32F412)

[复制链接]
1960|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
9块9包邮|  楼主 | 2018-4-9 18:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
      最近在玩412,这款在CUBEMX上很便宜的芯片,结果拿到样品之后,采购告诉我要6个美金,哭晕在厕所。 CUBEMX 不能相信价格啊。
      言归正传,最近需要大存储量更新外部flash,利用的是华邦的w25系列。  拟解决的方案有以下几个:
1.采用大数组进行先整体发送到串口然后再整体烧写外部FLASH
2.利用两个数组交替存储的方式写入外部FLASH(不使用DMA)
3.利用DMA 双缓冲的方式
4.利用HALF中断和全部完成中断的方式
首先第一个方案,测试之后丢失数据严重,PASS;
第二个方案,人为模拟双缓冲,太冗余,PASS(代码能力有限)
第三个方案,在利用HAL库的双缓冲的时候出现了一些问题,最终放弃掉了。
出现的问题:
HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength);
这个函数 的解释        Starts the multi_buffer DMA Transfer with interrupt enabled.  只要开启DMA中断就可以实现 ,
函数里面有一句
  /* Memory-to-memory transfer not supported in double buffering mode */
  if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
  {
    hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
    return HAL_ERROR;
  }

两个内存之间不可以用这种方式通信, 但是我的DMA配置是  hdma_usart6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; 从外设到内存
然而还是返回 HAL_ERROR . 我的SRCAddress的地址是USART6->DR,这个是内存地址? 这个还有待解决,为此,我就把这个方案pass了。。

最后我想到了half中断,一个half中断和 完成中断, 中断两次,我们可以利用一个数组就解决了双缓冲的问题。
在这里我参考了 原子哥的flash驱动,以及开源电子网的1201yuge 这个楼主的方法。
  先测了写入flash的时间,然后开始更新数据,更新的方法在原来的基础上做了改动,可以一直更新数据。
在更新开始之前要先将需要的扇区擦除。之后再写入。

主要思想:
先定义一个8192字节的数组,在一个HALF中断或者完成中断来来之后,开始更新数据。最后将最后一部分的DMA数据写入FLASH。

DMA配置的注意事项
  hdma_usart6_rx.Init.Mode = DMA_CIRCULAR;环形模式
__HAL_LINKDMA(huart,hdmarx,hdma_usart6_rx);  将DMA和USART RX连接
HAL_UART_Receive_DMA(&huart6,USART6_RX_Buf3,8192);//开启DMA中断接收
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//USART 完成回调
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)USART HAL回调

工程文件太大,上传不了论坛
需要的可以私信我,我传到网盘了。

希望大家对双缓冲有理解的多多交流,





沙发
mmuuss586| | 2018-4-9 21:39 | 只看该作者
不错,感谢楼主分享;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

0

粉丝