CPLD扩展51单片机寻址范围
扫描二维码
随时随地手机看文章
引言:
受其内部资源的限制,在很多应用中,单片机需要在片外扩展相关资源,如程序存储器,数据存储器,IO口,以及中断源等等。一般情况下51单片机地址线为16根(P0及P2),因此其地址空间为,也即64K。考虑到某些不需要高速度的应用场合,可以用单片机的一个八位IO口(如P0),多次输出地址,通过CPLD将这些地址位整合起来,并输出到相应的设备,这样,即可实现用单片机的一个八位IO口来实现多位地址的功能。
1. 51单片机扩展FLASH存储器
51单片机的系统扩展以单片机的P2口作为指令地址的高八位,P0口作为低八位地址并复用为数据线。下面以扩展ATMEL公司的AT29C020 flash芯片为例,该芯片地址线18根,容量为256K字节,其读写时序如图1:
如果采用上述常用接法,则用P0口通过74LS373接AT29C020地址低八位,同时P0接AT29C020的八位数据口,P2接高八位地址,而AT29C020的A16,A17两位地址位接P1.0,P1.1,从而由P1.0,P1.1与P0和P2口共同构成18位地址线
由接线图可知,对AT29C020进行读写操作时,需先将P1.0和P1.1置成相应电平,然后将低16位地址写入DPTR,再用指令 MOVX A, @DPTR或者MOVX @DPTR, A 来读或写AT29C020。
可见,为满足18位地址的AT29C020,单片机共用去了包括P0,P1,P2在内的18个IO口,同时考虑到P3口一般复用为其他功能,如果系统还需要进行其它的IO操作(比如将flash中的数据输出到LCD显示),硬件资源已经是捉襟见肘。并且随着存储器的容量进一步扩大,IO资源将更加紧张。所以在下文中,将讨论如何使用CPLD芯片来扩展单片机的寻址空间。
2. MAX7128S CPLD
CPLD属于ASIC,其内部有大量的门电路,通过软件编程可以实现这些门电路的不同连接关系,从而使CPLD对外完成不同的功能,而这些连接关系可以通过软件的改变而不断的改变。从功能上来看,CPLD可以完成任何数字器件的功能,上至高性能的CPU,下至简单的74电路。
目前,最大的两家PLD/FPGA厂商分别是ALTERA以及XILINX,其中Altera 公司的产品基本上都属于CPLD 结构。由于它的内部连线均采用连续式互联结构,MAX 系列是Altera 目前最为流行,使用最广泛的两个系列之一。本文所采用的MAX7128S芯片就是属于MAX7000S系列的一款CPLD芯片,它包含1800个可用门,96个宏单元。
3. 相关硬件及接线示意图
本应用中单片机选用PHILIPS公司的P89C61X2,相关硬件连接示意图见图三
4.CPLD及单片机程序设计
在应用中,将CPLD的4,5,6,8,9,10,11,12,15,16,17,18,20,21,22,24,25,27脚配置成连接 AT29C020地址线,将46,48,49,50,51,52,54,55脚配置成接受单片机P0口地址数据的输入口,并将41,44脚配置成连接 FLASH芯片的WE,OE引脚。
4.1 CPLD程序
本例中,采用硬件描述语言VHDL来编写CPLD程序,相关代码如下:
entity mcu_to_flash is
port ( clk : in std_logic;
add : in bit_vector (7 downto 0); --地址输入
flash_add : out bit_vector (17 downto 0); --地址输出(到flash)
oe : out std_logic; --到flash的oe
we : out std_logic ); --到flash的we
end mcu_flash;
architecture func1 of mcu_flash is
signal counter : integer range 0 to 10000; --定义一个计数器
signal add_reg : bit_vector (17 downto 0); --定义寄存器add_reg用于缓存地址
begin
process (clk)
begin
if (clk'event and clk='1') then
case add(7 downto 6) is
when "00" =>
add_reg (5 downto 0) <= add (5 downto 0); --地址0到5
counter <= 0;
when "01" =>
add_reg (11 downto 6) <= add (5 downto 0); --地址6-11
counter <= counter + 1;
if (counter = 5) then --恢复OE,WE到高电平,为后面产生下降沿作准备
oe <= '1';
we <= '1';
end if;
when "10" =>
add_reg (17 downto 12) <= add (5 downto 0); --地址12-17
counter <= 0;
when "11" =>
flash_add <= add_reg; --输出地址
counter <= counter + 1;
if (counter = 5) then --产生OE,WE的下降沿
oe <= '0';
end if;
end case;
end if;
end process;
end func1;
从程序可见,本例中单片机需要写四次P0口进行一次读/写操作,且这四次写入P0的数据的高两位应该分别为 “00”;“01”;“10”;“11”,CPLD将该两位作为标志位判断其后六位分别是所需地址的哪几位,将前三次P0口数据的低六位“拼”成 FLASH的18位地址,并在第四次写P0口时将该地址输出到FLASH的相应地址位,同时由CPLD产生OE或者WE的下降沿信号,以满足FLASH的读/写时序要求。
上述VHDL程序经MAX+PLUS II仿真器进行仿真,结果如图四:
如图,仿真中共有两次读操作。第一次操作时四次输入的地址值(十六进制)分别为:2C,4D,93,FD, 也即二进制的“00101100”;“01001101”;“10010011”;“11111101”,如前所述,此时希望得到的地址应该是 “010011001101101100”,换算成16进制即为1336C,与仿真结果一致,同时,在地址线(flash_add)得到地址值一段时间(时间值由程序中counter值判断条件控制)之后,OE产生下降沿,与FLASH芯片读写时续的要求一致。可以验证,第二次结果也和预期一致。值得注意的是,在仿真中,方便起见CPLD的时钟输入并没有和实际硬件一致,故在实际应用中,程序里面“counter”后一次判断条件中的数值应该保证能够满足FLASH芯片的时值要求。此外,针对本试验,程序中只给出了OE的下降沿,实际应用中,需要根据需要给出WE的下降沿。
4.2单片机程序
void Readflash (unsigned int add)
{char temp1,temp2,temp3; //定义三个变量缓存分三次输入的地址
temp1=add; //低六位地址
temp1 &= 0x3f; //将高两位清零,作为第一次写P0口的值
temp2=add>>6; //中六位地址
temp2 &= 0x3f;
temp2 |= 0x40; //将高两位置为01,作为第二次写P0口的值
temp3=add>>12; //高六位地址
temp3 &= 0x3f;
temp3 |= 0x80; //将高两位置为11,作为第三次写P0口的值
P0=temp1; P0=temp2; P0=temp3; P2=0xc0; }
//写P0口四次,写完之后,AT29C020的数据端口即输出有效数据。
可见,函数Readflash的入口地址为FLASH芯片的18位地址,调用该函数后,FLASH芯片的输出为该地址对应的数据,即可进行下一步的操作。
5.实验结果
本例中,用单片机的P1口读出该数据,并用P2口输出到8个LED,以判断数据是否正确。经过多次试验,证明所读出的数据正确无误。(FLASH中已经在实验前写入数据)
6.小结
本文提出了一种用CPLD器件扩展51单片机寻址范围的思路,并通过实际验证可行。在实际应用中,可以考虑用CPLD通过单片机固定的操作时间来判断单片机的地址信号是所需地址空间中的哪一个部分,从而替代本例中所采用的标志位,在不损失时间的情况下进一步扩大寻址范围和应用的灵活性。
参考文献
1 周立功. 单片机与CPLD综合应用技术. 北京. 北京航空航天大学出版社.
2 杨恒 FPGA/VHDL快速工程实践入门与提高 北京. 北京航空航天大学出版社.
3 马忠梅.单片机的C语言应用程序设计.北京:北京航空航天大学出版社