AVR_DIY 发表于 2010-3-24 12:05:17

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编译器

AVR_DIY 发表于 2010-3-24 12:06:17

#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编译器的

wugaohui04 发表于 2010-3-24 12:42:33

mark

liumaojun_cn 发表于 2010-3-24 12:49:06

mark

wjc1956 发表于 2010-3-24 13:15:54

mark

1181zjf 发表于 2010-3-24 13:22:23

谢谢分享。

root_007 发表于 2010-9-25 16:34:35

正需要,不过M32该怎么用?

danielmi 发表于 2010-9-25 18:32:14

感谢分享!!

AVR_DIY 发表于 2010-9-26 23:19:04

回复【6楼】root_007
正需要,不过m32该怎么用?
-----------------------------------------------------------------------

M32有总线吗?有的话 是一样 ,没有的话需要模拟

cuikai12345 发表于 2010-9-26 23:45:14

mark

wshini7316 发表于 2011-2-11 11:20:29

mark

Forever 发表于 2011-2-11 12:50:19

谢谢分享

wshini7316 发表于 2011-2-24 16:41:18

mark

司空摘星 发表于 2014-2-21 10:50:52

谢谢 楼主分享 正好需要好吧 我觉得我可能挖坟了0.0
页: [1]
查看完整版本: MEGA128外扩flash AT29C020/W29c020读写程序(已测试 GCCAVR CVAVR)