⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at45db.c

📁 SM858单片机完成AT45DB内部数据读写程序
💻 C
字号:
/******************************************************************************/ 
/*正常操作电压为2.7~3.6V,实验中发现当电压超过4.25V后读出的状态字节为9A(正常 */ 
/*的状态字节值为9D),并且读写数据均不准确,所以应当保证卡片的供电电压不超过  */ 
/*4.25V。                                                                     */ 
/*SPI规范:Data is always clocked into the device on the rising edge of SCK a-*/ 
/*    nd clocked out of the device on the falling edge of SCK.All instruction-*/ 
/*    s,addresses and data are transferred with the most significant bit(MSB) */ 
/*    first.                                                                  */ 
/*                                                                  2005-06-02*/ 
/******************************************************************************/ 

#pragma    optimize(5)
#include   <reg52.h> 
#include   <string.h> 
#include"charcode.h"
#define    UCHAR                      unsigned char 
#define    UINT                       unsigned int 

sbit       SPI_CS                   = P0^1; 
sbit       SPI_SCK                  = P0^3; 
sbit       SPI_SO                   = P2^3; 
sbit       SPI_SI                   = P0^4; 
sbit       SPI_RES                  = P0^2;
sbit       SPI_WP                   = P0^0;
sbit       SPI_AY1                  = P2^4;
sbit       SPI_AY2                  = P2^5;
sbit       SPI_AY3                  = P2^6;





static void delay(unsigned int s)
{
	unsigned int i;
	for(i=0; i<s; i++);
	for(i=0; i<s; i++);
}


void init_serial(void) 

{
				//定时器1的工作方式2
	TMOD=0x20;	//装载计数初值
	TL1=0xfb;
	TH1=0xfb;	//采用串口工作方式1,无奇偶校验
	SCON=0x50;	//串口波特率不加倍
	PCON=0x00; 	//开总中断,开串口中断
	TCON=0x01;  //中断设置
	IE=0x90;
		//启动定时器1
	TR1=1;
}


void SendCh(unsigned char c)	   //串口送数  8bit
{EA=0;
 TI=0;
 SBUF=c;
 while(!TI);
 TI=0;
 EA=1;
}


unsigned char SPI_HostReadByte(void){ 		 //EEPRAM READ	8bit
    unsigned char i,rByte=0; 
     
    for(i=0;i<8;i++){ 
        SPI_SCK=0; 
        SPI_SCK=1; 
         
        rByte<<=1; 
        rByte|=SPI_SO; 
    } 
    return rByte;     
} 
void SPI_HostWriteByte(unsigned char wByte){ 		//EEPRAM WRITE	8bit
    unsigned char i; 
     
    for(i=0;i<8;i++){ 
        if((wByte<<i)&0x80){SPI_SI=1;} 
        else{SPI_SI=0;} 
         
        SPI_SCK=0; 
        SPI_SCK=1; 
    }     
} 
/******************************************************************************/ 
/*Status Register Format:                                                     */ 
/*   -----------------------------------------------------------------------  */ 
/*  |  bit7  |  bit6  |  bit5  |  bit4  |  bit3  |  bit2  |  bit1  |  bit0  | */ 
/*  |--------|--------|--------|--------|--------|--------|--------|--------| */ 
/*  |RDY/BUSY|  COMP  |   0    |   1    |   1    |   1    |   X    |   X    | */ 
/*   -----------------------------------------------------------------------  */ 
/*  bit7 - 忙标记,0为忙1为不忙。                                             */ 
/*         当Status Register的位0移出之后,接下来的时钟脉冲序列将使SPI器件继续*/ 
/*         将最新的状态字节送出。                                             */ 
/*  bit6 - 标记最近一次Main Memory Page和Buffer的比较结果,0相同,1不同。     */ 
/*  bit5                                                                      */ 
/*  bit4                                                                      */ 
/*  bit3                                                                      */ 
/*  bit2 - 这4位用来标记器件密度,对于AT45DB041B,这4位应该是0111,一共能标记 */ 
/*         16种不同密度的器件。                                               */ 
/*  bit1                                                                      */ 
/*  bit0 - 这2位暂时无效                                                      */ 
/******************************************************************************/ 
unsigned char AT45DB041B_StatusRegisterRead(void){ 				//EEPRAM RegisterREAD
    unsigned char i; 
                 
    SPI_CS=0;     
    SPI_HostWriteByte(0xd7); 
    i=SPI_HostReadByte(); 
    SPI_CS=1; 
     
    return i;     
} 
/******************************************************************************/ 
/*描述:                                                                      */ 
/*    When the last bit in the main memory array has been read,the device will*/ 
/*    continue reading back at the beginning of the first page of memory.As w-*/ 
/*    ith crossing over page boundaries,no delays will be incurred when wrapp-*/ 
/*    ing around from the end of the array to the beginning of the array.     */ 
/*参数:                                                                      */ 
/*    PA      - 页地址,0~2047                                                */ 
/*    BFA     - 指定BUFFER中的起始写入地址                                    */ 
/*    pHeader - 指定数据的首地址                                              */ 
/*    len     - 指定数据的长度                                                */ 
/******************************************************************************/ 
void AT45DB041B_ContinuousArrayRead(UINT PA,UINT BFA,unsigned char *pHeader,UINT len){       //Array READ 
    unsigned int i;       
     
    while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}} 
    SPI_CS=0;     
    SPI_HostWriteByte(0xe8);     		   //指令
    SPI_HostWriteByte((unsigned char)(PA>>7));     		 //24位
    SPI_HostWriteByte((unsigned char)((PA<<1)|(BFA>>8))); 
    SPI_HostWriteByte((unsigned char)BFA); 
    for(i=0;i<4;i++){SPI_HostWriteByte(0x00);} 		//32位don't care 
     
    for(i=0;i<len;i++){pHeader[i]=SPI_HostReadByte();} 
    SPI_CS=1; 
} 
/******************************************************************************/ 
/*描述:                                                                      */ 
/*    将指定数据读出从某个地址(0~263)开始的BUFFER中。                       */ 
/*参数:                                                                      */ 
/*    buffer  - 选择BUFFER,01H选择BUFFER 1,02H选择BUFFER 2                  */ 
/*              在该指令序列中,操作码d4H选择BUFFER 1,d6H选择BUFFER 2        */ 
/*    BFA     - BUFFER中的起始地址,0~263                                     */ 
/*    pHeader - 待存数据的头指针                                              */ 
/*    len     - 待存数据的长度1~264                                           */ 
/******************************************************************************/ 
void AT45DB041B_BufferRead(UCHAR buffer,UINT BFA,UCHAR *pHeader,UINT len){ 
    unsigned int i; 
     
    while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}} 
    SPI_CS=0;     
    switch(buffer){ 
        case 1:SPI_HostWriteByte(0xd4);break; 
        case 2:SPI_HostWriteByte(0xd6);break; 
    } 
    SPI_HostWriteByte(0x00); 
    SPI_HostWriteByte((unsigned char)(BFA>>8)); 
    SPI_HostWriteByte((unsigned char)BFA);
    SPI_HostWriteByte(0x00);
     
    for(i=0;i<len;i++){pHeader[i]=SPI_HostReadByte();} 
    SPI_CS=1;         
} 
/******************************************************************************/ 
/*描述:                                                                      */ 
/*    将指定数据写入从某个地址(0~263)开始的BUFFER中。                       */ 
/*参数:                                                                      */ 
/*    buffer  - 选择BUFFER,01H选择BUFFER 1,02H选择BUFFER 2                  */ 
/*              在该指令序列中,操作码84H选择BUFFER 1,87H选择BUFFER 2        */ 
/*    BFA     - BUFFER中的起始地址,0~263                                     */ 
/*    pHeader - 待存数据的头指针                                              */ 
/*    len     - 待存数据的长度1~264                                           */ 
/******************************************************************************/ 
void AT45DB041B_BufferWrite(UCHAR buffer,UINT BFA,UCHAR *pHeader,UINT len){ 
    unsigned int i; 
     
    while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}} 
    SPI_CS=0;     
    switch(buffer){ 
        case 1:SPI_HostWriteByte(0x84);break; 
        case 2:SPI_HostWriteByte(0x87);break; 
    } 
    SPI_HostWriteByte(0x00); 
    SPI_HostWriteByte((unsigned char)(BFA>>8)); 
    SPI_HostWriteByte((unsigned char)BFA); 
     
    for(i=0;i<len;i++){SPI_HostWriteByte(pHeader[i]);} 
    SPI_CS=1;         
} 

void AT45DB041B_MainMemoryPageRead(UINT PA,UINT BFA,unsigned char *pHeader,UINT len)
{   unsigned int i; 
     
    while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}} 
    SPI_CS=0;   
    SPI_HostWriteByte(0xd2);
    SPI_HostWriteByte((unsigned char)(PA>>7));     
    SPI_HostWriteByte((unsigned char)((PA<<1)|(BFA>>8))); 
    SPI_HostWriteByte((unsigned char)BFA); 
    for(i=0;i<4;i++){SPI_HostWriteByte(0x00);} 
     
    for(i=0;i<len;i++){pHeader[i]=SPI_HostReadByte();} 
    SPI_CS=1;   
}
/******************************************************************************/ 
/*描述:                                                                      */ 
/*    将指定数据写入从某个地址(0~263)开始的页中:包含2个动作,首先将指定数据*/ 
/*    写入到BUFFER 1或者BUFFER 2中,其中可以指定BUFFER中的起始写入地址,此写入*/ 
/*    动作不影响BUFFER中其它地址中的数据,然后再将BUFFER中的整个数据写入到某指*/ 
/*    定页中(带预擦除)。                                                      */ 
/*参数:                                                                      */ 
/*    buffer  - 选择BUFFER,01H选择BUFFER 1,02H选择BUFFER 2                  */ 
/*    PA      - 页地址,0~2047                                                */ 
/*    BFA     - 指定BUFFER中的起始写入地址                                    */ 
/*    pHeader - 指定数据的首地址                                              */ 
/*    len     - 指定数据的长度                                                */ 
/******************************************************************************/ 
void AT45DB041B_BufferToMainMemoryPageProgramWithBuilt_inErase(UCHAR buffer,UINT PA,UINT BFA,UCHAR *pHeader,UINT len){ 
    unsigned int i; 

    AT45DB041B_BufferWrite(buffer,BFA,pHeader,len); 
    while(i++<1000){if(AT45DB041B_StatusRegisterRead()&0x80){break;}} 
             
    SPI_CS=0;         
    switch(buffer){ 
        case 1:SPI_HostWriteByte(0x83);break; 
        case 2:SPI_HostWriteByte(0x86);break; 
    } 
    SPI_HostWriteByte((unsigned char)(PA>>7)); 
    SPI_HostWriteByte((unsigned char)(PA<<1)); 
    SPI_HostWriteByte(0x00); 
    SPI_CS=1; 
} 
/******************************************************************************/ 
/*描述:                                                                      */ 
/*    与上一个函数的唯一区别是不带预擦除。                                    */ 
/******************************************************************************/ 
void AT45DB041B_BufferToMainMemoryPageProgramWithoutBuilt_inErase(UCHAR buffer,UINT PA,UINT BFA,UCHAR *pHeader,UINT len){ 
    unsigned int i=0; 

    AT45DB041B_BufferWrite(buffer,BFA,pHeader,len); 
    while(i++<1000){if(AT45DB041B_StatusRegisterRead()&0x80){break;}} 
     
    SPI_CS=0; 
    SPI_HostWriteByte(0x88+buffer); 
    SPI_HostWriteByte((unsigned char)(PA>>7)); 
    SPI_HostWriteByte((unsigned char)(PA<<1)); 
    SPI_HostWriteByte(0x00); 
     
    for(i=0;i<len;i++){SPI_HostWriteByte(pHeader[i]);} 
    SPI_CS=1; 
} 

void main(void){ 
 //   unsigned char i; 
//	unsigned char k; 
	unsigned char j;
    UCHAR idata test[128];
	
    SPI_RES=1;
	SPI_WP=1;
    SPI_AY1=0;
    SPI_AY2=0;
    SPI_AY3=0;
   
   // i=AT45DB041B_StatusRegisterRead(); 
     
    
    //memset(test,0x26,32); 
    //AT45DB041B_MainMemoryPageRead(2047,0,test,32);
//   AT45DB041B_ContinuousArrayRead(0,0,test,32);
   
 //  AT45DB041B_BufferToMainMemoryPageProgramWithBuilt_inErase(1,0,0,DisPlay22,264);      
   init_serial();
    while(1)
	{
 
     AT45DB041B_ContinuousArrayRead(0,0,test,128);
	 for(j=0;j<128;j++)
      {
	     SendCh(test[j]);	     
	     SPI_AY1=~SPI_AY1;
         SPI_AY2=~SPI_AY2;
         SPI_AY3=~SPI_AY3;
		 delay(20000);
	    
	  }
  
	   //SendCh(i);
       //delay(20000);
/*	  for(j=0;j<8;j++)
        {SendCh(test[j]); 
//		  SPI_AY1=~SPI_AY1;
//        SPI_AY2=~SPI_AY2;
//        SPI_AY3=~SPI_AY3;
		 delay(20000);
	    }
 	    */
  	  
	} 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -