MEGA128外扩flash AT29C020/W29c020读写程序(已测试 GCCAVR CVAVR)
#include"mega128.h"#include"delay.h"
#define SetBit(Port,N)(Port|=(1<<N)) //设置IO某一位
#define ClrBit(Port,N)(Port&=~(1<<N)) //清空IO某一位
#define ReverBit(Port,N)(Port^=(1<<N)) //取反IO某一位
#define GetBit(Pin,N) ((Pin>>N)&0x01) //读取IO某一位
#define U2X01
#define UPE02
#define DOR03
#define FE0 4
#define UDRE0 5
#define RXC07
#define High_A17 PORTD.7
#define High_A16 PORTD.6
#define ext_sram_add1 (*(volatile unsigned char *)0x5555)
#define ext_sram_add2 (*(volatile unsigned char *)0x2aaa)
#define ext_sram_add3 (*(volatile unsigned char *)0x1100)
//#define ext_sram_add(i) (*(volatile unsigned char *)i)
//unsigned char ext_sram_add @0x1200; //外部FLASH的起始地址
//unsigned char *p=&ext_sram_add; //定义一个指针指向外部FLASH的起始地址
unsigned char data={1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1};//作为写入FLASH测试用的
unsigned char rec_buf;//作为读出数据的缓冲
/**************************************************
usart0初始化
**************************************************/
void USART0_Init(void)
{
UCSR0A=0x20; //波特率不加倍,单机通信模式
//UCSR0A=0x22; //波特率加倍,单机通信模式
UCSR0B=0x18; //中断不使能,允许发送和接收
UCSR0C=0x06;//异步模式,无校验,8位数据,1位停止位
//UCSR0C=0x36;//异步模式,odd奇校验,8位数据,1位停止位
UBRR0H=0x00;
//UBRR0L=47;//9600波特率 晶振7.3728
UBRR0L=95;//9600波特率 晶振14.7456
}
/**************************************************
串口发送一个字节
**************************************************/
void USART0_SendByte(unsigned char data)
{
while(!(UCSR0A&(1<<UDRE0)));//等待发送缓冲空
UDR0=data; //发送数据
}
/**************************************************************
向W29C020某一个扇区(128B)写数据 一共2的11次方2048个
扇区,参数high,low是最高地址线A17,A16
注意:地址范围为0x001100到0x11ffff,超出界限,结果不定,
比如第一扇区的的地址范围为0x001100~0x001180,第二扇区的地址为
0x001200~0x001280
前11位为页地址,后面7为某一页的字节地址
**************************************************************/
void Write_W29(unsigned char high ,unsigned char low,unsigned int addr,unsigned char len,unsigned char *dat)
{
unsigned char ii,byte_add;
unsigned intsect;
unsigned char buf;
unsigned char *ptr;
sect=addr-addr%128;
ptr=(unsigned char*)sect;
High_A17=high;
High_A16=low; //获取扇区地址
for (ii=0;ii<128;ii++)//写之前先读出128字节的变量
{
buf=*ptr;
ptr++;
}
ptr=(unsigned char*)sect;//指针返回到扇区首地址
byte_add=addr%128; //原先数据的字节末地址
ext_sram_add1=0xaa;
ext_sram_add2=0x55;
ext_sram_add1=0xa0; //软件保护模式下写数据到W29C020
for (ii=0;ii<byte_add;ii++) //写入原先不需要变化的数据
{
*ptr=buf;
ptr++;
}
ptr=(unsigned char*)(sect+byte_add);//指针指向需要改变信息的首地址
for (ii=0;ii<len;ii++) //写入len字节长度的需要变化的数据
{
*ptr=dat;
ptr++;
}
delay_ms(10); //延时10MS等待写操作完成
}
/**************************************************************
读W29C020某一个扇区的len长度的数据
参数说明同写函数
**************************************************************/
void Read_W29(unsigned char high ,unsigned char low,unsigned int addr,unsigned char len,unsigned char *buf)
{
unsigned char ii;
unsigned char *ptr;
ptr=(unsigned char*)addr;
High_A17=high;
High_A16=low; //获取扇区地址
for (ii=0;ii<len;ii++)
{
buf=*ptr;
ptr++;
}
}
/**************************************************
主函数
**************************************************/
void main(void)
{
unsigned char i=0;
USART0_Init();//初始化USART0接口
MCUCR=0x80; //使能外部SRAM
XMCRA=0x00;
DDRE=0xff;
DDRD=0xff;
PORTD=0x00; //使能 CS A16 A17 =11
SetBit(PORTE,2); //程序启动蜂鸣器响50MS
delay_ms(500.0);
ClrBit(PORTE,2); //关蜂鸣器
/*ext_sram_add1=0xaa;
ext_sram_add2=0x55;
ext_sram_add1=0x80;
ext_sram_add1=0xaa;
ext_sram_add2=0x55;
ext_sram_add1=0x60;
delay_us(15);
PORTD=0xc0;
USART0_SendByte( ext_sram_add3);
ext_sram_add1=0xaa;
ext_sram_add2=0x55;
ext_sram_add1=0xf0;
delay_us(15);*/ //测试返回W29C020的ID
//Write_W29(0,0,0x1220,0x20,data); //下数据到W29C020
//delay_ms(200);
//PORTD=0xc0;
//p=&ext_sram_add;
Read_W29(0,0,0x1200,128,rec_buf);
for(i=0;i<128;i++) //通过串口发送读出的20字节FLASH数据
{
USART0_SendByte(rec_buf);
}
while(1)
{
ReverBit(PORTE,3);
delay_ms(500);//LED每隔500ms闪烁一次
}
}
——————————————————————————————————
基于CVAVR编译器 #include"avr/io.h"
#include"avr/interrupt.h"
#include"util/delay.h"
#define SetBit(Port,N)(Port|=(1<<N)) //设置IO某一位
#define ClrBit(Port,N)(Port&=~(1<<N)) //清空IO某一位
#define ReverBit(Port,N)(Port^=(1<<N)) //取反IO某一位
#define GetBit(Pin,N) ((Pin>>N)&0x01) //读取IO某一位
#define U2X01
#define UPE02
#define DOR03
#define FE0 4
#define UDRE0 5
#define RXC07
#define ext_sram_add1 (*(volatile unsigned char *)0x5555)
#define ext_sram_add2 (*(volatile unsigned char *)0x2aaa)
#define ext_sram_add3 (*(volatile unsigned char *)0x1100)
//#define ext_sram_add(i) (*(volatile unsigned char *)i)
//unsigned char ext_sram_add @0x1200; //外部FLASH的起始地址
//unsigned char *p=&ext_sram_add; //定义一个指针指向外部FLASH的起始地址
unsigned char data= {1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1,
1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1,
1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1,
1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1,
1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1,
1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1,
1,2,3,4,5,6,7,8};//作为写入FLASH测试用的
unsigned char data1={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x7e,0xe7,0x7e,0xe7,0xaa,
0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x7e,0xe7,0x7e,0xe7,0xaa,
0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x7e,0xe7,0x7e,0xe7,0xaa,
0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x7e,0xe7,0x7e,0xe7,0xaa,
0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x7e,0xe7,0x7e,0xe7,0xaa,
0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x7e,0xe7,0x7e,0xe7,0xaa,
0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
unsigned char rec_buf;//作为读出数据的缓冲
unsigned char rec_buf1;//作为读出数据的缓冲
/**************************************************
usart0初始化
**************************************************/
void USART0_Init(void)
{
UCSR0A=0x20; //波特率不加倍,单机通信模式
//UCSR0A=0x22; //波特率加倍,单机通信模式
UCSR0B=0x18; //中断不使能,允许发送和接收
UCSR0C=0x06;//异步模式,无校验,8位数据,1位停止位
//UCSR0C=0x36;//异步模式,odd奇校验,8位数据,1位停止位
UBRR0H=0x00;
//UBRR0L=47;//9600波特率 晶振7.3728
UBRR0L=95;//9600波特率 晶振14.7456
}
/**************************************************
串口发送一个字节
**************************************************/
void USART0_SendByte(unsigned char data)
{
while(!(UCSR0A&(1<<UDRE0)));//等待发送缓冲空
UDR0=data; //发送数据
}
/**************************************************************
向W29C020某一个扇区(128B)写数据 一共2的11次方2048个
扇区,参数high,low是最高地址线A17,A16
注意:地址范围为0x001100到0x11ffff,超出界限,结果不定,
比如第一扇区的的地址范围为0x001100~0x001180,第二扇区的地址为
0x001200~0x001280
前11位为页地址,后面7为某一页的字节地址
**************************************************************/
void Write_W29(unsigned char high ,unsigned char low,unsigned int addr,unsigned char len,unsigned char *dat)
{
unsigned char ii,byte_add;
unsigned intsect;
unsigned char buf;
unsigned char *ptr;
sect=addr-addr%128;
ptr=(unsigned char*)sect;
if(high==0x01)
{
SetBit(PORTD,7);
}
else
{
ClrBit(PORTD,7);
}
if(low==0x01)
{
SetBit(PORTD,6);
}
else
{
ClrBit(PORTD,6);
} //获取扇区地址
for (ii=0;ii<128;ii++)//写之前先读出128字节的变量
{
buf=*ptr;
ptr++;
}
ptr=(unsigned char*)sect;//指针返回到扇区首地址
byte_add=addr%128; //原先数据的字节末地址
ext_sram_add1=0xaa;
ext_sram_add2=0x55;
ext_sram_add1=0xa0; //软件保护模式下写数据到W29C020
for (ii=0;ii<byte_add;ii++) //写入原先不需要变化的数据
{
*ptr=buf;
ptr++;
}
ptr=(unsigned char*)(sect+byte_add);//指针指向需要改变信息的首地址
for (ii=0;ii<len;ii++) //写入len字节长度的需要变化的数据
{
*ptr=dat;
ptr++;
}
_delay_ms(10); //延时10MS等待写操作完成
}
/**************************************************************
读W29C020某一个扇区的len长度的数据
参数说明同写函数
**************************************************************/
void Read_W29(unsigned char high ,unsigned char low,unsigned int addr,unsigned char len,unsigned char *buf)
{
unsigned char ii;
unsigned char *ptr;
ptr=(unsigned char*)addr;
if(high==0x01)
{
SetBit(PORTD,7);
}
else
{
ClrBit(PORTD,7);
}
if(low==0x01)
{
SetBit(PORTD,6);
}
else
{
ClrBit(PORTD,6);
} //获取扇区地址
for (ii=0;ii<len;ii++)
{
buf=*ptr;
ptr++;
}
}
/**************************************************
主函数
**************************************************/
int main(void)
{
unsigned char i=0;
USART0_Init();//初始化USART0接口
MCUCR=0x80; //使能外部SRAM
XMCRA=0x00;
DDRE=0xff;
DDRD=0xff;
PORTD=0x00; //使能 CS A16 A17 =11
SetBit(PORTE,2); //程序启动蜂鸣器响50MS
_delay_ms(500.0);
ClrBit(PORTE,2); //关蜂鸣器
/*ext_sram_add1=0xaa;
ext_sram_add2=0x55;
ext_sram_add1=0x80;
ext_sram_add1=0xaa;
ext_sram_add2=0x55;
ext_sram_add1=0x60;
delay_us(15);
PORTD=0xc0;
USART0_SendByte( ext_sram_add3);
ext_sram_add1=0xaa;
ext_sram_add2=0x55;
ext_sram_add1=0xf0;
delay_us(15);*/ //测试返回W29C020的ID
//Write_W29(0,0,0x1100,128,data); //下数据到W29C020
//Write_W29(0,0,0x1180,128,data1);
_delay_ms(200);
//PORTD=0xc0;
//p=&ext_sram_add;
Read_W29(0,0,0x1100,128,rec_buf);
Read_W29(0,0,0x1180,128,rec_buf1);
for(i=0;i<128;i++) //通过串口发送读出的20字节FLASH数据
{
USART0_SendByte(rec_buf);
}
for(i=0;i<128;i++)
{
USART0_SendByte(rec_buf1);
}
while(1)
{
ReverBit(PORTE,3);
_delay_ms(500);//LED每隔500ms闪烁一次
}
}
————————————————————————————————-
基于GCCAVR编译器的 mark mark mark 谢谢分享。 正需要,不过M32该怎么用? 感谢分享!! 回复【6楼】root_007
正需要,不过m32该怎么用?
-----------------------------------------------------------------------
M32有总线吗?有的话 是一样 ,没有的话需要模拟 mark mark 谢谢分享 mark 谢谢 楼主分享 正好需要好吧 我觉得我可能挖坟了0.0
页:
[1]