这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » AT45DB081 求助:使用AT45DB081遇到的问题.

共3条 1/1 1 跳转至

AT45DB081 求助:使用AT45DB081遇到的问题.

院士
2006-09-17 18:14:16     打赏
AT45DB081 求助:使用AT45DB081遇到的问题.



关键词: AT45DB081     求助     使用     遇到     问题    

院士
2006-12-22 22:43:00     打赏
2楼
问   第一次使用外扩存储器,在使用AT45DB081的过程中遇到一点麻烦,从081取到的值和送去的值不符,不知

道是对081指令使用不当,还是单片机与081间通信存在问题(用spi与其它设备间通信,经验证通信正常)。
  希望用过081的朋友指点一下,部分源程序附在后面。可以给我发邮件yanyaomail@163.com  谢谢!


/*************************初始化变量*****************************/
xdata uchar send_081[15]=

{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15};
xdata uchar read_081[15];



/*************************SPI通信子程序***************************/

void SenDSPIByte(unsigned char ch)      //通过SPI发送一个字节数据{        SPIF = 0;               

       // SPIF位清零
         SPI0DAT = ch;               // 启动一次数据发送
         while (SPIF == 0);          // 等待数据发送完毕
}
unsigned char GetSPIByte()        //通过SPI接收一个字节数据
{        SPIF = 0;                      // SPIF位清零
         SPI0DAT = 0;                  //启动一次数据接收
         while (SPIF == 0);          // 等待数据接收完毕
     return  SPI0DAT;              // 读取SPI接收的数据
}

/**************************部分主程序**************************/

P5&=0xFD;                        //片选081            
SenDSPIByte(0x84);               //发送操作码,向缓存器写入数据
SenDSPIByte(0x00);               //发送8位无效位
SenDSPIByte(0x00);               //发送7位无效位和第一位地址位
SenDSPIByte(0x00);               //发送后8位地址
for(flag=0;flag<15;flag++)      //送入数据
SenDSPIByte(send_081[flag]);
P5|=0x02;            //释放081

P5&=0xFD;
SenDSPIByte(0x83);              //擦写主存储器页面后并从缓存器写入
SenDSPIByte(0x00);         //发送3位无效位和五位页面地址
SenDSPIByte(0x00);         //发送七位页面地址位和1位无效位
SenDSPIByte(0x00);        //发送8位无效位
P5|=0x02;

P5&=0xFD;                        
SenDSPIByte(0x53);             //将主存储器页面数据传送给缓存器
SenDSPIByte(0x00);        //发送3位无效位和五位页面地址
SenDSPIByte(0x00);        //发送七位页面地址位和1位无效位
SenDSPIByte(0x00);          //发送8位无效位
P5|=0x02;            //释放与081的通信

P5&=0xFD;            
SenDSPIByte(0x54);              //读缓存器内某个字节SenDSPIByte
SenDSPIByte(0x00);              //发送8位无效位
SenDSPIByte(0x00);              //发送7位无效位和第一位地址位
SenDSPIByte(0x00);              //发送后8位地址
SenDSPIByte(0x00);              //发送8位无效位
for(flag=0;flag<15;flag++)       //读取缓存器中数据        
read_081[flag]=GetSPIByte();
                   
P5|=0x02;//释放与081的通信
////////////////////////////////////////////////////
通信结束后得到的数据如下:
read_081[15]={0x88,0x91,0x19,0xa2,0x2a,0xb3,0x3b,0xc4,0x4c,0x88,0x08,0x89,0x09,0x8a,0x0a} 1: 问题解决了!!  通过大家发的邮件,终于把这个问题解决了.说起来也简单,就是每条命令发送前没有查询081的状态位,由于上条指令未执行完,导致接收不到数据。
  谢谢高手指点!!不胜感激。 2: AT45DB041读写缓存#include   <reg51.h>
#include   <string.h>

#define    uchar                      unsigned char
#define    uint                       unsigned int

sbit       SPI_CS                   = P1^3;
sbit       SPI_SCK                  = P1^2;
sbit       SPI_SO                   = P1^0;
sbit       SPI_SI                   = P1^1;
sbit       led                      = P3^1;

/***************************************************/

uchar SPI_HostReadByte(void){
    uchar 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(uchar wByte){
    uchar i;
     
      for(i=0;i<8;i++)
      {
         SPI_SCK=0;
          
         if(wByte&0x80){SPI_SI=1;}
         else{SPI_SI=0;}
         wByte<<=1;
                  
         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位暂时无效                                                      */
/******************************************************************************/
uchar  AT45DB041B_StatusRegisterRead(void){
    uchar i=0;
                 
    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,uchar *pHeader,uint len){      ///////  
    uint i;       
     
    while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
    SPI_CS=0;     
    SPI_HostWriteByte(0xe8);     
    SPI_HostWriteByte((uchar)(PA>>7));     
    SPI_HostWriteByte((uchar)((PA<<1)|(BFA>>8)));
    SPI_HostWriteByte((uchar)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)开始的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){
    uint 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((uchar)(BFA>>8));
    SPI_HostWriteByte((uchar)BFA);
     
    for(i=0;i<len;i++){SPI_HostWriteByte(pHeader[i]);}
    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){
    uint 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((uchar)(PA>>7));
    SPI_HostWriteByte((uchar)(PA<<1));
    SPI_HostWriteByte(0x00);
    SPI_CS=1;
}
/*************************************************************************

专家
2022-08-20 15:03:26     打赏
3楼

学习一下


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]