flashat45db161d驱动模块源码C.docx
- 文档编号:8540573
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:18
- 大小:19.26KB
flashat45db161d驱动模块源码C.docx
《flashat45db161d驱动模块源码C.docx》由会员分享,可在线阅读,更多相关《flashat45db161d驱动模块源码C.docx(18页珍藏版)》请在冰豆网上搜索。
flashat45db161d驱动模块源码C
声明:
希望使用者保留本人的相关信息,当然了,要面试时用除外,呵呵
/**********模块注释*********************************************************
模块名:
E:
\__ldr__\my_prj\SW_PRJ\SRC\EX_DEV_DRV\at45db161d.c
模块功能:
提供操作flash:
AT45DB161D的必要的接口,简单明了.
存在问题:
1)如果突然断电,很可能要会丢掉1page数据,原来的模块也存在这样的问题,电脑windows系统也有.
2)没有考虑坏页的问题.
把flash的两个ram分别用作wbuf和rbuf.
全局设定:
全局依赖:
与flash芯片通信的驱动模块
编程语言:
ANSIC
作者及日期:
练达荣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"
//#defineDEBUG_THIS_MODULE
#if0//defDEBUG_THIS_MODULE
#defineDEBUG_uart1_Sendbuf(buffer,bytes16)uart1_Sendbuf(buffer,bytes16)
#defineDEBUG_uart1_SendString(str)uart1_SendString(str)
#defineDEBUG_uart1_SendByte(dat8)uart1_SendByte(dat8)
#else
#defineDEBUG_uart1_Sendbuf(buffer,bytes16)
#defineDEBUG_uart1_SendString(str)
#defineDEBUG_uart1_SendByte(dat8)
#endif
///////////////////////////////////////////移植相关///////////////////////////////////////////////////////////////////////////
#defineSPI_CSP12//外部flashSPI使能信号
#defineSelect_Flash()SPI_CS=0
#defineUnSelect_Flash()SPI_CS=1
#definewrite1Byte(x)spi_WriteRead1Byte(x)
#defineread1Byte()spi_WriteRead1Byte(0)
///////////////////////////////////////////FLASH操作命令///////////////////////////////////////////////////////////////////////////
#definePAGE_TO_B1_XFER0x53//mainmemorypagetobuffer1transfer
#definePAGE_TO_B2_XFER0x55//mainmemorypagetobuffer2transfer
#definePAGE_TO_B2_COMP0x61//mainmemorypagecomparetobuffer2
#defineB2_TO_PAGE_WITH_ERASE0x86//buffer2tomainmemorypageprogramwithbuilt-inerase
#defineSTATUS_REGISTER0xD7
#defineBUFFER_1_READ0xD1//D4buffer1read(changeto0xD4forSPImode0,3)
#defineFLASH_CMD_ReadID0x9f//读取芯片32位ID.
#defineBUFFER_2_WRITE0x87//buffer2write
#defineBUFFER_2_READ0xD3//D6buffer2read(changeto0xD6forSPImode0,3)
///////////////////////////////////////////纯软件部分///////////////////////////////////////////////////////////////////////////
typedefstruct
{
UINT16pageIdRead;//[0~4095]当前读的页地址
UINT16pageIdWrite;//[0~4095]当前写的页地址
}T_FlashCtrl;
staticT_FlashCtrlctl;
typedefenum
{
E_ReadBuffer,
E_WriteBuffer
}ET_BufReadWrite;
/****************************************************************************************
*Function:
检测并等待器件忙状态
*Description:
过读状态寄存器来检测忙状态
*Calls:
-
*Input:
-
*Output:
-
*Return:
*****************************************************************************************/
staticvoidFLASH_Wait_Busy(void)
{
Select_Flash();
write1Byte(STATUS_REGISTER);
while
(1)
{
if(read1Byte()&0x80)//读取的最高位1时器件忙
break;
}
UnSelect_Flash();
}
/****************************************************************************************
*Function:
缓冲区(writebuffer)数据与FLASH指定页比较
*Description:
状态寄存器bit6为0表示比较数据想匹配,1表示比较数据不相匹配
*Calls:
-
*Input:
-
*Output:
TRUE不相同
FALSE相同
*Return:
*****************************************************************************************/
staticUINT8flash_buffer_compareUnsame(UINT16page)
{
Select_Flash();
write1Byte(PAGE_TO_B2_COMP);
write1Byte((UINT8)(page>>6));
write1Byte((UINT8)(page<<2));
write1Byte(0x00);
UnSelect_Flash();
FLASH_Wait_Busy();
Select_Flash();
write1Byte(STATUS_REGISTER);
if(read1Byte()&0x40)//读取的比较状态位
{
UnSelect_Flash();
return1;
}
else
{
UnSelect_Flash();
return0;
}
}
/****************************************************************
原型:
功能:
从flash里读给定page的数据到flash的部ram.
入参:
uintpageflash的页,[0~4095]
ET_BufReadWritebufferType
出参:
运行环境:
调用说明:
作者:
练达荣2015/06/18
****************************************************************/
staticvoidLoad_Page_To_Buffer(UINT16page,ET_BufReadWritebufferType)
{
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:
将"写缓冲区容"写入到主存储器中指定页
*Description:
*Calls:
-
*Input:
-页地址,缓冲区
*Output:
-
*Return:
*****************************************************************************************/
staticvoidWrite_Page_From_Buffer(UINT16page)
{
Select_Flash();
write1Byte(B2_TO_PAGE_WITH_ERASE);
write1Byte((UINT8)(page>>6));
write1Byte((UINT8)(page<<2));
write1Byte(0x00);//don'tcare
UnSelect_Flash();
FLASH_Wait_Busy();
}
/****************************************************************************************
*Function:
从读缓冲区读数据(BUFFER1),读出字节可选
*Description:
*Calls:
-
*Input:
-页字节地址,缓冲接收数组,读数据长度
*Output:
-
*Return:
*****************************************************************************************/
staticvoidRead_DataFromFlashBuffer(uintaddr,UINT8*dat,UINT16bytes)
{
uinti;
Select_Flash();
write1Byte(BUFFER_1_READ);
write1Byte(0x00);
write1Byte((UINT8)(addr>>8));
write1Byte((UINT8)addr);
for(i=0;i { dat[i]=read1Byte(); } UnSelect_Flash(); } /**************************************************************************************** *Function: 从读缓冲区读数据(BUFFER1),读出字节可选 *Description: *Calls: - *Input: -页字节地址,缓冲接收数组,读数据长度 *Output: - *Return: *****************************************************************************************/ staticvoidRead_DataFromWriteBuffer(uintaddr,UINT8*dat,UINT16bytes) { uinti; Select_Flash(); write1Byte(BUFFER_2_READ); write1Byte(0x00); write1Byte((UINT8)(addr>>8)); write1Byte((UINT8)addr); for(i=0;i { dat[i]=read1Byte(); } UnSelect_Flash(); } /**************************************************************************************** *Function: 将数据写入写缓冲区(BUFFER2),写入字节可选 *Description: ; *Calls: - *Input: -页字节地址,缓冲发送数组,写读数据长度 *Output: - *Return: *****************************************************************************************/ staticvoidWrite_Data2FlashBuffer(uintaddr,UINT8*dat,UINT16bytes) { uinti; Select_Flash(); write1Byte(BUFFER_2_WRITE); write1Byte(0x00); write1Byte((UINT8)(addr>>8)); write1Byte((UINT8)addr); for(i=0;i { write1Byte(dat[i]); } UnSelect_Flash(); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // //以下是全局函数 // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// voidflash_init(void) { memset(&ctl,0,sizeof(ctl)); Load_Page_To_Buffer(ctl.pageIdWrite,E_WriteBuffer); Load_Page_To_Buffer(ctl.pageIdRead,E_ReadBuffer); } /**************************************************************** 原型: BOOLflash_write_ok(UINT32addr,UINT8*buf,UINT16bytes) 功能: 把数据写到flash的绝对地址中,可能只是写到其buf里面. 约定: 任何时候的ctl.pageIdWrite所对应的页都会被读到相应writebuf里,并且只可能比flash里新. 入参: UINT32addrflash的绝对字节地址(0~2MByte,每个page最后16字节不要,但认为是连续的2MBytes) UINT8*buf等待保存的数据 UINT16bytes要保存数据字节数 出参: TRUE写成功 FALSE写失败,地址越界 运行环境: 调用说明: 作者: 练达荣2015/06/18 ****************************************************************/ BOOLflash_write_ok(UINT32addr,UINT8*buf,UINT16bytes) { UINT16page=addr/BYTES_PER_PAGE; UINT16beginAddr=addr%BYTES_PER_PAGE; UINT8bytes_will_write; if(addr>=FLASH_TOTAL_BYTES||addr+bytes>FLASH_TOTAL_BYTES)returnFALSE; DEBUG_uart1_SendString("FFWWBBBB\r\n"); if(page! =ctl.pageIdWrite)//写的不是当前页,先保存当前页到flash. { DEBUG_uart1_SendString("FFWW0000\r\n"); 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("FFWW1111\r\n"); 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("FFWW2222\r\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("FFWW3333\r\n"); DEBUG_uart1_Sendbuf((UINT8*)&beginAddr,sizeof(beginAddr)); DEBUG_uart1_Sendbuf((UINT8*)&bytes,sizeof(bytes)); DEBUG_uart1_Sendbuf(buf,bytes); Write_Data2FlashBuffer(beginAddr,buf,bytes); } returnTRUE; } /**************************************************************** 原型: UINT16flash_read(UINT32addr,UINT8*savebuf,UINT16bytes) 功能: 从flash的绝对地址中,读出特定的字节数,可能只是读readbuffer,也可能两个都读. 约定: 任何时候的ctl.pageIdWrite所对应的页都会被读到相应writebuf里,并且只可能比flash里新. 入参: UINT32addrflash的绝对字节地址(0~2MByte,每个page最后16字节不要,但认为是连续的2MBytes) UINT8*buf等待保存的数据 UINT16bytes要保存数据字节数 出参: 实际读成功的字节数. 运行环境: 调用说明: 作者: 练达荣2015/06/18 ****************************************************************/ UINT16flash_read(UINT32addr,UINT8*savebuf,UINT16bytes) { UINT16page=addr/BYTES_PER_PAGE; UINT16beginAddr=addr%BYTES_PER
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- flashat45db161d 驱动 模块 源码
![提示](https://static.bdocx.com/images/bang_tan.gif)