找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1679|回復(fù): 13
打印 上一主題 下一主題
收起左側(cè)

W25Q32存儲(chǔ)數(shù)據(jù)時(shí),上位機(jī)串口通信異常怎么解決?

[復(fù)制鏈接]
回帖獎(jiǎng)勵(lì) 10 黑幣 回復(fù)本帖可獲得 1 黑幣獎(jiǎng)勵(lì)! 每人限 1 次
跳轉(zhuǎn)到指定樓層
樓主
ID:1104941 發(fā)表于 2024-2-29 19:00 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
每次往25Q32存儲(chǔ)256字節(jié)數(shù)據(jù),看手冊(cè)貌似要200MS(擦除時(shí)間久),這是時(shí)間上位機(jī)有命令來的話,執(zhí)行串口中斷,會(huì)有通信異常。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:1111855 發(fā)表于 2024-2-29 20:23 | 只看該作者
數(shù)據(jù)發(fā)送中間歇性數(shù)據(jù)異常漏發(fā)亂發(fā)
回復(fù)

使用道具 舉報(bào)

板凳
ID:458247 發(fā)表于 2024-3-1 08:43 | 只看該作者
1、如果單片機(jī)有dma功能,則用dma接收串口數(shù)據(jù)
2、25Q32看能不能用狀態(tài)機(jī)編程,刪除指令發(fā)出后不死等,等到下次執(zhí)行時(shí)判斷有沒有擦除成功,若擦除成功了再進(jìn)行寫操作
3、25Q32的刪除操作看看能不能在程序初始化的時(shí)候就做好
回復(fù)

使用道具 舉報(bào)

地板
ID:370824 發(fā)表于 2024-3-1 08:45 | 只看該作者
1. 200ms擦除時(shí)間不需要mcu一直干預(yù),執(zhí)行完擦除指令,就退出來。2. 通訊采用中斷模式,若硬件有獨(dú)立自緩存區(qū)可以使用查詢模式,不會(huì)影響與上位機(jī)通訊。
回復(fù)

使用道具 舉報(bào)

5#
ID:636806 發(fā)表于 2024-3-1 10:19 | 只看該作者
1、提前擦除扇區(qū);2、實(shí)在避免不了擦除的時(shí)間,就先將數(shù)據(jù)緩存下來,擦除完成后再將緩存數(shù)據(jù)寫入
回復(fù)

使用道具 舉報(bào)

6#
ID:1104941 發(fā)表于 2024-3-1 14:01 | 只看該作者
臭獅子 發(fā)表于 2024-3-1 10:19
1、提前擦除扇區(qū);2、實(shí)在避免不了擦除的時(shí)間,就先將數(shù)據(jù)緩存下來,擦除完成后再將緩存數(shù)據(jù)寫入

好的,目前參照這個(gè)做著
回復(fù)

使用道具 舉報(bào)

7#
ID:1104941 發(fā)表于 2024-3-1 14:03 | 只看該作者
yzw846562238 發(fā)表于 2024-3-1 08:43
1、如果單片機(jī)有dma功能,則用dma接收串口數(shù)據(jù)
2、25Q32看能不能用狀態(tài)機(jī)編程,刪除指令發(fā)出后不死等,等 ...

受教了,因?yàn)槭盏酱诿钣猩婕坝?jì)算操作,感覺DMA不能用。狀態(tài)機(jī)編程我看下好不好實(shí)現(xiàn)
回復(fù)

使用道具 舉報(bào)

8#
ID:1111904 發(fā)表于 2024-3-1 14:04 | 只看該作者
執(zhí)行完擦除指令后,讀取狀態(tài)寄存器,判斷是否擦除完成,然后再進(jìn)行寫入數(shù)據(jù)
回復(fù)

使用道具 舉報(bào)

9#
ID:1104941 發(fā)表于 2024-3-1 14:09 | 只看該作者
JACKRENYONG 發(fā)表于 2024-3-1 08:45
1. 200ms擦除時(shí)間不需要mcu一直干預(yù),執(zhí)行完擦除指令,就退出來。2. 通訊采用中斷模式,若硬件有獨(dú)立自緩存 ...

/**
  * @brief  等待WIP(BUSY)標(biāo)志被置0,即等待到FLASH內(nèi)部數(shù)據(jù)寫入完畢
  * @param  none
  * @retval none
  */
void SPI_FLASH_WaitForWriteEnd(void)
{
  u8 FLASH_Status = 0;

  /* 選擇 FLASH: CS 低 */
  SPI_FLASH_CS_LOW();

  /* 發(fā)送 讀狀態(tài)寄存器 命令 */
  SPI_FLASH_SendByte(W25X_ReadStatusReg);

  /* 若FLASH忙碌,則等待 */
  do
  {
                /* 讀取FLASH芯片的狀態(tài)寄存器 */
    FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);         
  }
  while ((FLASH_Status & WIP_Flag) == SET);  /* 正在寫入標(biāo)志 */

  /* 停止信號(hào)  FLASH: CS 高 */
  SPI_FLASH_CS_HIGH();
}
這個(gè)是我25Q32擦除后等待擦除完畢的函數(shù),沒有試過不等待直接退出的。我測試一下。
采用中斷的話,我擔(dān)心正在寫入數(shù)據(jù)時(shí),串口中斷來了,寫進(jìn)去的數(shù)據(jù)異常。
回復(fù)

使用道具 舉報(bào)

10#
ID:401564 發(fā)表于 2024-3-1 15:42 | 只看該作者
這個(gè)實(shí)際上是你程序的問題,就算是死等,中斷也不全影響到W25Q32的寫入的,它對(duì)最慢時(shí)鐘是沒有要求的,一秒鐘一個(gè)時(shí)鐘都可以
這可能是你中斷中有改變W25Q32的操作,這才會(huì)影響到的
回復(fù)

使用道具 舉報(bào)

11#
ID:1104941 發(fā)表于 2024-3-2 09:29 | 只看該作者
Y_G_G 發(fā)表于 2024-3-1 15:42
這個(gè)實(shí)際上是你程序的問題,就算是死等,中斷也不全影響到W25Q32的寫入的,它對(duì)最慢時(shí)鐘是沒有要求的,一秒鐘一 ...

謝謝你的解疑,可以請(qǐng)教一下嗎?
1.W25Q32在寫過程中,來了中斷會(huì)影響保存的數(shù)據(jù)嗎?(中斷沒有操作25Q32)
2.目前中斷確實(shí)有操作25Q32的代碼,主循環(huán)每隔一段時(shí)間存儲(chǔ)數(shù)據(jù),串口中斷收到對(duì)應(yīng)命令,有操作25Q32。
目前是先等操作完再回應(yīng)上位機(jī),我擔(dān)心不在中斷中操作25Q32,先回應(yīng)上位機(jī)再操作25Q32的話,馬上又有中斷來,還是會(huì)影響。
回復(fù)

使用道具 舉報(bào)

12#
ID:401564 發(fā)表于 2024-3-2 11:47 | 只看該作者
bstljq 發(fā)表于 2024-3-2 09:29
謝謝你的解疑,可以請(qǐng)教一下嗎?
1.W25Q32在寫過程中,來了中斷會(huì)影響保存的數(shù)據(jù)嗎?(中斷沒有操作25Q3 ...

1,中斷不會(huì)影響W25Q32的操作,不管是時(shí)鐘低電平時(shí)觸發(fā)中斷還是字節(jié)只寫了一半,中斷都不會(huì)影響的
2,如果是中斷中要有對(duì)W25Q32的操作,正確的作法是設(shè)置一個(gè)標(biāo)志位,每次中斷只觸發(fā)標(biāo)志位,但不能直接對(duì)W25Q32進(jìn)行操作
在主函數(shù)中檢測標(biāo)志位,等到上一次W25Q32操作完成之后,再進(jìn)行操作,在子函數(shù)中清除標(biāo)志位
上位機(jī)操作一般就是這樣的,單片機(jī)檢測到上位機(jī)的命令之后,不直接操作的,先標(biāo)志一個(gè)標(biāo)志位,再在主函數(shù)中檢測標(biāo)志位,然后在對(duì)應(yīng)的函數(shù)中清除標(biāo)志位
回復(fù)

使用道具 舉報(bào)

13#
ID:1104941 發(fā)表于 2024-3-2 18:58 | 只看該作者
Y_G_G 發(fā)表于 2024-3-2 11:47
1,中斷不會(huì)影響W25Q32的操作,不管是時(shí)鐘低電平時(shí)觸發(fā)中斷還是字節(jié)只寫了一半,中斷都不會(huì)影響的
2,如果是 ...

謝謝了,按照你的思路有改善。
目前有個(gè)難以理解的問題,我現(xiàn)在是在25Q32取出一片區(qū)域,這個(gè)區(qū)域分成N塊,每塊寫入256字節(jié)。每次寫之前讀取該塊的前8個(gè)字節(jié),計(jì)算8字節(jié)累加和判斷是不是0XFF來確認(rèn)是否已經(jīng)擦除了。
現(xiàn)在的現(xiàn)象是,如果是上電使用整片擦除,后續(xù)存儲(chǔ)數(shù)據(jù)讀出來的8字節(jié)都沒問題,驗(yàn)證都通過。
如果我是在單個(gè)扇區(qū)擦除,然后讀出8字節(jié),就會(huì)檢驗(yàn)失敗。一個(gè)扇區(qū)里面有16個(gè)256字節(jié)的數(shù)據(jù)塊,起碼2個(gè)以上都是校驗(yàn)失敗的,其他的的校驗(yàn)成功。
扇區(qū)擦除加了讀BUSY狀態(tài)等待,而且后續(xù)還加了50MS軟件延遲,還是會(huì)出現(xiàn)問題。
回復(fù)

使用道具 舉報(bào)

14#
ID:1104941 發(fā)表于 2024-3-2 18:59 | 只看該作者
Y_G_G 發(fā)表于 2024-3-2 11:47
1,中斷不會(huì)影響W25Q32的操作,不管是時(shí)鐘低電平時(shí)觸發(fā)中斷還是字節(jié)只寫了一半,中斷都不會(huì)影響的
2,如果是 ...

/**
  * @brief  擦除FLASH扇區(qū)
  * @param  SectorAddr:要擦除的扇區(qū)地址[24位地址,但是芯片會(huì)忽略掉低12位地址]
  * @retval 無
  */
void SPI_FLASH_SectorErase(u32 SectorAddr)
{
//        #ifdef DEBUG_PRINTF
//        printf("erase addr %x\r\n",SectorAddr);
//        #endif
  /* 發(fā)送FLASH寫使能命令 */
  SPI_FLASH_WriteEnable();
  SPI_FLASH_WaitForWriteEnd();
  /* 擦除扇區(qū) */
  /* 選擇FLASH: CS低電平 */
  SPI_FLASH_CS_LOW();
  /* 發(fā)送扇區(qū)擦除指令*/
  SPI_FLASH_SendByte(W25X_SectorErase);
  /*發(fā)送擦除扇區(qū)地址的高位*/
  SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
  /* 發(fā)送擦除扇區(qū)地址的中位 */
  SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
  /* 發(fā)送擦除扇區(qū)地址的低位 */
  SPI_FLASH_SendByte(SectorAddr & 0xFF);
  /* 停止信號(hào) FLASH: CS 高電平 */
  SPI_FLASH_CS_HIGH();
  /* 等待擦除完畢*/
  SPI_FLASH_WaitForWriteEnd();
}

/**
  * @brief  擦除FLASH扇區(qū),整片擦除
        * 描述  :25Q32擦除一次要7-8秒
  * @param  無
  * @retval 無
  */
void SPI_FLASH_BulkErase(void)
{
  /* 發(fā)送FLASH寫使能命令 */
  SPI_FLASH_WriteEnable();

  /* 整塊 Erase */
  /* 選擇FLASH: CS低電平 */
  SPI_FLASH_CS_LOW();
  /* 發(fā)送整塊擦除指令*/
  SPI_FLASH_SendByte(W25X_ChipErase);
  /* 停止信號(hào) FLASH: CS 高電平 */
  SPI_FLASH_CS_HIGH();

  /* 等待擦除完畢*/
  SPI_FLASH_WaitForWriteEnd();
}
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表