版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、聲明 : 希望使用者保留本人的相關信息,當然了 ,要面試時用除外,呵呵/*模塊注釋*模塊名 :模塊功能:E:_ldr_my_prjSW_PRJSRCEX_DEV_DRVat45db161d.c提供操作flash:AT45DB161D的必要的接口 , 簡單明了 .存在問題 :1)如果突然斷電, 很可能要會丟掉1page 數(shù)據(jù) ,原來的模塊也存在這樣的問題,電腦 windows 系統(tǒng)也有 .2) 沒有考慮壞頁的問題 .把 flash 的兩個 ram 分別用作 wbuf 和 rbuf.全局設定 :全局依賴 :與 flash芯片通信的驅動模塊編程語言 :ANSI C作者及日期 :練達榮2015/06/
2、18版本 :V1.0修改及日期 :*/#include <STC15F2K60S2.H>#include <string.h>#include "./delay.h"#include "./uart.h"#include "./stc_spi.h"#define _DELCALE_IN_THIS_FILE_#include "at45db161d.h"/#define DEBUG_THIS_MODULE#if 0/def DEBUG_THIS_MODULE#define DEBUG_uart
3、1_Sendbuf(buffer,bytes16)uart1_Sendbuf(buffer,bytes16)#define DEBUG_uart1_SendString(str)#define DEBUG_uart1_SendByte(dat8)#else#define DEBUG_uart1_Sendbuf(buffer,bytes16)#define DEBUG_uart1_SendString(str)#define DEBUG_uart1_SendByte(dat8)#endifuart1_SendString(str)uart1_SendByte(dat8)/移植相關/#define
4、 SPI_CSP12 /外部 flash SPI使能信號#define Select_Flash()SPI_CS=0#define UnSelect_Flash()SPI_CS=1#define write1Byte(x)spi_WriteRead1Byte(x)#define read1Byte()spi_WriteRead1Byte(0)/FLASH操作命令/#define PAGE_TO_B1_XFER0x53/mainmemory pagetobuffer 1 transfer#define PAGE_TO_B2_XFER0x55/mainmemory pagetobuffer 2 t
5、ransfer#define PAGE_TO_B2_COMP0x61/ main memorypage compareto buffer 2#define B2_TO_PAGE_WITH_ERASE0x86/ buffer 2 to main memorypage program with built-in erase#define STATUS_REGISTER0xD7#define BUFFER_1_READ0xD1 / D4 buffer 1 read (changeto 0xD4 for SPI mode 0,3)#define FLASH_CMD_ReadID0x9f/ 讀取芯片32
6、 位 ID.#define BUFFER_2_WRITE0x87/ buffer 2 write#define BUFFER_2_READ0xD3 / D6 buffer 2 read (changeto 0xD6 for SPI mode 0,3)/純軟件部分/typedef structUINT16 pageIdRead;/ 04095UINT16 pageIdWrite; / 04095T_FlashCtrl;static T_FlashCtrl ctl;當前讀的頁地址當前寫的頁地址typedef enumE_ReadBuffer,E_WriteBufferET_BufReadWrite
7、;/* Function:檢測并等待器件忙狀態(tài)* Description:過讀狀態(tài)寄存器來檢測忙狀態(tài)* Calls:-* Input:-* Output:-* Return:*/static void FLASH_Wait_Busy(void)Select_Flash(); write1Byte(STATUS_REGISTER); while(1)if(read1Byte() & 0x80) /讀取的最高位1 時器件忙break;UnSelect_Flash();/* Function:緩沖區(qū) (write buffer)數(shù)據(jù)與 FLASH指定頁比較* Description:狀態(tài)寄存
8、器 bit 6 為 0 表示比較數(shù)據(jù)想匹配, 1 表示比較數(shù)據(jù)不相匹配* Calls:-* Input:-* Output:TRUE不相同F(xiàn)ALSE相同* Return:*/static UINT8 flash_buffer_compareUnsame(UINT16 page)Select_Flash();write1Byte(PAGE_TO_B2_COMP);write1Byte(UINT8)(page >> 6);write1Byte(UINT8)(page << 2);write1Byte(0x00);UnSelect_Flash();FLASH_Wait_Bus
9、y();Select_Flash();write1Byte(STATUS_REGISTER);if(read1Byte() & 0x40)/讀取的比較狀態(tài)位UnSelect_Flash();return 1;elseUnSelect_Flash();return 0;/*原型 :功能 :從 flash里讀給定 page 的數(shù)據(jù)到 flash的內部 ram.入參 :uint pageflash 的頁 ,0 4095ET_BufReadWrite bufferType出參 :運行環(huán)境 :調用說明 :作者 :練達榮2015/06/18*/static void Load_Page_To_Bu
10、ffer(UINT16 page, ET_BufReadWrite bufferType)Select_Flash();write1Byte(bufferType = E_ReadBuffer ? PAGE_TO_B1_XFER : PAGE_TO_B2_XFER); write1Byte(UINT8)(page >> 6);write1Byte(UINT8)(page << 2);write1Byte(0x00);UnSelect_Flash();FLASH_Wait_Busy();/* Function:將 " 寫緩沖區(qū)內容 "寫入到主存儲器中指
11、定頁* Description:* Calls:-* Input:-頁地址,緩沖區(qū)* Output:-* Return:*/static void Write_Page_From_Buffer(UINT16 page)Select_Flash();write1Byte(B2_TO_PAGE_WITH_ERASE);write1Byte(UINT8)(page >> 6);write1Byte(UINT8)(page << 2);write1Byte(0x00); / don't careUnSelect_Flash();FLASH_Wait_Busy();/*
12、Function:從讀緩沖區(qū)讀數(shù)據(jù)(BUFFER1),讀出字節(jié)可選* Description:* Calls:-* Input:-頁內字節(jié)地址,緩沖接收數(shù)組,讀數(shù)據(jù)長度* Output:-* Return:*/static void Read_DataFromFlashBuffer(uint addr, UINT8 *dat, UINT16 bytes)uint i;Select_Flash();write1Byte(BUFFER_1_READ);write1Byte(0x00);write1Byte(UINT8)(addr >> 8);write1Byte(UINT8)addr)
13、;for(i = 0; i < bytes; i+)dati = read1Byte();UnSelect_Flash();/* * Function:從讀緩沖區(qū)讀數(shù)據(jù)(BUFFER1),讀出字節(jié)可選* Description:* Calls:-* Input:-頁內字節(jié)地址,緩沖接收數(shù)組,讀數(shù)據(jù)長度* Output:-* Return:*/static void Read_DataFromWriteBuffer(uint addr, UINT8 *dat, UINT16 bytes)uint i;Select_Flash();write1Byte(BUFFER_2_READ);writ
14、e1Byte(0x00);write1Byte(UINT8)(addr >> 8);write1Byte(UINT8)addr);for(i = 0; i < bytes; i+)dati = read1Byte();UnSelect_Flash();/* Function:將數(shù)據(jù)寫入寫緩沖區(qū)(BUFFER2),寫入字節(jié)可選* Description:;* Calls:-* Input:-頁內字節(jié)地址,緩沖發(fā)送數(shù)組,寫讀數(shù)據(jù)長度* Output:-* Return:*/static void Write_Data2FlashBuffer(uint addr, UINT8 *d
15、at, UINT16 bytes)uint i;Select_Flash();write1Byte(BUFFER_2_WRITE);write1Byte(0x00);write1Byte(UINT8)(addr >> 8);write1Byte(UINT8)addr);for(i = 0; i < bytes; i+)write1Byte(dati);UnSelect_Flash();/以下是全局函數(shù)/void flash_init(void)memset(&ctl, 0, sizeof(ctl);Load_Page_To_Buffer(ctl.pageIdWrite
16、, E_WriteBuffer);Load_Page_To_Buffer(ctl.pageIdRead, E_ReadBuffer);/*原型 :BOOL flash_write_ok(UINT32 addr,UINT8 *buf,UINT16 bytes)功能 :把數(shù)據(jù)寫到 flash的絕對地址中 ,可能只是寫到其 buf里面 .約定 : 任何時候的 ctl.pageIdWrite所對應的頁都會被讀到相應write buf 里 , 并且只可能比 flash里新 .入參 :UINT32 addrflash 的絕對字節(jié)地址 (0 2MByte,每個 page 最后 16字節(jié)不要 , 但認為是連續(xù)
17、的2MBytes)UINT8 *buf等待保存的數(shù)據(jù)UINT16 bytes要保存數(shù)據(jù)字節(jié)數(shù)出參 :TRUE寫成功FALSE寫失敗 , 地址越界運行環(huán)境 :調用說明 :作者 :練達榮2015/06/18*/ BOOL flash_write_ok(UINT32 addr,UINT8 *buf,UINT16 bytes) UINT16 page = addr/BYTES_PER_PAGE;UINT16 beginAddr = addr % BYTES_PER_PAGE;UINT8 bytes_will_write;if(addr >= FLASH_TOTAL_BYTES | addr +
18、bytes > FLASH_TOTAL_BYTES) FALSE;returnDEBUG_uart1_SendString("FFWWBBBBrn");if(page != ctl.pageIdWrite) /寫的不是當前頁, 先保存當前頁到flash.DEBUG_uart1_SendString("FFWW0000rn");DEBUG_uart1_Sendbuf(UINT8*)&page, sizeof(page);DEBUG_uart1_Sendbuf(UINT8*)&ctl.pageIdWrite, sizeof(ctl.pa
19、geIdWrite); Write_Page_From_Buffer(ctl.pageIdWrite); ctl.pageIdWrite = page;Load_Page_To_Buffer(ctl.pageIdWrite, E_WriteBuffer);while(beginAddr + bytes > BYTES_PER_PAGE)/超出原來的頁DEBUG_uart1_SendString("FFWW1111rn");DEBUG_uart1_Sendbuf(UINT8*)&beginAddr, sizeof(beginAddr);DEBUG_uart1_S
20、endbuf(UINT8*)&bytes, sizeof(bytes);DEBUG_uart1_Sendbuf(UINT8*)&ctl.pageIdWrite, sizeof(ctl.pageIdWrite);bytes_will_write = BYTES_PER_PAGE - beginAddr;Write_Data2FlashBuffer(beginAddr, buf, bytes_will_write);if(flash_buffer_compareUnsame(ctl.pageIdWrite)DEBUG_uart1_SendString("FFWW2222r
21、n");Write_Page_From_Buffer(ctl.pageIdWrite);buf += bytes_will_write;bytes -= bytes_will_write;beginAddr = 0;ctl.pageIdWrite+;Load_Page_To_Buffer(ctl.pageIdWrite, E_WriteBuffer);if(bytes != 0)DEBUG_uart1_SendString("FFWW3333rn");DEBUG_uart1_Sendbuf(UINT8*)&beginAddr, sizeof(beginAd
22、dr);DEBUG_uart1_Sendbuf(UINT8*)&bytes, sizeof(bytes);DEBUG_uart1_Sendbuf(buf, bytes);Write_Data2FlashBuffer(beginAddr, buf, bytes);return TRUE;/*原型 :UINT16 flash_read(UINT32 addr,UINT8 *savebuf,UINT16 bytes)功能 :從 flash的絕對地址中 ,讀出特定的字節(jié)數(shù) , 可能只是讀 read buffer ,也可能兩個都讀 .約定 : 任何時候的 ctl.pageIdWrite所對應的頁
23、都會被讀到相應write buf里 , 并且只可能比 flash里新 .入參 :UINT32 addrflash的絕對字節(jié)地址 (0 2MByte,每個 page 最后 16字節(jié)不要 , 但認為是連續(xù)的 2MBytes)UINT8 *buf等待保存的數(shù)據(jù)UINT16 bytes要保存數(shù)據(jù)字節(jié)數(shù)出參 :實際讀成功的字節(jié)數(shù) .運行環(huán)境 :調用說明 :作者 :練達榮2015/06/18*/UINT16 flash_read(UINT32 addr,UINT8 *savebuf,UINT16 bytes)UINT16 page = addr/BYTES_PER_PAGE;UINT16 beginAdd
24、r = addr % BYTES_PER_PAGE;UINT16 bytes_will_read;UINT16 rbytes_true;if(addr >= FLASH_TOTAL_BYTES) if(addr + bytes > FLASH_TOTAL_BYTES) rbytes_true = bytes;return 0;bytes = FLASH_TOTAL_BYTES - addr;DEBUG_uart1_SendString("FFRR0000rn");DEBUG_uart1_Sendbuf(UINT8*)&addr, sizeof(addr)
25、;DEBUG_uart1_Sendbuf(UINT8*)&beginAddr, sizeof(beginAddr);DEBUG_uart1_Sendbuf(UINT8*)&page, sizeof(page);DEBUG_uart1_Sendbuf(UINT8*)&bytes, sizeof(bytes);if(page != ctl.pageIdRead)能要重新load./讀的數(shù)據(jù)不在當前讀buf頁 , 可DEBUG_uart1_SendString("FFRR1111rn");DEBUG_uart1_Sendbuf(UINT8*)&ct
26、l.pageIdRead, sizeof(ctl.pageIdRead); DEBUG_uart1_Sendbuf(UINT8*)&ctl.pageIdWrite, sizeof(ctl.pageIdWrite);if(page = ctl.pageIdWrite)/與當前寫的頁相同,看數(shù)據(jù)是否有更新 .if(flash_buffer_compareUnsame(ctl.pageIdWrite)Write_Page_From_Buffer(ctl.pageIdWrite);Load_Page_To_Buffer(page, E_ReadBuffer);/讀的數(shù)據(jù)不在當前頁 .ctl.p
27、ageIdRead = page;while(beginAddr + bytes > BYTES_PER_PAGE)/超出原來的頁bytes_will_read = BYTES_PER_PAGE - beginAddr;DEBUG_uart1_SendString("FFRR2222rn");DEBUG_uart1_Sendbuf(UINT8*)&bytes, sizeof(bytes);DEBUG_uart1_Sendbuf(UINT8*)&beginAddr, sizeof(beginAddr);DEBUG_uart1_Sendbuf(UINT8*
28、)&ctl.pageIdRead, sizeof(ctl.pageIdRead);DEBUG_uart1_Sendbuf(UINT8*)&bytes_will_read, sizeof(bytes_will_read);Read_DataFromFlashBuffer(beginAddr, savebuf, bytes_will_read); savebuf += bytes_will_read;bytes -= bytes_will_read;beginAddr = 0;ctl.pageIdRead+;Load_Page_To_Buffer(ctl.pageIdRead, E
29、_ReadBuffer);if(bytes != 0)Read_DataFromFlashBuffer(beginAddr, savebuf, bytes);DEBUG_uart1_SendString("FFRR3333rn");DEBUG_uart1_Sendbuf(UINT8*)&ctl.pageIdRead, sizeof(ctl.pageIdRead);DEBUG_uart1_Sendbuf(UINT8*)&bytes, sizeof(bytes);DEBUG_uart1_Sendbuf(UINT8*)&beginAddr, sizeof(
30、beginAddr);return rbytes_true;/*原型 :功能 :入參 :讀取 flashUINT8 *buf芯片ID,長度為 4 字節(jié) , 可以用作軟件加密用途保存讀出的設備ID.出參 :無運行環(huán)境:調用說明作者 :練達榮2015/06/18*/void flash_read_deviceID(UINT8 *buf)UINT8 i;Select_Flash();write1Byte(FLASH_CMD_ReadID);for(i = 0; i < 4; i+)bufi = read1Byte();/SPI_Write_Byte(0xff);UnSelect_Flash()
31、;/模塊測試部分/#ifdef DEBUG_THIS_MODULE#include "./uart.h"/UINT8 wbufBYTES_PER_PAGE;/UINT8 rbufBYTES_PER_PAGE;static void debug_flagView(UINT8 dat)DEBUG_uart1_SendByte(0x55);DEBUG_uart1_SendByte(0x66);DEBUG_uart1_SendByte(0x77);DEBUG_uart1_SendByte(0x88);DEBUG_uart1_SendByte(dat);static void deb
32、ug_FillFlash(UINT32 begin, UINT32 end)UINT32 addr;for(addr=begin; addr < end; addr+=4)flash_write_ok(addr, (UINT8*)&addr, sizeof(addr);static void test_scan_time(void);static void test_ok(void);void test_flash(void)test_scan_time();/ UINT32 addr;/ UINT16 i;/ /test_ok();/ for(i=0; i<BYTES_P
33、ER_PAGE; i+)/ / wbufi = i % 256;/ < 256?0x5A:0xA5;/ / read id/ flash_read_deviceID(rbuf);/ for(i=0; i<4; i+)/ / DEBUG_uart1_SendByte(rbufi);/ /寫&讀整頁/ addr = BYTES_PER_PAGE * 200;/ if(flash_write_ok(addr, wbuf, sizeof(wbuf)/ / if(flash_write_ok(addr+BYTES_PER_PAGE, wbuf, sizeof(wbuf)/ /debu
34、g_flagView(1);/memset(rbuf, 0, sizeof(rbuf);/flash_read(addr, rbuf, sizeof(rbuf);/DEBUG_uart1_Sendbuf(rbuf,sizeof(rbuf);/ / /寫& 讀跨頁測試/ addr = BYTES_PER_PAGE * 10 + BYTES_PER_PAGE/2;/ if(flash_write_ok(addr, wbuf, sizeof(wbuf)/ / if(flash_write_ok(addr+BYTES_PER_PAGE, wbuf, sizeof(wbuf)/ /debug_f
35、lagView(2);/memset(rbuf, 0, sizeof(rbuf);/flash_read(addr - 5, rbuf, sizeof(rbuf);/for(i=0; i<BYTES_PER_PAGE; i+)/DEBUG_uart1_SendByte(rbufi);/ / /寫 & 讀 頁末前面邊沿測試/ addr = BYTES_PER_PAGE * 30 - 10;/ if(flash_write_ok(addr, wbuf, sizeof(wbuf)/ / if(flash_write_ok(addr+BYTES_PER_PAGE, wbuf, sizeo
36、f(wbuf)/ /debug_flagView(4);/memset(rbuf, 0, sizeof(rbuf);/flash_read(addr - 20, rbuf, sizeof(rbuf);/for(i=0; i<BYTES_PER_PAGE; i+)/DEBUG_uart1_SendByte(rbufi);/ / /寫 & 讀 頁末后面邊沿測試/ addr = BYTES_PER_PAGE * 40 + 10;/ if(flash_write_ok(addr, wbuf, sizeof(wbuf)/ / if(flash_write_ok(addr+BYTES_PER_PAGE, wbuf, sizeof(wbuf)/ /debug_flagView(5);/memset(rbuf, 0, sizeo
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 校園應急預案解讀
- 食品安全伴我行
- 認識銷售課件教學課件
- 假如課件教學課件
- 高三化學一輪復習 第一章 離子反應 離子方程式 課件
- 稻田餐廳課件教學課件
- 3.1.1鐵及鐵的氧化物 課件 高一上學期化學人教版(2019)必修第一冊
- 2.2化學平衡 課件高二上學期化學人教版(2019)選擇性必修1
- 成人夏季食品安全教育
- 企業(yè)宿舍管理培訓
- 消防應急疏散預案培訓
- 2024-2025學年八年級上學期期中考試地理試題
- 2019年湖南岳陽中考滿分作文《握手》3
- 注冊安全工程師考試安全生產法律法規(guī)(初級)試題及解答參考
- 危急值的考試題及答案
- 鼻竇炎圍手術期護理
- 浙江省北斗星盟2023-2024學年高二下學期5月階段性聯(lián)考數(shù)學試題2
- MOOC創(chuàng)新創(chuàng)業(yè)與管理基礎(東南大學)
- 硫磺安全技術說明書MSDS
- 國開電大《工程數(shù)學(本)》形成性考核作業(yè)5答案
- GB/T 28653-2012工業(yè)氟化銨
評論
0/150
提交評論