原创 C51 ATMEL AT45DB642D操作函数库

2008-12-15 14:44 2944 3 3 分类: MCU/ 嵌入式

说明: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
 


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条