當前位置:
首頁 >
SpiFlash同步/异步读写单片机裸机实例
發(fā)布時間:2024/1/1
28
豆豆
生活随笔
收集整理的這篇文章主要介紹了
SpiFlash同步/异步读写单片机裸机实例
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
單片機裸機開發(fā)中會經(jīng)常遇到外設速度過慢,長時間讀忙等待,但CPU又不能長時間阻塞的問題。
這種問題可以通過實現(xiàn)一個狀態(tài)機來異步處理。
這種問題可以通過實現(xiàn)一個狀態(tài)機來異步處理。
異步狀態(tài)機代碼結(jié)構(gòu)示例:
enum {eIDLE = 0,eSTART,eWAIT,eSUCCESS };static uint8_t stage = 0; //啟動異步處理 void DoSomethingRequest() {if(stage != eIDLE){printf("AsyncMachine is busy!!!,return\n");return;}SomethingReq = TRUE; } //異步處理任務 void AsyncMachine() {switch(stage){case eIDLE:if(SomethingReq){stage = eSTART;printf("A task will be start\n");}break;case eSTART: do_something();stage = eWAIT;printf("do something\n");break;case eWAIT: if(something_state() == OK){stage = eSUCCESS;}printf("Wait...\n");break;case eSUCCESS: stage = eIDLE;printf("task exec success\n");break;} }通過把阻塞的任務單獨分離出來,交給一個狀態(tài)機子任務來處理。則應用程序只需要調(diào)用一個處理請求而無需原地死等,狀態(tài)機處理完成后,可以異步回調(diào)來通知應用程序任務已完成。
下面附上SPI FLASH 同步/異步讀寫實例。
//SPI狀態(tài)機狀態(tài) typedef enum {eFLASH_STATE_IDLE = 0,eFLASH_STATE_WRITE = 1, eFLASH_STATE_READ = 2,eFLASH_STATE_BUSY = 3,eFLASH_STATE_ERASE_CHIP = 4,eFLASH_STATE_ERASE = 5, }FlashState_e; //SPI設備結(jié)構(gòu)體 typedef struct SpiDevice_s {SPI_TypeDef *spiHandle;//SPI物理屬性uint8_t *pTxBuffer;//異步發(fā)送緩存uint32_t uTxDstAddr;//異步發(fā)送目地地址uint16_t wTxLen;//異步發(fā)送長度uint16_t wTxOffset; //異步當前緩存已發(fā)送偏移 uint8_t *pRxBuffer;uint32_t uRxSrcAddr;uint16_t wRxLen;uint16_t wRxOffset; void (*pWriteAsyncNotifyCallback)(); //異步寫完成回調(diào)通知void (*pEraseChipAsyncNotifyCallback)();//異不擦除回調(diào)通知struct {FlashState_e eStage;//當前狀態(tài)機狀態(tài)//BOOL bTxBusy:1; //發(fā)送忙BOOL bTxReq:1; //發(fā)送請求BOOL bTxCompleted:1;//發(fā)送完成//BOOL bRxBusy:1; //讀忙BOOL bRxReq:1; //讀請求BOOL bEraseChipReq:1;//擦整片請求BOOL bEraseSectorReq:1;//擦扇區(qū)請求BOOL bEraseSuccess:1; //擦成功}tState;void (*Init)(void);uint8_t (*EraseChip)(void);//同步擦void (*Read)(uint8_t* pBuffer,uint32_t uReadAddr,uint16_t wNumByteToRead);//同步讀uint32_t (*WriteByte)(uint8_t Byte, uint32_t uWriteAddr);//同步寫字節(jié)uint32_t (*Write)(uint8_t* pBuffer,uint32_t uWriteAddr, uint16_t wNumByteToWrite);//同步寫B(tài)OOL (*WriteAsync)(uint8_t* pBuffer,uint32_t uWriteAddr, uint16_t wNumByteToWrite);//異步寫B(tài)OOL (*EraseChipAsync)(void);//異步整片擦BOOL (*EraseAsync)(uint32_t uAddr, uint16_t wlen);//奶步擦void (*WriteAsyncNotifyCallbackRegister)(void* pfn);//異步寫完成回調(diào)注冊void (*EraseChipAsyncNotifyCallbackRegister)(void *pfn);//異步擦完成回調(diào)注冊 }SpiDevice_t;實例化 SpiDevice_t g_tSpiDevice = {SPI2,g_aTxBuffer,0,0,0,g_aRxBuffer,0,0,0,0,0,{0,0},Spi_Init,SPI_Flash_Erase_Chip, //í?2?????2áSPI_Flash_Read, //í?2??áSPI_Flash_WriteByte, //í?2?D′×??úSPI_Flash_Write, //í?2?D′SPI_FlashWriteAsync, //òì2?D′SPI_FlashEraseChipAsync, //òì2?????2á3ySPI_FlashEraseAsync,SPI_WriteAsyncNotifyCallbackRegister,//D′×′ì?òì2?í¨?a??μ÷SPI_EraseChipAsyncNotifyCallbackRegister,//2á3y×′ì?òì2?í¨?a??μ÷ };
總結(jié)
以上是生活随笔為你收集整理的SpiFlash同步/异步读写单片机裸机实例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 帝国CMS自动批量定时审核插件
- 下一篇: 电子工程师自学成才pdf_作为一名自学成