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

📄 at45db_spi.c

📁 高速flash AT45db041B驱动程序。msp430f149+at45db041b,包括源件和项目文件。
💻 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*/ 
/******************************************************************************/
#include  <string.h> 
#include  "at45db_spi.h"

void AT45_ini()
{
	P4DIR |= SPI_SI + SPI_SCK + SPI_CS + SPI_WP;
	P4DIR &=~ SPI_SO;
	P4OUT |= SPI_WP;
}
uchar SPI_HostReadByte(void)
{ 
    uchar i,rByte=0;     
    for(i=0;i<8;i++)
    { 
        P4OUT |=  SPI_SCK;		//SPI_SCK=1; 
        _NOP(); _NOP();
        rByte<<=1;
        P4OUT &=~ SPI_SCK;		//SPI_SCK=0; 
		_NOP(); _NOP();
		if(P4IN&SPI_SO)	rByte |= 0x01;
		_NOP(); _NOP();
    /*
        P4OUT &=~ SPI_SCK;		//SPI_SCK=0; 
        _NOP();
		_NOP();
        P4OUT |=  SPI_SCK;		//SPI_SCK=1; 
        rByte<<=1; 
        if(P4IN&SPI_SO)	rByte |= 0x01;
		_NOP();
		_NOP();
	*/
    } 
    return rByte;     
} 
void SPI_HostWriteByte(uchar val)
{ 
    uchar i;
    uchar wByte; 
    
    wByte = val;
	for(i=0;i<8;i++)
    { 
        P4OUT &=~ SPI_SCK;		//SPI_SCK=0; 
        if((wByte<<i)&0x80) {  P4OUT |= SPI_SI; } 
        else{	P4OUT &=~ SPI_SI;	}
        _NOP();_NOP();_NOP();_NOP();
        P4OUT |=  SPI_SCK;		//SPI_SCK=1; 
        _NOP();_NOP();
    }    
    /*     
    for(i=0;i<8;i++)
    { 
        if((wByte<<i)&0x80) {  P4OUT |= SPI_SI; } 
        else{	P4OUT &=~ SPI_SI;	} 
        
        P4OUT &=~ SPI_SCK;		//SPI_SCK=0; 
        _NOP();
		_NOP();
        P4OUT |=  SPI_SCK;		//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 AT45_Status_Read(void)
{
	uchar i;
	P4OUT &=~ SPI_CS;		//SPI_CS=0;
	_NOP();
	SPI_HostWriteByte(0xd7); 
    i=SPI_HostReadByte(); 
    P4OUT |= SPI_CS;		//SPI_CS=1;
    _NOP();      
    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 AT45_Continu_Read(uint PA, uint BFA, uchar *pHeader,uint len)
{
    uint i=0;  
    while(i++<255){if(AT45_Status_Read()&0x80){break;}} 
    P4OUT &=~ SPI_CS;		//SPI_CS=0;
    _NOP();
    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();} 
    P4OUT |= SPI_CS;		//SPI_CS=1;
    _NOP();
} 

/******************************************************************************/ 
/*描述: 
	//读数据到Buffer                                                                      */ 
/*参数:                                                                     */ 
/*    PA      - 页地址,0~2047                                                */ 
/*    addr    - 指定BUFFER中的起始写入地址                                    */ 
/*    buf_n   - 指定BUFFER是1还是2                                            */ 
/*    len     - 指定数据的长度                                                */ 
/******************************************************************************/ 
void PageToBuffer1(ulong addr, uchar buf_n)
{
    uint i=0;
    uint PA;
    
    PA=addr / 264; 		//页地址,0~2047
    if(PA > 2047) PA=0; 
    while(i++<255){if(AT45_Status_Read()&0x80){break;}} 
    P4OUT &=~ SPI_CS;		//SPI_CS=0;
    _NOP();
    if(buf_n == 1) SPI_HostWriteByte(0x53);
    else SPI_HostWriteByte(0x55);
    SPI_HostWriteByte((uchar)(PA>>7)); 
    SPI_HostWriteByte((uchar)(PA<<1)); 
    SPI_HostWriteByte(0x00); 
    //SPI_HostWriteByte( (uchar)BFA ); 
    //for(i=0;i<4;i++){SPI_HostWriteByte(0x00);}      
    //for(i=0;i<len;i++){pHeader[i]=SPI_HostReadByte();} 
    P4OUT |= SPI_CS;		//SPI_CS=1;
    _NOP();
} 

/******************************************************************************/ 
/*描述:                                                                      */ 
/*    将指定数据写入从某个地址(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 AT45_BufferWrite(uchar buffer,uint BFA,uchar *pHeader,uint len)
{ 
    uint i=0;
    while(i++<255){if(AT45_Status_Read()&0x80){break;}} 
    P4OUT &=~ SPI_CS;		//SPI_CS=0;
    _NOP();
    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]);} 
    P4OUT |= SPI_CS;		//SPI_CS=1;
    _NOP();
} 
/******************************************************************************/ 
/*描述:                                                                      */ 
/*    将指定数据写入从某个地址(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 AT45_Built_With_Erase(uchar buffer,uint PA,uint BFA,uchar *pHeader,uint len)
{ 
   uint i=0; 
    AT45_BufferWrite(buffer,BFA,pHeader,len);     
    while(i++<1000){if(AT45_Status_Read()&0x80){break;}} 
             
    P4OUT &=~ SPI_CS;		//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); 
    P4OUT |= SPI_CS;		//SPI_CS=1;
} 
/******************************************************************************/ 
/*描述:                                                                      */ 
/*    与上一个函数的唯一区别是不带预擦除。                                    */ 
/******************************************************************************/ 
void AT45_Built_Without_Erase(uchar buffer,uint PA,uint BFA,uchar *pHeader,uint len)
{ 
    uint i=0; 

    AT45_BufferWrite(buffer,BFA,pHeader,len); 
    while(i++<1000){if(AT45_Status_Read()&0x80){break;}} 
     
    P4OUT &=~ SPI_CS;		//SPI_CS=0;
    SPI_HostWriteByte(0x88+buffer); 
    SPI_HostWriteByte((uchar)(PA>>7)); 
    SPI_HostWriteByte((uchar)(PA<<1)); 
    SPI_HostWriteByte(0x00); 
     
    for(i=0;i<len;i++){SPI_HostWriteByte(pHeader[i]);} 
    P4OUT |= SPI_CS;		//SPI_CS=1;
}

void Read_data_AT45(ulong addr, uchar *pHeader, uint len)
{    
    //uint PA, BFA;
    //PA=addr / 264; 
    //BFA=addr % 264;
    AT45_Continu_Read(addr/264,addr%264,pHeader,len);    
}
/******************************************************************************/ 
//写数据到AT45DB041B
/*描述:                                                                      */ 
/*    将指定数据写入从某个地址(0~263)开始的页中:包含2个动作,首先将指定数据*/ 
/*    写入到BUFFER 1或者BUFFER 2中,其中可以指定BUFFER中的起始写入地址,此写入*/ 
/*    动作不影响BUFFER中其它地址中的数据,然后再将BUFFER中的整个数据写入到某指*/ 
/*    定页中(带预擦除)。                                                      */ 
/*参数:                                                                      */ 
/*    addr      - 地址,0~540408										         */ 
/*    pHeader - 指定数据的首地址                                              */ 
/*    len     - 指定数据的长度                                                */ 
/******************************************************************************/ 
void Write_data_AT45(uchar buf,ulong addrl, uchar *pHeader, uint len)
{
	//uint PA, BFA;
    //PA=addr / 264; 		//页地址,0~2047 
    //BFA=addr % 264;		//BFA指定BUFFER中的起始写入地址
   //_DINT(); 
    AT45_Built_With_Erase(buf,addrl/264,addrl%264,pHeader,len);
   // _EINT();
}
/******************************* ALL END **********************************************************/

⌨️ 快捷键说明

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