📄 at45db161d.c
字号:
/************************************************
*serial flash driver
*该驱动在读flash内容时不使用CS
*在写flash时需要使用CS
*NOTE:目前驱动只支持512Byte/Page
************************************************/
#include "typedef.h"
#include "w77e532.h"
#include "spi.h"
#include "at45db161d.h"
#include "common_function.h"
//#define SPI_CS P1_3
extern Uchar volatile xdata D12_Y5;
extern idata Uchar D18CS;//D12_Y5的寄存器
/************cs = 0**************/
void spi_cson()
{
D18CS &= 0xfe;
D12_Y5 = D18CS;
}
/************cs = 1**************/
void spi_csoff()
{
D18CS |= 0x01;
D12_Y5 = D18CS;
}
/**********************
*在读flash时需要用到的初始化
**********************/
/*void at45_init_read()
{
spi_init();
}*/
/*****************************
*在写flash时需要用到的初始化
*******************************/
void at45_init_write()
{
spi_csoff();
spi_init();
}
/***************************
*本函数需要在命令已经输入的情况下在调用
***************************/
void at45_readdataout(Byte nLen, Byte* pBuf)
{
Byte i;
for (i=0; i<nLen; i++)
pBuf[i] = spi_read();
}
/***********************************
*读数据命令输入
*************************************/
/*void command_legacy_conread(Uint16 pageAddr, Uint16 byteAddr)
{
Byte addr[3];
Byte notCare;
Byte i;
for (i=0; i<3; i++)
addr[i] = 0;
//3 not care+ 12 page + 9 byte
pageAddr <<= 1;
addr[0] = ((Byte*)&pageAddr)[0];
addr[1] = ((Byte*)&pageAddr)[1]+((Byte*)&byteAddr)[0];
addr[2] = ((Byte*)&byteAddr)[1];
spi_write(READ_LEG_CONARRAY);
for (i=0; i<3; i++)
spi_write(addr[i]);
for (i=0; i<4; i++)
spi_write(notCare);
}*/
void command_high_conread(Uint16 pageAddr, Uint16 byteAddr)
{
Byte addr[3];
Byte notCare;
Byte i;
for (i=0; i<3; i++)
addr[i] = 0;
/******3 not care+ 12 page + 9 byte****************/
pageAddr <<= 1;
addr[0] = ((Byte*)&pageAddr)[0];
addr[1] = ((Byte*)&pageAddr)[1]+((Byte*)&byteAddr)[0];
addr[2] = ((Byte*)&byteAddr)[1];
spi_cson();
spi_write(READ_HIGH_CONARRAY);
for (i=0; i<3; i++)
spi_write(addr[i]);
spi_write(notCare);
}
void command_low_conread(Uint16 pageAddr, Uint16 byteAddr)
{
Byte addr[3];
Byte i;
for (i=0; i<3; i++)
addr[i] = 0;
/******3 not care+ 12 page + 9 byte****************/
pageAddr <<= 1;
addr[0] = ((Byte*)&pageAddr)[0];
addr[1] = ((Byte*)&pageAddr)[1]+((Byte*)&byteAddr)[0];
addr[2] = ((Byte*)&byteAddr)[1];
spi_cson();
spi_write(READ_LOW_CONARRAY);
for (i=0; i<3; i++)
spi_write(addr[i]);
}
/***********************以下命令需要CS的支持*************/
/**************buffer write***************/
/*bufNum:1 表示要写buffer1; 2 表示要写buffer2
/*startAddr:要写的buf首地址
/*pBuf:要写入的内容
/*nLen:需要写入的长度
/******************************************/
/*******15+9**********/
void buffer_write(Byte bufNum, Uint16 startAddr, Uint16 nLen, Byte* pBuf)
{
Byte addr[3];
Byte command;
Uint16 i;
spi_csoff();//SPI_CS = 1;
for (i=0; i<3; i++)
addr[i] = 0;
addr[1] = ((Byte*)&startAddr)[0];
addr[2] = ((Byte*)&startAddr)[1];
if (1 == bufNum)
command = WRITE_BUF1;
else
command = WRITE_BUF2;
spi_cson();//SPI_CS = 0;
spi_write(command);
for (i=0; i<3; i++)
spi_write(addr[i]);
for (i=0; i<nLen; i++)
spi_write(pBuf[i]);
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
}
void buffer_write_onepage(Byte bufNum, Byte* pBuf1, Byte* pBuf2, Byte* pBuf3, Byte* pBuf4)
{
Byte addr[3];
Byte command;
Uint16 i;
spi_csoff();//SPI_CS = 1;
for (i=0; i<3; i++)
addr[i] = 0;
if (1 == bufNum)
command = WRITE_BUF1;
else
command = WRITE_BUF2;
spi_cson();//SPI_CS = 0;
spi_write(command);
for (i=0; i<3; i++)
spi_write(addr[i]);
for (i=0; i<128; i++)
spi_write(pBuf1[i]);
for (i=0; i<128; i++)
spi_write(pBuf2[i]);
for (i=0; i<128; i++)
spi_write(pBuf3[i]);
for (i=0; i<128; i++)
spi_write(pBuf4[i]);
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
}
void buffer_to_mainPage_builtin(Byte bufNum, Uint16 pageAddr)
{
Byte addr[3];
Byte command;
Byte i;
for (i=0; i<3; i++)
addr[i] = 0;
pageAddr <<= 1;
spi_csoff();//SPI_CS = 1;
addr[0] = ((Byte*)&pageAddr)[0];
addr[1] = ((Byte*)&pageAddr)[1];
if (1 == bufNum)
command = PROGRAM_BUF1TOMAIN_IN;
else
command = PROGRAM_BUF2TOMAIN_IN;
spi_cson();//SPI_CS=0;
spi_write(command);
for (i=0; i<3; i++)
spi_write(addr[i]);
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
//需要延迟17-40ms
delayMs(40);
}
void buffer_to_mainPage_noErase(Byte bufNum, Uint16 pageAddr)
{
Byte addr[3];
Byte command;
Byte i;
for (i=0; i<3; i++)
addr[i] = 0;
pageAddr <<= 1;
spi_csoff();//SPI_CS = 1;
addr[0] = ((Byte*)&pageAddr)[0];
addr[1] = ((Byte*)&pageAddr)[1];
if (1 == bufNum)
command = PROGRAM_BUF1TOMAIN_OUT;
else
command = PROGRAM_BUF2TOMAIN_OUT;
spi_cson();//SPI_CS=0;
spi_write(command);
for (i=0; i<3; i++)
spi_write(addr[i]);
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
//需要延迟3-6ms
delayMs(6);
}
/**3+12+9*/
void page_erase(Uint16 pageAddr)
{
Byte addr[3];
Byte i;
for (i=0; i<3; i++)
addr[i] = 0;
pageAddr <<= 1;
spi_csoff();//SPI_CS = 1;
addr[0] = ((Byte*)&pageAddr)[0];
addr[1] = ((Byte*)&pageAddr)[1];
spi_cson();//SPI_CS=0;
spi_write(ERASE_PAGE);
for (i=0; i<3; i++)
spi_write(addr[i]);
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
//需要延迟15-35ms
}
/***3+9+12***/
void block_erase(Uint16 BlockAddr)
{
Byte addr[3];
Byte i;
delayMs(10000);
for (i=0; i<3; i++)
addr[i] = 0;
BlockAddr <<= 4;
spi_csoff();//SPI_CS = 1;
addr[0] = ((Byte*)&BlockAddr)[0];
addr[1] = ((Byte*)&BlockAddr)[1];
spi_cson();//SPI_CS=0;
spi_write(ERASE_BLOCK);
for (i=0; i<3; i++)
spi_write(addr[i]);
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
//需要延迟45-100ms
delayMs(3000);
}
void chip_erase()
{
}
/***************************************
sectorAddr:1-15 1-15个sector
16 0a
17 0b
*****************************************/
void sector_erase(Byte sectorAddr)
{
Byte addr[3];
Byte i;
for (i=0; i<3; i++)
addr[i] = 0;
delayMs(10000);
if (17 == sectorAddr)
{
addr[1] = 0x10;
}
else if (sectorAddr < 16)
{
sectorAddr <<= 1;
addr[0] = sectorAddr;
}
spi_csoff();//SPI_CS=0;
spi_write(ERASE_SECTOR);
for (i=0; i<3; i++)
spi_write(addr[i]);
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
//需要延迟1.5-6s
delayMs(10000);
}
/********3+12+9***********/
void program_page_throughbuf(Byte bufNum, Uint16 bufAddr, Uint16 pageAddr, Uint16 nLen, Byte* pBuf)
{
Byte addr[3];
Byte command;
Uint16 i;
spi_csoff();//SPI_CS = 1;
for (i=0; i<3; i++)
addr[i] = 0;
pageAddr <<= 1;
addr[0] = ((Byte*)&pageAddr)[0];
addr[1] = ((Byte*)&pageAddr)[1]+((Byte*)&bufAddr)[0];
addr[2] = ((Byte*)&bufAddr)[1];
if (1 == bufNum)
command = PROGRAM_PAGE_BYBUF1;
else
command = PROGRAM_PAGE_BYBUF2;
spi_cson();//SPI_CS = 0;
spi_write(command);
for (i=0; i<3; i++)
spi_write(addr[i]);
for (i=0; i<nLen; i++)
spi_write(pBuf[i]);
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
//需要延迟17-40ms
delayMs(40);
}
/*********编程1页用四段缓冲*************/
/*每段缓冲的大小为128Byte
/*buffer起始地址为0
/****************************************/
void program_onepage_throughbuf(Byte bufNum, Uint16 pageAddr, Byte* pBuf1, Byte* pBuf2, Byte* pBuf3, Byte* pBuf4)
{
Byte addr[3];
Byte command;
Uint16 i;
spi_csoff();//SPI_CS = 1;
for (i=0; i<3; i++)
addr[i] = 0;
pageAddr <<= 1;
addr[0] = ((Byte*)&pageAddr)[0];
addr[1] = ((Byte*)&pageAddr)[1];
addr[2] = 0;
if (1 == bufNum)
command = PROGRAM_PAGE_BYBUF1;
else
command = PROGRAM_PAGE_BYBUF2;
spi_cson();//SPI_CS = 0;
spi_write(command);
for (i=0; i<3; i++)
spi_write(addr[i]);
for (i=0; i<128; i++)
spi_write(pBuf1[i]);
for (i=0; i<128; i++)
spi_write(pBuf2[i]);
for (i=0; i<128; i++)
spi_write(pBuf3[i]);
for (i=0; i<128; i++)
spi_write(pBuf4[i]);
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
//需要延迟17-40ms
delayMs(40);
}
Byte read_status_register()
{
Byte nValue;
nValue = 0;
spi_cson();//SPI_CS = 0;
spi_write(READ_STATUS_REG);
nValue = spi_read();
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
return nValue;
}
void Program_configure_reg()
{
spi_csoff();//SPI_CS = 1;
spi_cson();//SPI_CS = 0;
spi_write(0x3d);
spi_write(0x2a);
spi_write(0x80);
spi_write(0xa6);
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
//需要延迟3-6ms
delayMs(6);
}
/*******************
*读取ID号
*返回值:OK表示值吻合
KO表示不对
*******************/
Byte read_deviceid()
{
Byte id[4];
Byte i;
id[0] = 0;
id[1] = 0;
id[2] = 0;
id[3] = 0;
spi_cson();//SPI_CS = 0;
spi_write(READ_DEVICEID);
for (i=0; i<4; i++)
{
id[i] = spi_read();
}
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
if ((id[0] == MANU_ID) && (id[1] == DEVICE_ID1) &&
(id[2] == DEVICE_ID2) && (id[3] == DEVICE_ID3))
return OK;
else
return KO;
}
void check_toready()
{
Byte nValue;
nValue = 0;
spi_cson();//SPI_CS = 0;
spi_write(READ_STATUS_REG);
nValue = spi_read();
while (0 == (nValue & 0x80))
{
nValue = spi_read();
}
spi_csoff();//SPI_CS = 1;
SPI_CLK = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -