AVR单片机Atmega128外扩RAM
来源:互联网 发布:php页面跳转url不变 编辑:程序博客网 时间:2024/06/03 12:31
由于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 各寻址范围地址线和寄存器状态表(略)
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虚地址。
以下是测试程序:
// 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)
{
}
void Delayxms(unsigned char ms)
{
}
//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)
{
}
void sendinthex1(unsigned int c)
{
}
void sendchar1(char c) // 发送
{
}
void sendint1(unsigned int c) // 发送
{
}
void sendstring1(unsigned char * txbuf) // 发送
{
}
void port_init(void)
{
}
//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)
{
}
//call this routine to initialise all peripherals
void init_devices(void)
{
}
#if 0
unsigned char readram(unsigned int iaddr)
{