费尽周折,可谓山穷水尽疑无路,柳暗花明又一村,哈哈
M45PE40-VMW6TG,可替代AT45DB041
公布移植代码。
//ICC-AVR application builder : 2010-11-11 18:37:49
// Target : M128
// Crystal: 8.0000Mhz
#i nclude <iom128v.h>
#i nclude <macros.h>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define DB041CS (1<<0)
#define BEEP (1<<5)
//命令
#define WREN 0x06 //写使能
#define WRDI 0x04 //写禁止
#define RDID 0x9F //读芯片ID
#define RDSR 0x05 //读状态寄存器
#define READ 0x03 //读数据
#define FAST_READ 0x0B //快速读数据
#define PW 0x0A //页写
#define PP 0x02 //页编程
#define PE 0xDB //页擦除
#define SCE 0xD8 //扇区擦除
#define DP 0xB9 //掉电模式
#define RDP 0xAB //掉电模式换醒
uchar Data_Buff[256];
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0xF7;
DDRB = 0xF7; //11110111
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
PORTE = 0x00;
DDRE = 0x00;
PORTF = 0x00;
DDRF = 0x00;
PORTG = 0x00;
DDRG = 0x00;
}
//SPI initialize
// clock rate: 2000000hz
void spi_init(void)
{
SPCR = 0x5f; //setup SPI 模式3 速率8/128M
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
XDIV = 0x00; //xtal divider
XMCRA = 0x00; //external memory
port_init();
spi_init();
MCUCR = 0x80;
EICRA = 0x00; //extended ext ints
EICRB = 0x00; //extended ext ints
EIMSK = 0x00;
TIMSK = 0x00; //timer interrupt sources
ETIMSK = 0x00; //extended timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
/******************************************************************************/
/* 函数名称:void write_to_flash_byte(uchar) */
/* 功能描述:向AT45DB081B flas写入一个字节 */
/* 参数说明:cdata为待写入的数据 */
/* 参数返回:无 */
/******************************************************************************/
void Write_To_Flash_Byte(uchar cdata)
{
uchar byte;
SPDR = cdata;
while (!(SPSR & 0x80))
; //等待写结束
byte = SPDR;
}
/******************************************************************************/
/* 函数名称:uchar check_flash_busy(void) */
/* 功能描述:检查flash是否忙 */
/* 参数说明:无 */
/* 参数返回: 如果忙返回1,不忙返回0 */
/******************************************************************************/
uchar Check_Flash_Busy(void)
{
uchar busy_flag;
PORTB &=~DB041CS; //置cs低选中
Write_To_Flash_Byte(RDSR);
Write_To_Flash_Byte(0xff); //写字节数据,使字节数据从SO移出
busy_flag = SPDR;
PORTB |=DB041CS; //置cs高不选中
if(busy_flag & 1)
busy_flag = 1;
else
busy_flag = 0;
return busy_flag;
}
/******************************************************************************/
/* 函数名称:void read_flash(uchar,uint,uint,uint) */
/* 功能描述:从flash指定页指定页内起始地址读取指定数量的数据字节到 */
/* datasave_buff数组 */
/* 参数说明:Write_com为命令字READ读命令,page_offset为页内起始地址 */
/* page_address为页地址,count为欲读取的字节数 */
/* 参数返回: 无 */
/******************************************************************************/
void Read_Flash_page(uchar Readcmd,uint page_offset,uint page_address,uint count,uchar *dp)
{
uint pa,i;
uchar byte;
pa=0;
//page_address <<=2;
//pa = page_offset>>8;
//page_address |= pa;
while(Check_Flash_Busy()==1);
PORTB &=~DB041CS; //置cs低选中
Write_To_Flash_Byte(Readcmd);
Write_To_Flash_Byte((uchar)(page_address>>8));
Write_To_Flash_Byte((uchar)page_address);
Write_To_Flash_Byte((uchar)page_offset);
for(byte=0;byte<4;byte++)
{
Write_To_Flash_Byte(0);
}
for(;count!=0;count--)
{
Write_To_Flash_Byte(0xff); //写字节数据,使字节数据从SO移出
*dp=SPDR;
dp++;
}
PORTB |=DB041CS; //置cs高不选中
}
//-----------------------------------------
/*********************************************************************************************************
**
** input parameters: uint32 addr: flash addr
uint16 number:欲读数据个数
uint8 *dp:目的数据指针
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void flash_read_continue(ulong addr,uint number,uchar *dp)
{
uchar err;
uint i;
uint j;
if(number == 0) return;
i=addr/256; //页地址
j=addr%256; //页内偏移地址
if(j+number>256)
{
Read_Flash_page(READ,j,i,256-j,dp);
dp+=(256-j);
number-=(256-j);
i++;
while(1)
{
if(number>256)
{
Read_Flash_page(READ,0,i,256,dp);
dp+=256;
number-=256;
i++;
}
else
{
Read_Flash_page(READ,0,i,number,dp);
break;
}
}
}
else
{
Read_Flash_page(READ,j,i,number,dp);//0-20f
}
}
//--------------------------------------------------------
void main(void )
{
init_devices();
PORTB= ~BEEP;
PORTB |=BEEP; /* low output to turn BEEP on */
Read_Flash_page(READ,0,0,256,Data_Buff);//0-ff
Read_Flash_page(READ,0,1,256,Data_Buff);//100-1ff
Read_Flash_page(READ,0,2,256,Data_Buff);//200-2ff
Read_Flash_page(READ,0,3,256,Data_Buff);//300-3ff
Read_Flash_page(READ,0,4,256,Data_Buff);//400-4ff
flash_read_continue(0x210,256,Data_Buff);
flash_read_continue(0x220,256,Data_Buff);
flash_read_continue(0x620,256,Data_Buff);
flash_read_continue(0x400,256,Data_Buff);
while(1);
}
文章评论(0条评论)
登录后参与讨论