说明:MCU采用STC89C58RC,AT45DB642D与MCU的接口是采用8位并行模式
/*****************************************************************************/
/* ATMEL AT45DB642D操作函数库 */
/* File Name: AT45D642D.C */
/* Author: JAY.J */
/* Created: 2008/8/3 */
/* Modified: NO */
/* Revision: 1.0 */
/*****************************************************************************/
#ifndef AT45DB642D
#include <reg52.h>
#include <absacc.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define READ_STATE_REGISTER 0xD7 // 读取状态寄存器
#define PROGRAM_CONFIGURATION_RES_1 0x3D // 编程状态寄存器字节1
#define PROGRAM_CONFIGURATION_RES_2 0x2A // 编程状态寄存器字节2
#define PROGRAM_CONFIGURATION_RES_3 0x80 // 编程状态寄存器字节3
#define PROGRAM_CONFIGURATION_RES_4 0xA6 // 编程状态寄存器字节4
#define BUFFER_1_WRITE 0x84 // 写入第一缓冲区
#define BUFFER_2_WRITE 0x87 // 写入第二缓冲区
#define BUFFER_1_READ 0xD1 // 读第一缓冲区
#define BUFFER_2_READ 0xD3 // 读第二缓冲区
#define B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83 // 将第一缓冲区的数据写入主存储器(擦除模式)
#define B2_TO_MM_PAGE_PROG_WITH_ERASE 0x86 // 将第二缓冲区的数据写入主存储器(擦除模式)
#define MM_PAGE_READ 0xD2 // 主记忆体页读
#define PAGE_ERASE 0x81 // 住记忆体页擦除
#define MAXLEN 1024 // 缓冲区最大长度
extern uchar xdata buf[MAXLEN];
sfr P4=0xE8;
sbit CS="P2"^7;//AT45DB642D的CS端口
sbit CLK="P3"^4;//AT45DB642D的CLK端口
sbit BUSY="P4"^1;//AT45DB642D的RDY/BUSY端口
//往AT45DB642D写入一字节数据****************************************/
void write_byte_flash(uchar tout)
{
CLK=0;//CLK产生一上升沿,数据输入到AT45DB642D
_nop_();
P0=tout;
_nop_();
CLK=1;
_nop_();
}
//从AT45D642D读出一字节数据*****************************************/
uchar read_byte_flash(void)
{
uchar temp;
temp=0;
P0=0xFF;
CLK=1; //CLK产生一下降沿,数据从AT45DB642D输出
_nop_();
CLK=0;
_nop_();
temp=P0;
return(temp);
}
//读状态寄存器****************************************************/
/*bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0/
//RDY/BUSY COMP 1 1 1 1 PROTECT PAGE SIZE/
//******************************************************************/
uchar read_status_res()
{
uchar status;
status=0;
P2=0xFF;
while(!BUSY);
CS=0;
write_byte_flash(0xD7);//命令码输入
write_byte_flash(0x00);//并行模式,状态寄存器状态在2周期后输出
write_byte_flash(0x00);
status=read_byte_flash();//状态寄存器状态输出
return(status);
}
//编程配置寄存器,改变页面大小************************************/
//status res bit0 0-->1056byte/page bit0 1-->1024byte/page */
/*******************************************************************/
void program_configuration_res()
{
uchar pagesize0,pagesize1,temp,flag_ok;
pagesize0=0;
pagesize1=0;
flag_ok=0;
temp=0;
temp=read_status_res();//读状态寄存器初始状态
pagesize0=0x01&temp;
P2=0xFF;
while(!flag_ok)
{
while(!BUSY);//判断是否忙
CS="0";
_nop_();
write_byte_flash(PROGRAM_CONFIGURATION_RES_1);//命令码输入
write_byte_flash(PROGRAM_CONFIGURATION_RES_2);
write_byte_flash(PROGRAM_CONFIGURATION_RES_3);
write_byte_flash(PROGRAM_CONFIGURATION_RES_4);
CS="1";
while(!BUSY);//判断是否忙
temp="read"_status_res();//读配置后状态寄存器状态
pagesize1=0x01&temp;
if(pagesize0!=pagesize1) flag_ok=1;//判断页面大小是否改变
}
}
//将DF_buffer[]数组中指定长度的数据写入指定缓冲区*******************/
void DF_write_buf(uchar buffer,uint start_address,uint length)
{
uint i;
P2=0xFF;
while(!BUSY);//判断是否忙
CS=0;
if (buffer==1)//写入命令
write_byte_flash(BUFFER_1_WRITE);
else
write_byte_flash(BUFFER_2_WRITE);
write_byte_flash(0x00);//写入三字节地址(1024--14个不关心位+10位缓冲区地址)
write_byte_flash((uchar)(start_address >> 8)); //(1056--13个不关心位+11位缓冲区地址)
write_byte_flash((uchar)start_address);
for (i=0;i<length;i++)
write_byte_flash(buf);
CS=1;
while(!BUSY);//判断是否忙
}
/*缓冲区读函数*********************************************************/
void DF_read_buf(uchar buffer,uint start_address,uint length)
{
uint i;
P2=0xFF;
while(!BUSY);//判断是否忙
CS=0;
if(buffer==1)//写入命令
write_byte_flash(BUFFER_1_READ);
else
write_byte_flash(BUFFER_2_READ);
write_byte_flash(0x00);//写入三字节地址(1024--14个不关心位+10位缓冲区地址)
write_byte_flash((uchar)(start_address >> 8)); //(1056--13个不关心位+11位缓冲区地址)
write_byte_flash((uchar)start_address);
write_byte_flash(0x00);//写入一字节不关心字节
for(i=0;i<length;i++)
{
buf=read_byte_flash();
}
CS=1;
}
//将指定缓冲区中的数据写入主存储区的指定页(擦除模式)****************/
void DF_buf_to_mm(uchar buffer,uint xpage)
{
P2=0xFF;
while(!BUSY);//判断是否忙
CS=0;
if (buffer==1)//写入命令
write_byte_flash(B1_TO_MM_PAGE_PROG_WITH_ERASE);//buffer 1
else
write_byte_flash(B2_TO_MM_PAGE_PROG_WITH_ERASE);//buffer 2
//write_byte_flash((uchar)(xpage>>5));//写入三字节地址(13位页地址+11不关心位)
//write_byte_flash((uchar)(xpage<<3));//1056/page
write_byte_flash((uchar)(xpage>>6));//写入三字节地址(13位页地址+10不关心位)
write_byte_flash((uchar)(xpage<<2));//1024/page
write_byte_flash(0x00);
CS=1;
while(!BUSY);//判断是否忙
}
//主记忆体页读**********************************************************/
/*功能:从主记忆体的指定页中读出指定长度的数据***********************/
void read_mm_page(uint xpage,uint start_address,uint length)
{
uint i;
uchar j;
uchar temp;
P2=0xFF;
while(!BUSY);//判断是否忙
CS=0;
write_byte_flash(MM_PAGE_READ);
//write_byte_flash((uchar)(xpage>>5));//写入三字节地址(13位页地址+11位指定页开始地址)
//temp=(uchar)(start_address >> 8)|0xF8;//1056/page
//temp=((uchar)(xpage<<3)|0x07)&temp;
//write_byte_flash(temp);
write_byte_flash((uchar)(xpage>>6));//写入三字节地址(13位页地址+10位指定页开始地址)
temp=(uchar)(start_address >> 8)|0xFC;//1024/page
temp=((uchar)(xpage<<2)|0x03)&temp;
write_byte_flash(temp);
write_byte_flash((uchar)start_address);
for(j=0;j<19;j++)
write_byte_flash(0x00);//写入19字节不关心字节
for(i=0;i<length;i++)
buf=read_byte_flash();
CS=1;
}
//从主记忆体页读出某个字节*********************************************/
uchar read_page_byte(uint xpage ,uint start_address)
{
uchar value;
uchar j,temp;
P2=0xFF;
while(!BUSY);//判断是否忙
CS=0;
write_byte_flash(MM_PAGE_READ);
//write_byte_flash((uchar)(xpage>>5));//写入三字节地址(13位页地址+11位指定页开始地址)
//temp=(uchar)(start_address >> 8)|0xF8;//1056/page
//temp=((uchar)(xpage<<3)|0x07)&temp;
//write_byte_flash(temp);
write_byte_flash((uchar)(xpage>>6));//写入三字节地址(13位页地址+10位指定页开始地址)
temp=(uchar)(start_address >> 8)|0xFC;//1024/page
temp=((uchar)(xpage<<2)|0x03)&temp;
write_byte_flash(temp);
write_byte_flash((uchar)start_address);
for(j=0;j<19;j++)
write_byte_flash(0x00);//写入19字节不关心字节
value=read_byte_flash();
CS=1;
return value;
}
/*擦除指定的主存储器块(地址范围0-1024)********************************/
void DF_black_earse(uchar black)
{
P2=0xFF;
while(!BUSY);//判断是否忙
CS=0;
write_byte_flash(0x50);
write_byte_flash((uchar)(black>>3));//写入三字节地址(10位块地址+14位不关心位)
write_byte_flash((uchar)(black<<5));//1024/page
write_byte_flash(0x00);
CS=1;
while(!BUSY);
}
//擦除指定的主存储器页(地址范围0-8191)*******************************/
void DF_page_earse(uchar page)
{
P2=0xFF;
while(!BUSY);//判断是否忙
CS=0;
write_byte_flash(PAGE_ERASE);
write_byte_flash((uchar)(page>>6));//写入三字节地址(13位页地址+11不关心位)
write_byte_flash((uchar)(page<<2));//1024/page
write_byte_flash(0x00);
CS=1;
while(!BUSY);
}
/*整片擦除*************************************************************/
void DF_chip_earse()
{
P2=0xFF;
while(!BUSY);//判断是否忙
CS=0;
write_byte_flash(0xC7);
write_byte_flash(0x94);
write_byte_flash(0x80);
write_byte_flash(0x9A);
CS=1;
while(!BUSY);
}
#endif
文章评论(0条评论)
登录后参与讨论