单片机读写flash AT45DB041D-SU调试BK2461

PC通过串口发送flash数据给单片机写入AT45DB041D-SU
单片机读写flash AT45DB041D-SU调试BK2461_第1张图片
在这里插入图片描述
单片机读写flash AT45DB041D-SU调试BK2461_第2张图片
单片机读写flash AT45DB041D-SU调试BK2461_第3张图片

sbit CSN=  P1^2;
sbit MOSI= P1^3;
sbit MISO= P1^4;
sbit SCK=  P1^5;

bdata unsigned char st=0;
sbit st_1=st^0;
sbit st_2=st^1;
sbit st_3=st^2;
sbit st_4=st^3;
sbit st_5=st^4;
sbit st_6=st^5;
sbit st_7=st^6; 
sbit st_8=st^7;
bdata unsigned char st1=0;
sbit st_11=st1^0;
sbit st_12=st1^1;
sbit st_13=st1^2;
sbit st_14=st1^3;
sbit st_15=st1^4;
sbit st_16=st1^5;
sbit st_17=st1^6;
sbit st_18=st1^7;

uchar SPI_RW(uchar byte)
{
	//uchar bit_ctr;

    st=byte;

    MOSI=st_8;
    SCK = 1;
    st_18=MISO;
    SCK = 0;

    MOSI=st_7;
    SCK = 1;
    st_17=MISO;
    SCK = 0;

    MOSI=st_6;
    SCK = 1;
    st_16=MISO;
    SCK = 0;

    MOSI=st_5;
    SCK = 1;
    st_15=MISO;
    SCK = 0;

    MOSI=st_4;
    SCK = 1;
    st_14=MISO;
    SCK = 0;

    MOSI=st_3;
    SCK = 1;
    st_13=MISO;
    SCK = 0;

    MOSI=st_2;
    SCK = 1;
    st_12=MISO;
    SCK = 0;

    MOSI=st_1;
    SCK = 1;
    st_11=MISO;
    SCK = 0;

    return(st1);           		  // return read byte
}
/**************************************************/

/**************************************************
Function: SPI_Read_Buf();

Description:
  Reads 'bytes' #of bytes from register 'reg'
  Typically used to read RX payload, Rx/Tx address
/**************************************************/
uchar SPI_Read_Buf(BYTE *pBuf,BYTE wbytes, BYTE rbytes)
{
	uchar status,byte_ctr;
	
  	CSN = 0;                    		// Set CSN low, init SPI tranaction
  	
  	for(byte_ctr=0; byte_ctr<wbytes; byte_ctr++) // then write all byte in buffer(*pBuf)
  	{
  		//DebugInfoChar(pBuf[byte_ctr]);
    	SPI_RW(pBuf[byte_ctr] );
  	}

  	for(byte_ctr=0;byte_ctr<rbytes;byte_ctr++)
  	{
    	//pBuf[byte_ctr] = SPI_RW(0);    // Perform SPI_RW to read byte from 
    	//DebugInfoChar(pBuf[byte_ctr]);
    	if(byte_ctr==0){
			status=SPI_RW(0);
			//DebugInfoChar(status);
    	}
    	//else DebugInfoChar(SPI_RW(0));
    	else SPI_RW(0);
  	}

  	CSN = 1;                           // Set CSN high again
	
  	return(status);                    // return status byte
}

#define ACK_NONE    0x0
#define ACK_SUMERR  0x1
#define ACK_UNSPORT 0x2
#define ACK_DONE 	0x3

//=============================
#define CMD_WRITE_START 	0
#define CMD_WRITE_END 		1
#define CMD_WRITE_DATA 		2
#define CMD_READ  			3
#define CMD_GET_PAGESIZE 	4
#define CMD_ERASE_PAGE		5

//
#define CMD_INDEX    0
#define CMD_HIGH     1
#define CMD_LOW    	 2
#define CMD_END_HIGH 3
#define CMD_END_LOW  4

//#define CMD_CHECKSUM 18
//#define CMD_MAX 	 19
//2048 2112
#define SECTOR_SZIE 2048
#define SECTOR_ADDR_A 0x0a
#define SECTOR_ADDR_B 0x0b
#define SECTOR_ADDR_START 1
#define SECTOR_ADDR_END 7

//2048 2112
#define BLOCK_SZIE 2048
#define BLOCK_ADDR_START 0
#define BLOCK_ADDR_END 255
#define BLOCK_COUNT 256

//256 264
#define PAGE_ADDR_COUNT 2048

u16 u16PageSize=256;
//256 bytes CMD opcode page address byte/buffer address
// cmd + A18-A8 + A7-A0/BFA7-BFA0

//Except Status Register Read D7

//Manufacturer and Device ID Read 9F

//low frequency:opcode 03h

uchar ReadStatusRegister(void)
{
	uchar cmd=0xD7;
	
    return SPI_Read_Buf(&cmd,1,1);
}
//0 is busy
uchar CheckBusy(void)
{
    u16 count=1000;
	u8 states;

    while(count--)
    {
    	states = ReadStatusRegister();
		
        if(states&0x80)
        {
        	if(states&0x01)u16PageSize=256;
			else u16PageSize=264;
			
            return 1;
        }
		
        delay_ms(10);
    }
	
    return 0;
}

void ReadManufacturer(void)
{
	uchar cmd=0x9F;

	CheckBusy();
	
    SPI_Read_Buf(&cmd,1,4);
}

/*
//Chip Erase
void ChipErase(void)
{
	u8 cmd[4];
	
	cmd[0]=0xC7;
	cmd[0]=0x94;
	cmd[0]=0x80;
	cmd[0]=0x9A;
	
	SPI_Read_Buf(cmd,4,0);
}

void EnableSectorProtectionCommand(void)
{
	u8 cmd[4];
	
	cmd[0]=0x3D;
	cmd[0]=0x2A;
	cmd[0]=0x7F;
	cmd[0]=0xA9;
	
	SPI_Read_Buf(cmd,4,0);
}

void DisableSectorProtectionCommand(void)
{
	u8 cmd[4];
	
	cmd[0]=0x3D;
	cmd[0]=0x2A;
	cmd[0]=0x7F;
	cmd[0]=0x9A;
	
	SPI_Read_Buf(cmd,4,0);

}

//7C H A18-A11  0a 0b 1-7 sector
void SectorErase(u8 addr)
{
	u8 cmd[4];

	CheckBusy();
	
	cmd[0]=0x81;

	//A18 - A11
	if(addr == 0x0a )
	{
		cmd[1]=0;//A23-A16
		cmd[2]=0;//A15-A8
		cmd[3]=0;//A7-A0
	}
	else if( addr == 0x0b)
	{
		cmd[1]=0;//A23-A16
		cmd[2]=0x08;//A15-A8
		cmd[3]=0;//A7-A0
	}
	//A18-A16
	else
	{
		cmd[1]=(addr>>8)&0x7;//A23-A16
		cmd[2]=(addr>>8)&0xff;//A15-A8
		cmd[3]=0;//A7-A0
	}
	
	SPI_Read_Buf(cmd,4,0);

}
//50 H A18-A11 Block0=0-7page page=256/264 bytes  0-255block
void BlockErase(u8 addr)
{
	u8 cmd[4];

	CheckBusy();
	
	cmd[0]=0x50;
	if(u16PageSize == 256)
	{
		cmd[1]=(addr>>5)&0x7;//A23-A16
		cmd[2]=(addr<<3)&0xf8;//A15-A8
	}
	else//264
	{
		cmd[1]=(addr>>4)&0x0f;//A23-A16
		cmd[2]=(addr<<4)&0xf0;//A15-A8
	}
	cmd[3]=0;//A7-A0
	
	SPI_Read_Buf(cmd,4,0);
}
*/
//81 H A18-A8 page=256/264 bytes   0-2047page
void PageErase(u16 addr)
{
	u8 cmd[4];

	CheckBusy();
	
	cmd[0]=0x81;
	
	if(u16PageSize == 256)
	{
		cmd[1]=(addr>>8)&0x7;//A23-A16
		cmd[2]=addr&0xff;//A15-A8
	}
	else//264
	{
		cmd[1]=(addr>>7)&0x0f;//A23-A16
		cmd[2]=(addr<<1)&0xfe;//A15-A8
	}

	cmd[3]=0;//A7-A0
	
	SPI_Read_Buf(cmd,4,0);
}

//Main Memory Page Program Through Buffer
//82 buffer1 85 buffer2 A18-A8
//84 87 -> 83 86
//Buffer to Main Memory Page Program with Built-in Erase
//83 buffer1  86h buffer2
void MainMemoryPageProgramThroughBuffer(u16 addr,u16 vender)
{
	u8 cmd[4],i;
	
	cmd[0]=0x85;
	if(u16PageSize == 256)
	{
		cmd[1]=(addr>>8)&0x7;//A23-A16
		cmd[2]=addr&0xff;//A15-A8
		cmd[3]=vender;//A7-A0
	}
	else //264
	{
		cmd[1]=(addr>>7)&0xf;//A23-A16
		cmd[2]=(addr<<1)&0xfe;//A15-A8
		cmd[2]|=(vender>>8)&0x01;//A15-A8
		cmd[3]=vender&0xff;//A7-A0
	}

  	for(i=0; i<4; i++) // then write all byte in buffer(*pBuf)
  	{
    	SPI_RW(cmd[i]);
  	}
}
//Main Memory Page Read
//D2 The first 11 bits (A18 - A8) of the 19-bits sequence specify which page of the main memory array to read
//the last 8 bits (A7 - A0) of the 19-bits address sequence specify the starting byte address within the page
void MainMemoryPageRead(u16 addr,u16 vender,u8 dummy,u16 size)
{
	u8 cmd[4];
	u16 i;
	
	cmd[0]=0xD2;
	if(u16PageSize == 256)
	{
		cmd[1]=(addr>>8)&0x7;//A23-A16
		cmd[2]=addr&0xff;//A15-A8
		cmd[3]=vender;//A7-A0
	}
	else //264
	{
		cmd[1]=(addr>>7)&0xF;//A23-A16
		cmd[2]=(addr<<1)&0xfe;//A15-A8
		cmd[2]|=(vender>>8)&0x01;//A15-A8
		cmd[3]=vender&0xff;//A7-A0
	}

	CheckBusy();
	
	CSN = 0;     // Set CSN low, init SPI tranaction
	
	for(i=0;i<4; i++) // then write all byte in buffer(*pBuf)
  	{
    	SPI_RW(cmd[i]);
  	}

	for(i=0;i<dummy; i++) // then write all byte in buffer(*pBuf)
  	{
    	SPI_RW(0);
  	}

	for(i=0; i<size; i++)
  	{
		DebugInfoChar(SPI_RW(0));
  	}
	
	CSN = 1;
}

void UartPageCmd()
{
	u8 cmd=0;
	u16 addr=0,i=0;

	//checksum
	if(DataCheckSum() == 0)
	{
		DebugInfoStr("err:sum");

		delay_ms(30);
		
		addr = COM1.RX_Cnt;
		
		for(i=0;i<addr;i++){
			if(i < COM_RX1_Lenth)
			{
				DebugInfoChar(RX1_Buffer[i]);
			}
			else
			{
				DebugInfoChar(RX1_XBuffer[i-COM_RX1_Lenth]); 
			}
		}
		
		return;
	}

	cmd = RX1_Buffer[CMD_INDEX];

	switch(cmd)
	{
		case CMD_WRITE_START:
			{				
				addr = (RX1_Buffer[CMD_HIGH]<<8) | (RX1_Buffer[CMD_LOW]);

				PageErase(addr);
				
				CheckBusy();
				
				CSN = 0;	 // Set CSN low, init SPI tranaction
				
				MainMemoryPageProgramThroughBuffer(addr,0);

				DebugInfoStr("done");
			}break;
		
		case CMD_WRITE_END:
			{
				DebugInfoStr("done");
				CSN = 1;
			}
			break;
			
		case CMD_WRITE_DATA:
			{
				addr = (RX1_Buffer[CMD_HIGH]<<8) | (RX1_Buffer[CMD_LOW]);
					
				for(i=3; i<(addr+3); i++)
				{
					if(i < COM_RX1_Lenth)
					{
						SPI_RW(RX1_Buffer[i]);
					}
					else
					{
						SPI_RW(RX1_XBuffer[i-COM_RX1_Lenth]); 
					}
				}
				
				DebugInfoStr("done");
			}
			break;
			
		case CMD_READ:
			{
				i = (RX1_Buffer[CMD_END_HIGH]<<8) | (RX1_Buffer[CMD_END_LOW]);
				
				for(;addr<=i;addr++){
					MainMemoryPageRead(addr,0,4,u16PageSize);
				}
			}break;
		
		case CMD_GET_PAGESIZE:
			{
				CheckBusy();
				DebugInfoChar(u16PageSize>>8);
				DebugInfoChar(u16PageSize&0xff);
				DebugInfoChar(COM_RX1_Max>>8);
				DebugInfoChar(COM_RX1_Max&0xff);
			}break;
		
		case CMD_ERASE_PAGE:
			{
				addr = (RX1_Buffer[CMD_HIGH]<<8) | (RX1_Buffer[CMD_LOW]);
				PageErase(addr);
				CheckBusy();
				DebugInfoStr("done");
			}break;

		default:
			{
				DebugInfoStr("cmd unsuport");

				delay_ms(30);
		
				addr = COM1.RX_Cnt;
				
				for(i=0;i<addr;i++){
					if(i < COM_RX1_Lenth)
					{
						DebugInfoChar(RX1_Buffer[i]);
					}
					else
					{
						DebugInfoChar(RX1_XBuffer[i-COM_RX1_Lenth]); 
					}
				}
			}
			break;
	}
}

你可能感兴趣的:(单片机,AT45DB041D-SU,BK2461)