找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 340|回复: 13
打印 上一主题 下一主题
收起左侧

W25Q32存储数据时,上位机串口通信异常怎么解决?

[复制链接]
回帖奖励 10 黑币 回复本帖可获得 1 黑币奖励! 每人限 1 次
跳转到指定楼层
楼主
ID:1104941 发表于 2024-2-29 19:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
每次往25Q32存储256字节数据,看手册貌似要200MS(擦除时间久),这是时间上位机有命令来的话,执行串口中断,会有通信异常。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1111855 发表于 2024-2-29 20:23 | 只看该作者
数据发送中间歇性数据异常漏发乱发
回复

使用道具 举报

板凳
ID:458247 发表于 2024-3-1 08:43 | 只看该作者
1、如果单片机有dma功能,则用dma接收串口数据
2、25Q32看能不能用状态机编程,删除指令发出后不死等,等到下次执行时判断有没有擦除成功,若擦除成功了再进行写操作
3、25Q32的删除操作看看能不能在程序初始化的时候就做好
回复

使用道具 举报

地板
ID:370824 发表于 2024-3-1 08:45 | 只看该作者
1. 200ms擦除时间不需要mcu一直干预,执行完擦除指令,就退出来。2. 通讯采用中断模式,若硬件有独立自缓存区可以使用查询模式,不会影响与上位机通讯。
回复

使用道具 举报

5#
ID:636806 发表于 2024-3-1 10:19 | 只看该作者
1、提前擦除扇区;2、实在避免不了擦除的时间,就先将数据缓存下来,擦除完成后再将缓存数据写入
回复

使用道具 举报

6#
ID:1104941 发表于 2024-3-1 14:01 | 只看该作者
臭狮子 发表于 2024-3-1 10:19
1、提前擦除扇区;2、实在避免不了擦除的时间,就先将数据缓存下来,擦除完成后再将缓存数据写入

好的,目前参照这个做着
回复

使用道具 举报

7#
ID:1104941 发表于 2024-3-1 14:03 | 只看该作者
yzw846562238 发表于 2024-3-1 08:43
1、如果单片机有dma功能,则用dma接收串口数据
2、25Q32看能不能用状态机编程,删除指令发出后不死等,等 ...

受教了,因为收到串口命令有涉及计算操作,感觉DMA不能用。状态机编程我看下好不好实现
回复

使用道具 举报

8#
ID:1111904 发表于 2024-3-1 14:04 | 只看该作者
执行完擦除指令后,读取状态寄存器,判断是否擦除完成,然后再进行写入数据
回复

使用道具 举报

9#
ID:1104941 发表于 2024-3-1 14:09 | 只看该作者
JACKRENYONG 发表于 2024-3-1 08:45
1. 200ms擦除时间不需要mcu一直干预,执行完擦除指令,就退出来。2. 通讯采用中断模式,若硬件有独立自缓存 ...

/**
  * @brief  等待WIP(BUSY)标志被置0,即等待到FLASH内部数据写入完毕
  * @param  none
  * @retval none
  */
void SPI_FLASH_WaitForWriteEnd(void)
{
  u8 FLASH_Status = 0;

  /* 选择 FLASH: CS 低 */
  SPI_FLASH_CS_LOW();

  /* 发送 读状态寄存器 命令 */
  SPI_FLASH_SendByte(W25X_ReadStatusReg);

  /* 若FLASH忙碌,则等待 */
  do
  {
                /* 读取FLASH芯片的状态寄存器 */
    FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);         
  }
  while ((FLASH_Status & WIP_Flag) == SET);  /* 正在写入标志 */

  /* 停止信号  FLASH: CS 高 */
  SPI_FLASH_CS_HIGH();
}
这个是我25Q32擦除后等待擦除完毕的函数,没有试过不等待直接退出的。我测试一下。
采用中断的话,我担心正在写入数据时,串口中断来了,写进去的数据异常。
回复

使用道具 举报

10#
ID:401564 发表于 2024-3-1 15:42 | 只看该作者
这个实际上是你程序的问题,就算是死等,中断也不全影响到W25Q32的写入的,它对最慢时钟是没有要求的,一秒钟一个时钟都可以
这可能是你中断中有改变W25Q32的操作,这才会影响到的
回复

使用道具 举报

11#
ID:1104941 发表于 2024-3-2 09:29 | 只看该作者
Y_G_G 发表于 2024-3-1 15:42
这个实际上是你程序的问题,就算是死等,中断也不全影响到W25Q32的写入的,它对最慢时钟是没有要求的,一秒钟一 ...

谢谢你的解疑,可以请教一下吗?
1.W25Q32在写过程中,来了中断会影响保存的数据吗?(中断没有操作25Q32)
2.目前中断确实有操作25Q32的代码,主循环每隔一段时间存储数据,串口中断收到对应命令,有操作25Q32。
目前是先等操作完再回应上位机,我担心不在中断中操作25Q32,先回应上位机再操作25Q32的话,马上又有中断来,还是会影响。
回复

使用道具 举报

12#
ID:401564 发表于 2024-3-2 11:47 | 只看该作者
bstljq 发表于 2024-3-2 09:29
谢谢你的解疑,可以请教一下吗?
1.W25Q32在写过程中,来了中断会影响保存的数据吗?(中断没有操作25Q3 ...

1,中断不会影响W25Q32的操作,不管是时钟低电平时触发中断还是字节只写了一半,中断都不会影响的
2,如果是中断中要有对W25Q32的操作,正确的作法是设置一个标志位,每次中断只触发标志位,但不能直接对W25Q32进行操作
在主函数中检测标志位,等到上一次W25Q32操作完成之后,再进行操作,在子函数中清除标志位
上位机操作一般就是这样的,单片机检测到上位机的命令之后,不直接操作的,先标志一个标志位,再在主函数中检测标志位,然后在对应的函数中清除标志位
回复

使用道具 举报

13#
ID:1104941 发表于 2024-3-2 18:58 | 只看该作者
Y_G_G 发表于 2024-3-2 11:47
1,中断不会影响W25Q32的操作,不管是时钟低电平时触发中断还是字节只写了一半,中断都不会影响的
2,如果是 ...

谢谢了,按照你的思路有改善。
目前有个难以理解的问题,我现在是在25Q32取出一片区域,这个区域分成N块,每块写入256字节。每次写之前读取该块的前8个字节,计算8字节累加和判断是不是0XFF来确认是否已经擦除了。
现在的现象是,如果是上电使用整片擦除,后续存储数据读出来的8字节都没问题,验证都通过。
如果我是在单个扇区擦除,然后读出8字节,就会检验失败。一个扇区里面有16个256字节的数据块,起码2个以上都是校验失败的,其他的的校验成功。
扇区擦除加了读BUSY状态等待,而且后续还加了50MS软件延迟,还是会出现问题。
回复

使用道具 举报

14#
ID:1104941 发表于 2024-3-2 18:59 | 只看该作者
Y_G_G 发表于 2024-3-2 11:47
1,中断不会影响W25Q32的操作,不管是时钟低电平时触发中断还是字节只写了一半,中断都不会影响的
2,如果是 ...

/**
  * @brief  擦除FLASH扇区
  * @param  SectorAddr:要擦除的扇区地址[24位地址,但是芯片会忽略掉低12位地址]
  * @retval 无
  */
void SPI_FLASH_SectorErase(u32 SectorAddr)
{
//        #ifdef DEBUG_PRINTF
//        printf("erase addr %x\r\n",SectorAddr);
//        #endif
  /* 发送FLASH写使能命令 */
  SPI_FLASH_WriteEnable();
  SPI_FLASH_WaitForWriteEnd();
  /* 擦除扇区 */
  /* 选择FLASH: CS低电平 */
  SPI_FLASH_CS_LOW();
  /* 发送扇区擦除指令*/
  SPI_FLASH_SendByte(W25X_SectorErase);
  /*发送擦除扇区地址的高位*/
  SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
  /* 发送擦除扇区地址的中位 */
  SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
  /* 发送擦除扇区地址的低位 */
  SPI_FLASH_SendByte(SectorAddr & 0xFF);
  /* 停止信号 FLASH: CS 高电平 */
  SPI_FLASH_CS_HIGH();
  /* 等待擦除完毕*/
  SPI_FLASH_WaitForWriteEnd();
}

/**
  * @brief  擦除FLASH扇区,整片擦除
        * 描述  :25Q32擦除一次要7-8秒
  * @param  无
  * @retval 无
  */
void SPI_FLASH_BulkErase(void)
{
  /* 发送FLASH写使能命令 */
  SPI_FLASH_WriteEnable();

  /* 整块 Erase */
  /* 选择FLASH: CS低电平 */
  SPI_FLASH_CS_LOW();
  /* 发送整块擦除指令*/
  SPI_FLASH_SendByte(W25X_ChipErase);
  /* 停止信号 FLASH: CS 高电平 */
  SPI_FLASH_CS_HIGH();

  /* 等待擦除完毕*/
  SPI_FLASH_WaitForWriteEnd();
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表