AVR单片机Atmega128外扩RAM

 

 

由于AVR系列单片机采用的是内部外部RAM统一编址,ATmega128工作在非ATmega 103模式时具有4k+256B的包括寄存器文件(通用工作寄存器)、I/O寄存器、扩展I/O寄存器和内部SRAM的连续内部存储空间。所以在扩展外部RAM时,和内部SRAM地址重叠的外部RAM地址是不能直接访问的。也就是说扩展的外部RAM每64k要浪费掉内部SRAM那么大的空间(AT90系列如此)。所幸的是mega系列解决了这一缺点,专门有一个寄存器XMCRB用来解决对与内部SRAM地址空间相同地址的外部RAM访问。其低三位XMM2 、XMM1 、XMM0三位的设置,决定高位地址线PC口的哪些口线被释放为普通I/O,而不是作为高位地址。这样就可以巧妙地屏蔽高位,就ATmega128而言,要避开内部的4k+245B空间,注意到,只要所访问的地址范围大于0X1100(且MCUCR,XMCRA设置正确),那么所访问的就是外部RAM空间。所以在访问小于4k+245B的外部地址时,只要使地址大于0X10FF就可以访问了。0X1100用二进制表示为:0001,0001,0000,0000,高位地址线PC5、PC6、PC7没有使用到。在访问的时候就可设置XMCRB的XMM1、XMM0位为1,释放该三根地址线为普通I/O,将其设为输出。并且输出0;并在外部地址加上一个虚地址以使地址超过0X1100,如此设置,就可以访问外部0X0000~0X10FF空间了。超出这个空间,CPU就自动将其识别为外部相应的地址了,不用设置XMCRB寄存器(即不需释放任何总线),也不需加虚地址,按照正常外部RAM访问即可。在此约定所加的虚地址为0X2000,XMCRB寄存器设置为****,*011,所释放的地址线输出0。

表1 0-0X10FF范围的寄存器状态和寻址范围(略)

表2 各寻址范围地址线和寄存器状态表(略)

表3 各寻址范围地址线和寄存器状态表(略)

    比如要访问外部0X0200地址,用二进制表示为0000,0010,0000,0000。其中有6位高地址没有使用。按照约定设置XMCRB寄存器的为****,*011,并设置释放的PC5、PC6、PC7为输出,并输出0。为屏蔽内部RAM,在地址上加0X2000,所以在指令中使用的目标地址就是0X2200,二进制表示为:0010,0010,0000,0000;在指令中,CPU是把0X2200作为外部RAM 地址访问的(因为它大于0X10FF),并且输出的地址也是按照0X2200向外部RAM输出的。但是由于XMCRB的设置使PC5-PC7地址线被释放为普通I/O口,并且同时设置它们为输出状态,输出均为0。所以在执行访问指令时,PC5以上的地址根本就不起实际作用,0X2200只是一个虚地址,而实际指向的是外部RAM中的0000,0010。0000,0000。这样就"骗"过了CPU,对与内部0~0X10FF重叠编址的外部RAM地址成功进行了访问。当然,当外部RAM的地址大于0X10FF的时候,就可以不使用XMCRB寄存器,而直接进行访问了。表1列出了0~0X10FF范围的寄存器状态和寻址范围(采用加0X2000虚地址方法):

1. "*"表示该位对寻址操作无影响;"?"表示保留位;

2. XMCRA的设置,使整个外部0~0X10FF 空间的RAM被看成是一个部分,并且在访问它时产生两个周期的等待;

3. XMCRB的设置,表示在对该地址范围进行寻址时,使能总线保持,并且释放PC5、PC6、PC7三根高位地址线为普通I/O,并且输出0。
8位单片机的可寻址范围为64k,但是如果加上真实I/O口作为地址线,可寻址范围就大得多了。就本系统设计而言,以PD口的PD0、PD1、PD2作为地址线A16、A17、A18,另外再使用PD3和PD4分别作为两片512的片选信号,可寻址范围可扩展到1M。在寻址0X1100~0XFFFF 64K范围内时,可以在使相应的512片选有效高的同时将三位地址A16、A17、A18置低,就可在64K范围内正常寻址;在此范围之外寻址时,需要对A16、A17、A18三个地址线进行相关操作。表2、表3列出了不同寻址范围A16、A17、A18的状态以及寻址范围:

1. "*"表示该位与该范围内的寻址操作无关;"?"表示保留位;
2. 表2表示在每个个64K寻址范围中的0X1100~0XFFFF空间,0~0X10FF空间将按照表3所示的虚地址方式寻址;

3. XMCRA的设置,使整个外部0~0X10FF 空间的RAM被看成是一个部分,并且在访问它时产生两个周期的等待;

4. 表2的XMCRB的设置,使在对该地址范围进行寻址时,使能总线保持;并不释放任何地址线;而表三表示释放PC5、PC6、PC7三位高地址线作为普通I/O,并且输出0;

5. 表3中对外部SRAM的访问,是按照先前的约定,采用增加0X2000虚地址。

    为保证数据采集的准确性和适时性,需要精确确定采样时间,做到采集和处理两不误。由于温度信号变化比较慢,而且比较有线性规律。所以设定通道0采集振动信号,通道1采集温度信号,振动信号的采样率为温度信号的50倍。即先进行50次振动信号采集后,切换通道,进行温度信号的采集,之后再切换到振动采集通道。对ADC转换启动噪声抑制功能,采用中断编程。ATmega128采用外部16MHz时钟。(由于Can已经是一种比较成熟和常用的总线技术,在此不做过多介绍)

AVR单片机Atmega128外扩RAM

 

     硬件连接和普通的51单片机外扩是一样的。

 

AVR单片机Atmega128外扩RAM

    内存分布。

以下是测试程序:

// Target : ATMEGA128
// Crystal : 7.3728Mhz
// Modifed By : Moxudong
// Date : 2010.03

#include<avr/io.h>
#include<util/delay.h>
#include <avr/interrupt.h> //中断函数头文件

#include<stdio.h>
#include<string.h>

//PG0 0x65
#define WRL (PORTG=PORTG&0XFE)
#define WRH (PORTG=PORTG|0X01)

//PG1
#define RDL (PORTG=PORTG&0XFD)
#define RDH (PORTG=PORTG|0X02)

//PG2
#define ALEL (PORTG=PORTG&0XFB)
#define ALEH (PORTG=PORTG|0X04)

//MCU时钟频率
#undef F_CPU
//#define F_CPU 7372800UL
//默认的系统BAUD
#define baud 115200
//#define fosc 7372800UL //晶振7.3728MHZ
#define fosc 16000000UL

//#define baud 9600//波特率

#define MCUBAUD9600 1

//declare memory mapped variables
//#define txbuf1_head 0x1100

//extern unsigned char txbuf1[256];
#define ext_PORT1 ((volatile unsigned char *)0x1100)
unsigned char *p=(unsigned char *)ext_PORT1;
unsigned char testramtable[4]={0x00,0x55,0xaa,0x00};

void Delay1ms(void)
{
    unsigned int i;
    for(i=0;i<=(unsigned int)(16*143-2);i++);
}

void Delayxms(unsigned char ms)
{
    unsigned char i;
    for(i=0;i<=ms;i++)
    Delay1ms();
}

//unsigned char readram(unsigned int iaddr);
void port_init(void);
void uart1_init(void);
//void writeram(unsigned int iaddr, unsigned char ctemp);
void test_ram(void);
void test_net(void);
//void sendstring1(unsigned int * txbuf);

char char2hex(char t1)
{
    if((t1>=00) &&(t1<=0x09))
    {
        t1=t1+0x30;//'0'--'9'
    }
    else
    {
    if((t1>=0x0a)&&(t1<=0x0f))//'A'--'F'
    t1=t1-0x0a+0x61;
    }
    return t1;
}

void sendinthex1(unsigned int c)
{
    char temph=0,templ=0;
    char t1=0,t2=0;
    temph=c/256;
    templ=c%6;
    t1=(c/256)/16;
    //t1=t1>>8;
    UDR1 = char2hex(t1);
    while(!(UCSR1A & 0x40));
    UCSR1A |=0x40;
    t1=(c/256);
    UDR1 = char2hex(t1);
    while(!(UCSR1A & 0x40));
    UCSR1A |=0x40;
    t2=(c%6)/16;//templ&0xf0;
    //t2=t2>>8;
    UDR1 = char2hex(t2);
    while(!(UCSR1A & 0x40));
    UCSR1A |=0x40;
    t2=(c%6);//templ&0x0f;
    UDR1 = char2hex(t2);
    while(!(UCSR1A & 0x40));
    UCSR1A |=0x40;
}

void sendchar1(char c) // 发送
{
    UDR1 = c;
    while(!(UCSR1A & 0x40));
    UCSR1A |=0x40;
}

void sendint1(unsigned int c) // 发送
{
    UDR1 = (c&0xff00)>>8;
    while(!(UCSR1A & 0x40));
    UCSR1A |=0x40;
    UDR1 = c&0xff;
    while(!(UCSR1A & 0x40));
    UCSR1A |=0x40;
}

void sendstring1(unsigned char * txbuf) // 发送
{
    unsigned int j;
    for (j = 0; *txbuf; j++, txbuf++)
        sendchar1(*txbuf);
}

void port_init(void)
{
    //PA AD0-AD7 地址
    //PC AD8-AD15
    PORTA = 0xFF;
    DDRA = 0xFF;

    PORTC = 0xFF; //m103 output only
    DDRC = 0x00;

    //PB4 NETRST O

    PORTB = 0xFF;
    DDRB = 0x10;

    PORTD = 0xFF;
    DDRD = 0x00;

    PORTE = 0xFF;
    DDRE = 0x00;

    PORTF = 0xFF;
    DDRF = 0x00;

    PORTG = 0x1F;
    DDRG = 0x00;
}

//UART0 initialisation
// desired baud rate:115200
// actual baud rate:111111 (3.7%)
// char size: 8 bit
// parity: Disabled


//UART1 initialisation
// desired baud rate:115200
// actual baud rate:111111 (3.7%)
// char size: 8 bit
// parity: Disabled
void uart1_init(void)
{
    UCSR1B = 0x00; //disable while setting baud rate
    UCSR1A = 0x00;
    UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);//8bit+1bit stop
    UBRR1L=(fosc/16/(baud+1))%6;
    UBRR1H=(fosc/16/(baud+1))/256;
    UCSR1B =(1<<RXEN1)|(1<<TXEN1);//RXCEN TXCEN
}



//call this routine to initialise all peripherals
void init_devices(void)
{
    cli(); //disable all interrupts
    port_init();
    uart1_init();
}

#if 0

unsigned char readram(unsigned int iaddr)
{
    //unsigned char caddl,caddh;
    unsigned char cdatatemp=0;
    RDH;
    WRH;
    ALEH;
    DDRA = 0xFF;
    DDRC = 0xFF;
    PORTC=iaddr>>8;
    PORTA=(unsigned char)iaddr;
    asm("nop;");
    ALEL; //LATCH IT
    DDRA = 0x00;//PORT INPUT
    RDL;
    // send wr
    asm("nop;");
    cdatatemp=PINA;
    RDH;
    ALEH;
    return cdatatemp;
}
void writeram(unsigned int iaddr, unsigned char ctemp)
{
    //unsigned char caddl,caddh;
    unsigned char cdatatemp=0;
    RDH;
    WRH;
    ALEH;
    DDRA = 0xFF;
    DDRC = 0xFF;
    PORTC=iaddr>>8;
    PORTA=(unsigned char)iaddr;
    ALEL;//锁存A0-A7
    WRL;
    PORTA=ctemp;
    asm("nop;");
    WRH;
    ALEH;
    return;
}

#endif

#define RAMSTARTADDR 0X1100
#define RAMENDADDR 0X90FF
#define RAMLEN 32768
// 测试32KRAM 用的是UT62256和74HC573

int main(void)
{
    unsigned int k=0;
    unsigned int i=0,j=0;
    unsigned char DATA,u;

    init_devices();

    MCUCR = 0x80; // 允许外部并行扩展接口
    XMCRA = 0x00; //0x00 external memory

    XMCRB = 0x01; // 释放PC7,作为通用I/O引脚使用
    DDRC = 0xff; // PC7,PC6用于输出,(不影响PC0-PC6地址线)
    PORTC = 0x00; // PC7,PC6输出0,(不影响PC0-PC6地址线)
    //由于是32KB所以PC7用作62256片选使能,可以释放P7为普通IO使用,输出低电平使能62256
    sendstring1("init system ok!rn");
    sendstring1("now test system-ram all is 32k !rn");

    sendstring1("----now write ramrn");
    _delay_ms(1300);
#if 1
    for(i=0;i<32768;i++)
    {
        if(i%2)
        *(p+i)=(unsigned char)(p+i);
        else
        *(p+i)=0xff;
        _delay_us(10);
    }
// #else
    sendstring1("----write okrn");
    sendstring1("----now check writern");
    sendstring1("----now read ramrn");
    for(i=0;i<32768;i++)
    {
        DATA = *(p+i);
        sendstring1("addr=");
        sendinthex1((unsigned int)(p+i));
        sendstring1("=");
        sendinthex1(DATA);
        sendstring1("rn");
    }
#endif
    sendstring1("---- test system-ram end!rn");
}

      由于AVR系列单片机采用的是内部外部RAM统一编址,ATmega128工作在非ATmega 103模式时具有4k+256B的包括寄存器文件(通用工作寄存器)、I/O寄存器、扩展I/O寄存器和内部SRAM的连续内部存储空间。所以在扩展外部RAM时,和内部SRAM地址重叠的外部RAM地址是不能直接访问的。也就是说扩展的外部RAM每64k要浪费掉内部SRAM那么大的空间(AT90系列如此)。所幸的是mega系列解决了这一缺点,专门有一个寄存器XMCRB用来解决对与内部SRAM地址空间相同地址的外部RAM访问。其低三位XMM2 、XMM1 、XMM0三位的设置,决定高位地址线PC口的哪些口线被释放为普通I/O,而不是作为高位地址。这样就可以巧妙地屏蔽高位,就ATmega128而言,要避开内部的4k+245B空间,注意到,只要所访问的地址范围大于0X1100(且MCUCR,XMCRA设置正确),那么所访问的就是外部RAM空间。所以在访问小于4k+245B的外部地址时,只要使地址大于0X10FF就可以访问了。0X1100用二进制表示为:0001,0001,0000,0000,高位地址线PC5、PC6、PC7没有使用到。在访问的时候就可设置XMCRB的XMM1、XMM0位为1,释放该三根地址线为普通I/O,将其设为输出。并且输出0;并在外部地址加上一个虚地址以使地址超过0X1100,如此设置,就可以访问外部0X0000~0X10FF空间了。超出这个空间,CPU就自动将其识别为外部相应的地址了,不用设置XMCRB寄存器(即不需释放任何总线),也不需加虚地址,按照正常外部RAM访问即可。在此约定所加的虚地址为0X2000,XMCRB寄存器设置为****,*011,所释放的地址线输出0。

 

表1 0-0X10FF范围的寄存器状态和寻址范围(略)

 

表2 各寻址范围地址线和寄存器状态表(略)

 

表3 各寻址范围地址线和寄存器状态表(略)

 

    比如要访问外部0X0200地址,用二进制表示为0000,0010,0000,0000。其中有6位高地址没有使用。按照约定设置XMCRB寄存器的为****,*011,并设置释放的PC5、PC6、PC7为输出,并输出0。为屏蔽内部RAM,在地址上加0X2000,所以在指令中使用的目标地址就是0X2200,二进制表示为:0010,0010,0000,0000;在指令中,CPU是把0X2200作为外部RAM 地址访问的(因为它大于0X10FF),并且输出的地址也是按照0X2200向外部RAM输出的。但是由于XMCRB的设置使PC5-PC7地址线被释放为普通I/O口,并且同时设置它们为输出状态,输出均为0。所以在执行访问指令时,PC5以上的地址根本就不起实际作用,0X2200只是一个虚地址,而实际指向的是外部RAM中的0000,0010。0000,0000。这样就"骗"过了CPU,对与内部0~0X10FF重叠编址的外部RAM地址成功进行了访问。当然,当外部RAM的地址大于0X10FF的时候,就可以不使用XMCRB寄存器,而直接进行访问了。表1列出了0~0X10FF范围的寄存器状态和寻址范围(采用加0X2000虚地址方法):

 

1. "*"表示该位对寻址操作无影响;"?"表示保留位;

 

2. XMCRA的设置,使整个外部0~0X10FF 空间的RAM被看成是一个部分,并且在访问它时产生两个周期的等待;

 

3. XMCRB的设置,表示在对该地址范围进行寻址时,使能总线保持,并且释放PC5、PC6、PC7三根高位地址线为普通I/O,并且输出0。

8位单片机的可寻址范围为64k,但是如果加上真实I/O口作为地址线,可寻址范围就大得多了。就本系统设计而言,以PD口的PD0、PD1、PD2作为地址线A16、A17、A18,另外再使用PD3和PD4分别作为两片512的片选信号,可寻址范围可扩展到1M。在寻址0X1100~0XFFFF 64K范围内时,可以在使相应的512片选有效高的同时将三位地址A16、A17、A18置低,就可在64K范围内正常寻址;在此范围之外寻址时,需要对A16、A17、A18三个地址线进行相关操作。表2、表3列出了不同寻址范围A16、A17、A18的状态以及寻址范围:

 

1. "*"表示该位与该范围内的寻址操作无关;"?"表示保留位;

2. 表2表示在每个个64K寻址范围中的0X1100~0XFFFF空间,0~0X10FF空间将按照表3所示的虚地址方式寻址;

 

3. XMCRA的设置,使整个外部0~0X10FF 空间的RAM被看成是一个部分,并且在访问它时产生两个周期的等待;

 

4. 表2的XMCRB的设置,使在对该地址范围进行寻址时,使能总线保持;并不释放任何地址线;而表三表示释放PC5、PC6、PC7三位高地址线作为普通I/O,并且输出0;

 

5. 表3中对外部SRAM的访问,是按照先前的约定,采用增加0X2000虚地址。

 

    为保证数据采集的准确性和适时性,需要精确确定采样时间,做到采集和处理两不误。由于温度信号变化比较慢,而且比较有线性规律。所以设定通道0采集振动信号,通道1采集温度信号,振动信号的采样率为温度信号的50倍。即先进行50次振动信号采集后,切换通道,进行温度信号的采集,之后再切换到振动采集通道。对ADC转换启动噪声抑制功能,采用中断编程。ATmega128采用外部16MHz时钟。(由于Can已经是一种比较成熟和常用的总线技术,在此不做过多介绍)

 AVR单片机Atmega128外扩RAM

 

 

     硬件连接和普通的51单片机外扩是一样的。

 AVR单片机Atmega128外扩RAM

 

 

    内存分布。

 

以下是测试程序:

 

// Target : ATMEGA128

// Crystal : 7.3728Mhz

// Modifed By : Moxudong

// Date : 2010.03

 

#include<avr/io.h>

#include<util/delay.h>

#include <avr/interrupt.h> //中断函数头文件

 

#include<stdio.h>

#include<string.h>

 

//PG0 0x65

#define WRL (PORTG=PORTG&0XFE)

#define WRH (PORTG=PORTG|0X01)

 

//PG1

#define RDL (PORTG=PORTG&0XFD)

#define RDH (PORTG=PORTG|0X02)

 

//PG2

#define ALEL (PORTG=PORTG&0XFB)

#define ALEH (PORTG=PORTG|0X04)

 

//MCU时钟频率

#undef F_CPU

//#define F_CPU 7372800UL

//默认的系统BAUD

#define baud 115200

//#define fosc 7372800UL //晶振7.3728MHZ

#define fosc 16000000UL

 

//#define baud 9600//波特率

 

#define MCUBAUD9600 1

 

//declare memory mapped variables

//#define txbuf1_head 0x1100

 

//extern unsigned char txbuf1[256];

#define ext_PORT1 ((volatile unsigned char *)0x1100)

unsigned char *p=(unsigned char *)ext_PORT1;

unsigned char testramtable[4]={0x00,0x55,0xaa,0x00};

 

void Delay1ms(void)

{

    unsigned int i;

    for(i=0;i<=(unsigned int)(16*143-2);i++);

}

 

void Delayxms(unsigned char ms)

{

    unsigned char i;

    for(i=0;i<=ms;i++)

    Delay1ms();

}

 

//unsigned char readram(unsigned int iaddr);

void port_init(void);

void uart1_init(void);

//void writeram(unsigned int iaddr, unsigned char ctemp);

void test_ram(void);

void test_net(void);

//void sendstring1(unsigned int * txbuf);

 

char char2hex(char t1)

{

    if((t1>=00) &&(t1<=0x09))

    {

        t1=t1+0x30;//'0'--'9'

    }

    else

    {

    if((t1>=0x0a)&&(t1<=0x0f))//'A'--'F'

    t1=t1-0x0a+0x61;

    }

    return t1;

}

 

void sendinthex1(unsigned int c)

{

    char temph=0,templ=0;

    char t1=0,t2=0;

    temph=c/256;

    templ=c%6;

    t1=(c/256)/16;

    //t1=t1>>8;

    UDR1 = char2hex(t1);

    while(!(UCSR1A & 0x40));

    UCSR1A |=0x40;

    t1=(c/256);

    UDR1 = char2hex(t1);

    while(!(UCSR1A & 0x40));

    UCSR1A |=0x40;

    t2=(c%6)/16;//templ&0xf0;

    //t2=t2>>8;

    UDR1 = char2hex(t2);

    while(!(UCSR1A & 0x40));

    UCSR1A |=0x40;

    t2=(c%6);//templ&0x0f;

    UDR1 = char2hex(t2);

    while(!(UCSR1A & 0x40));

    UCSR1A |=0x40;

}

 

void sendchar1(char c) // 发送

{

    UDR1 = c;

    while(!(UCSR1A & 0x40));

    UCSR1A |=0x40;

}

 

void sendint1(unsigned int c) // 发送

{

    UDR1 = (c&0xff00)>>8;

    while(!(UCSR1A & 0x40));

    UCSR1A |=0x40;

    UDR1 = c&0xff;

    while(!(UCSR1A & 0x40));

    UCSR1A |=0x40;

}

 

void sendstring1(unsigned char * txbuf) // 发送

{

    unsigned int j;

    for (j = 0; *txbuf; j++, txbuf++)

        sendchar1(*txbuf);

}

 

void port_init(void)

{

    //PA AD0-AD7 地址

    //PC AD8-AD15

    PORTA = 0xFF;

    DDRA = 0xFF;

 

    PORTC = 0xFF; //m103 output only

    DDRC = 0x00;

 

    //PB4 NETRST O

 

    PORTB = 0xFF;

    DDRB = 0x10;

 

    PORTD = 0xFF;

    DDRD = 0x00;

 

    PORTE = 0xFF;

    DDRE = 0x00;

 

    PORTF = 0xFF;

    DDRF = 0x00;

 

    PORTG = 0x1F;

    DDRG = 0x00;

}

 

//UART0 initialisation

// desired baud rate:115200

// actual baud rate:111111 (3.7%)

// char size: 8 bit

// parity: Disabled

 

//UART1 initialisation

// desired baud rate:115200

// actual baud rate:111111 (3.7%)

// char size: 8 bit

// parity: Disabled

void uart1_init(void)

{

    UCSR1B = 0x00; //disable while setting baud rate

    UCSR1A = 0x00;

    UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);//8bit+1bit stop

    UBRR1L=(fosc/16/(baud+1))%6;

    UBRR1H=(fosc/16/(baud+1))/256;

    UCSR1B =(1<<RXEN1)|(1<<TXEN1);//RXCEN TXCEN

}

 

 

//call this routine to initialise all peripherals

void init_devices(void)

{

    cli(); //disable all interrupts

    port_init();

    uart1_init();

}

 

#if 0

 

unsigned char readram(unsigned int iaddr)

{

    //unsigned char caddl,caddh;

    unsigned char cdatatemp=0;

    RDH;

    WRH;

    ALEH;

    DDRA = 0xFF;

    DDRC = 0xFF;

    PORTC=iaddr>>8;

    PORTA=(unsigned char)iaddr;

    asm("nop;");

    ALEL; //LATCH IT

    DDRA = 0x00;//PORT INPUT

    RDL;

    // send wr

    asm("nop;");

    cdatatemp=PINA;

    RDH;

    ALEH;

    return cdatatemp;

}

void writeram(unsigned int iaddr, unsigned char ctemp)

{

    //unsigned char caddl,caddh;

    unsigned char cdatatemp=0;

    RDH;

    WRH;

    ALEH;

    DDRA = 0xFF;

    DDRC = 0xFF;

    PORTC=iaddr>>8;

    PORTA=(unsigned char)iaddr;

    ALEL;//锁存A0-A7

    WRL;

    PORTA=ctemp;

    asm("nop;");

    WRH;

    ALEH;

    return;

}

 

#endif

 

#define RAMSTARTADDR 0X1100

#define RAMENDADDR 0X90FF

#define RAMLEN 32768

// 测试32KRAM 用的是UT62256和74HC573

 

int main(void)

{

    unsigned int k=0;

    unsigned int i=0,j=0;

    unsigned char DATA,u;

 

    init_devices();

 

    MCUCR = 0x80; // 允许外部并行扩展接口

    XMCRA = 0x00; //0x00 external memory

 

    XMCRB = 0x01; // 释放PC7,作为通用I/O引脚使用

    DDRC = 0xff; // PC7,PC6用于输出,(不影响PC0-PC6地址线)

    PORTC = 0x00; // PC7,PC6输出0,(不影响PC0-PC6地址线)

    //由于是32KB所以PC7用作62256片选使能,可以释放P7为普通IO使用,输出低电平使能62256

    sendstring1("init system ok!rn");

    sendstring1("now test system-ram all is 32k !rn");

 

    sendstring1("----now write ramrn");

    _delay_ms(1300);

#if 1

    for(i=0;i<32768;i++)

    {

        if(i%2)

        *(p+i)=(unsigned char)(p+i);

        else

        *(p+i)=0xff;

        _delay_us(10);

    }

// #else

    sendstring1("----write okrn");

    sendstring1("----now check writern");

    sendstring1("----now read ramrn");

    for(i=0;i<32768;i++)

    {

        DATA = *(p+i);

        sendstring1("addr=");

        sendinthex1((unsigned int)(p+i));

        sendstring1("=");

        sendinthex1(DATA);

        sendstring1("rn");

    }

#endif

    sendstring1("---- test system-ram end!rn");

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值