flashat45db161d驱动模块源码.C.doc_第1页
flashat45db161d驱动模块源码.C.doc_第2页
flashat45db161d驱动模块源码.C.doc_第3页
flashat45db161d驱动模块源码.C.doc_第4页
flashat45db161d驱动模块源码.C.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

声明: 希望使用者保留本人的相关信息,当然了,要面试时用除外,呵呵/* 模块注释 *模块名:E:_ldr_my_prjSW_PRJSRCEX_DEV_DRVat45db161d.c模块功能:提供操作 flash:AT45DB161D 的必要的接口,简单明了.存在问题:1) 如果突然断电,很可能要会丢掉1page数据, 原来的模块也存在这样的问题, 电脑windows系统也有.2) 没有考虑坏页的问题.把flash的两个ram分别用作wbuf和rbuf.全局设定:全局依赖:与 flash 芯片通信的驱动模块编程语言: ANSI C作者及日期:练达荣2015/06/18版本:V1.0修改及日期:*/#include #include #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_uart1_Sendbuf(buffer,bytes16)uart1_Sendbuf(buffer,bytes16)#define DEBUG_uart1_SendString(str)uart1_SendString(str)#define DEBUG_uart1_SendByte(dat8)uart1_SendByte(dat8)#else#define DEBUG_uart1_Sendbuf(buffer,bytes16)#define DEBUG_uart1_SendString(str)#define DEBUG_uart1_SendByte(dat8)#endif/ 移植相关 /#define SPI_CSP12 /外部flash SPI使能信号#define Select_Flash() SPI_CS=0#define UnSelect_Flash() SPI_CS=1#definewrite1Byte(x)spi_WriteRead1Byte(x)#define read1Byte()spi_WriteRead1Byte(0)/ FLASH 操作命令 /#define PAGE_TO_B1_XFER 0x53 / main memory page to buffer 1 transfer#define PAGE_TO_B2_XFER 0x55 / main memory page to buffer 2 transfer#define PAGE_TO_B2_COMP 0x61 / main memory page compare to buffer 2#define B2_TO_PAGE_WITH_ERASE 0x86 / buffer 2 to main memory page program with built-in erase#define STATUS_REGISTER 0xD7#define BUFFER_1_READ 0xD1 / D4 buffer 1 read (change to 0xD4 for SPI mode 0,3)#define FLASH_CMD_ReadID0x9f/ 读取芯片32位ID.#define BUFFER_2_WRITE 0x87 / buffer 2 write#define BUFFER_2_READ 0xD3 / D6 buffer 2 read (change to 0xD6 for SPI mode 0,3)/ 纯软件部分 /typedef structUINT16 pageIdRead;/ 04095 当前读的页地址UINT16 pageIdWrite;/ 04095 当前写的页地址T_FlashCtrl;static T_FlashCtrl ctl;typedef enumE_ReadBuffer,E_WriteBufferET_BufReadWrite;/* Function: 检测并等待器件忙状态* Description:过读状态寄存器来检测忙状态* 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: 缓冲区(write buffer)数据与FLASH指定页比较* Description:状态寄存器bit 6为0 表示比较数据想匹配,1表示比较数据不相匹配* Calls:-* Input:-* Output: TRUE不相同FALSE相同* Return:* */static UINT8 flash_buffer_compareUnsame(UINT16 page)Select_Flash();write1Byte(PAGE_TO_B2_COMP);write1Byte(UINT8)(page 6);write1Byte(UINT8)(page 6);write1Byte(UINT8)(page 6);write1Byte(UINT8)(page 8);write1Byte(UINT8)addr);for(i = 0; i 8);write1Byte(UINT8)addr);for(i = 0; i 8);write1Byte(UINT8)addr);for(i = 0; i = FLASH_TOTAL_BYTES | addr + bytes FLASH_TOTAL_BYTES)return FALSE;DEBUG_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.pageIdWrite);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_Sendbuf(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(FFWW2222rn);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(beginAddr);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 的绝对地址中, 读出特定的字节数, 可能只是读 read buffer ,也可能两个都读.约定: 任何时候的ctl.pageIdWrite所对应的页都会被读到相应write buf里,并且只可能比flash里新.入参:UINT32 addrflash的绝对字节地址(0 2MByte,每个page最后16字节不要,但认为是连续的2MBytes)UINT8 *buf等待保存的数据UINT16 bytes要保存数据字节数出参:实际读成功的字节数.运行环境:调用说明:作者:练达荣2015/06/18*/UINT16 flash_read(UINT32 addr,UINT8 *savebuf,UINT16 bytes)UINT16 page = addr/BYTES_PER_PAGE;UINT16 beginAddr = addr % BYTES_PER_PAGE;UINT16 bytes_will_read;UINT16 rbytes_true;if(addr = FLASH_TOTAL_BYTES)return 0;if(addr + bytes FLASH_TOTAL_BYTES)bytes = FLASH_TOTAL_BYTES - addr;rbytes_true = bytes;DEBUG_uart1_SendString(FFRR0000rn);DEBUG_uart1_Sendbuf(UINT8*)&addr, sizeof(addr);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)/ 读的数据不在当前读buf页,可能要重新load.DEBUG_uart1_SendString(FFRR1111rn);DEBUG_uart1_Sendbuf(UINT8*)&ctl.pageIdRead, sizeof(ctl.pageIdRead);DEBUG_uart1_Sendbuf(UINT8*)&ctl.pageIdWrite, sizeof(ctl.pageIdWrite);if(page = ctl.pageIdWrite)/ 与当前写的页相同, 看数据是否有更新.if(flash_buffer_compareUnsame(ctl.pageIdWrite)Write_Page_From_Buffer(ctl.pageIdWrite);Load_Page_To_Buffer(page, E_ReadBuffer);/ 读的数据 不在当前页.ctl.pageIdRead = 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*)&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_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(beginAddr);return rbytes_true;/*原型:功能:读取 flash 芯片ID, 长度为4字节,可以用作软件加密用途.入参:UINT8 *buf保存读出的设备ID出参:无运行环境:调用说明:作者:练达荣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();/模块测试部分/#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 debug_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; iBYTES_PER_PAGE; i+)/ / wbufi = i % 256;/ 256?0x5A:0xA5;/ / / read id/ flash_read_deviceID(rbuf);/ for(i=0; i4; 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)/ / debug_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_flagView(2);/ memset(rbuf, 0, sizeof(rbuf);/ flash_read(addr - 5, rbuf, sizeof(rbuf);/ for(i=0; iBYTES_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, sizeof(wbuf)/ / debug_flagView(4);/ memset(rbuf, 0, sizeof(rbuf);/ flash_read(addr - 20, rbuf, sizeof(rbuf);/ for(i=0; iBYTES_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, sizeof(rbuf);/ flash_read(addr - 20, rbuf, sizeof(rbuf);/ for(i=0; iBYTES_PER_PAGE; i+)/ / DEBUG_uart1_SendByte(rbufi);/ / / static void test_ok(void)/ 这个函数能正常 写/读; 数据也是对的./ UINT32 i;/ #define BEGIN_ADDR(200*BYTES_PER_PAGE)/ debug_FillFlash(0+BEGIN_ADDR, BEGIN_ADDR + BYTES_PER_PAGE

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论