综合资讯 在线阅读 原文阅读 在线商城 下载专区 DATASHEET 技术论坛 商务频道

嵌入式系统  单片机  D S P  EDA/PLD  接口电路  存储技术  显示光电  电源技术
传感/控制  模拟技术  通信网络  无线通信  电测仪表  消费电子  汽车电子

所在的位置:首页技术文章接口电路正文
 
基于PC/104总线与CPLD的SPI接口设计
发布日期:2005-12-22 作者:梁祥 封吉平 安学军 来源:微计算机信息

  要:本文根据SPI同步串行接口的通信协议,介绍了在CPLD中利用VHDL语言实现PC/104总线扩展SPI接口的设计原理和编程思想。通过该方法的介绍,使得那些没有SPI接口功能的处理器和控制器能够扩展SPI接口,以便同外部设备进行数据交换。并给出了VHDL语言的源代码程序。

关键词:SPI接口;CPLD;PC/104总线;接口设计;VHDL

0 引言

近年来,带有SPI总线接口的器件越来越多,该器件可以共用SPI总线,十分方便的组成多个带有SPI总线接口的系统。尽管这种总线结构没有并行总线那样大的吞吐能力,但由于连接线和连接引脚少,因此其构成的系统价格降低,器件间总线连接简单,结构紧凑,而且在总线上增加器件不影响系统的正常工作,系统修改和可扩张性好。

PC/104与标准台式PC(PC/AT)体系无论是硬件还是软件上都完全兼容。在形态上,PC/104是十分紧凑的、自栈式、模块化结构。如今利用PC/104总线来制作各种各样的设备越拉越多,在使用的过程中,经常要用到具有SPI总线接口的器件。本文将介绍一种基于CPLD来实现PC/104总线扩展SPI接口的设计方案。

1 SPI总线接口及时序

SPI(Serial Peripheral Interface)总线接口是一种同步串行数据接口。 这一通讯接口采用单独的三根信号线(SCLK、MOSI、MISO)传送数据及同步时钟,可以实现全双工通信,由CS片选线实现多机通信或扩展多片SPI芯片。

SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。SPI主模块和与之通信的外设间时钟相位和极性应该一致。SPI 接口时序如图1、图2所示。  

 

2 设计方案

本文以PC/104总线与多个SPI接口模块为例,说明基于CPLD的SPI总线接口设计方案。通过CPLD整合时序实现PC/104总线与SPI总线的转换,满足SPI总线的时序要求。

利用CPLD具有以下优点:①采用CPLD可以根据需要定义输入输出脚,方便PCB板布局和走线;②采用CPLD时不必担心设计中所采用器件的种类、数量,可以任意定义所需各种器件,从而优化电路性能;③采用CPLD可以通过软件对电路进行仿真,方便电路调试;④采用CPLD可以在线修改其内部逻辑,升级或修改可不改动外部电路。

CPLD芯片选用ALTERA公司的EPM7064SLC84-10,该芯片具有基于EEPROM的第二代MAX结构,支持通过JTAG引脚实现在系统编程。拥有64个宏单元,4个逻辑阵列块,1250个可用门单元,支持5V/3.3V多电压IO接口,可提供68个用户IO引脚

2.1 系统的结构设计

系统的基本功能是通过CPLD来实现PC/104总线与SPI总线的数据交换。系统的结构框图如图3所示。系统主要由两部分组成:一是PC/104总线与CPLD的接口;另一是SPI接口。为了能在PC/104总线制定的时刻读/写SPI接口的数据,使用PC/104总线的读写信号、同步时钟、数据总线和地址总线。                     

2.2 SPI接口的设计结构

基于CPLD设计的SPI接口其目的在于为PC/104处理器扩展SPI接口的功能。能够实现PC/104总线与SPI总线之间的通信。为了满足扩展SPI接口功能,基于CPLD的SPI接口必须具有以下功能:①与PC/104总线的接口功能;②多位外部从机选择功能;③时钟极性和相位选择不同,有四种传输模式功能;④SPI数据传送完成标志。在SPI接口中,芯片EPM7128SLC-84的I/O接口被定义为SPI接口的控制线、数据线和地址线等。SPI接口的结构框图如图4所示。在我们设计的速率校准装置的SPI接口中,状态端RDY和片选端CS已经够用。如果外部有更多的SPI接口模块,我们可以通过软件的编程与设置,扩展更多的状态端RDY和片选端CS,并共用时钟线和数据线,实现扩展具有SPI接口的外部设备。

                                             

3 时序

    PC/104总线对SPI总线的访问很简单,只需对SPI接口模块内的数据寄存器(30AH)、控制寄存器(304H)以及状态寄存器(300H)进行读写。其中控制寄存器功能有中断使能位、MOSI高阻位、时钟极性与相位以及片选信号;状态寄存器可以读取RDY的状态以及中断标志。下面以读和写两种时序来说明PC/104总线对SPI接口访问时SPI接口的时序图。

在对SPI接口写数据时,它的工作过程是先向控制寄存器内写入控制字,以确定工作方式。然后再向数据寄存器写入要发送的数据,工作时序图5所示。

在对SPI接口读数据时,同样需要向控制寄存器写入控制字,以确定其工作方式,并使MOSI处于高阻状态。然后向数据寄存器内写入任意值,其目的是产生同步时钟脉冲以及移位寄存器开始工作,以使外部MISO信号传送到移位寄存器内。当IRQ为高电平,说明数据接收完成,即可读取移位寄存器内的数据即为SPI接口发送的数据,工作时序图6所示。

图5 SPI接口写工作时序图                     

图6 SPI接口读工作时序图

4 软件编程

软件的编程主要分为移位寄存器的移位、数据寄存器的读写、系统时钟的分频、时钟的相位极性确定等几大部分。如下为它们的VHDL语言源代码,由于篇幅原因,结构体内的定义语句没有给出。

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_signed.all;

entity spi_top is

port(     clk, wr_n, rd_n, misoi    : in  std_logic; 

       irq, mosio, scko         : out std_logic;

       addr      : in  std_logic_vector(9 downto 0);

    data       : inout std_logic_vector(7 downto 0);

       rdy           : in std_logic_vector(2 downto 0);

       slv_sel    : out std_logic_vector(2 downto 0)  );

end spi_top;

architecture spi of spi_top is

begin 

data <= shift_reg  when addr=SPIFT_ADDR and rd_n='0' else

            stat_reg   when addr=SPISR_ADDR and rd_n='0' else

            "ZZZZZZZZ";

mosio <= shift_dataout when open_drain ='0' else 'Z';    

sr_proc : process(clk)

  begin

        if(clk'event and clk='1')then

          if(spi_go='1')then  shift_reg<=data_reg;

           elsif(shift_clk='1')then

           shift_reg <= shift_reg(6 downto 0) & shift_datain;

         end if;

     end if;      

    end process; 

  neg_proc : process(clk)

  begin

     if (clk'event and clk='1') then      

        if (shift_clk_negedge='1') then

           shift_negative_edge  <= shift_negative_edge_nxt;

        elsif (spi_go='1') then

           shift_negative_edge  <= shift_reg(7);

        end if;

     end if;

  end process;

  shift_negative_edge_nxt <= shift_reg(7) when phase='1' else misoi ;

  shift_dataout <= shift_negative_edge when phase='1' else shift_reg(7);

  shift_datain <= shift_negative_edge when phase='0' else misoi; 

  tr_proc : process(clk)

  begin

    if (clk'event and clk='1') then

        if (tx_start='1') then tx_run  <= '1';

        elsif (tx_end='1') then tx_run <= '0';

        end if;

     end if;

  end process;

  bc_proc : process (clk)

  begin

    if (clk'event and clk='1') then

        if (tx_start='1') then bit_ctr <= bit_counter;

        elsif (shift_clk='1') then bit_ctr <= bit_ctr-1;

        end if;

    end if;

  end process;

  tx_end <= '1' when  bit_ctr=001 and shift_clk='1' and tx_run='1' else  '0';

  tx_start <= '1' when  spi_go='1' else  '0';

  elr_proc : process (clk)

  begin

    if (clk'event and clk='1') then

       if (tx_end ='1')then irq_flag <='1';

       elsif (tx_run='1')then  irq_flag <='0';

       end if;

    end if;

  end process;

  dvd_proc : process (clk) 

  begin-

    if (clk'event and clk='1') then

      if (not (tx_run='1' ) or tx_end='1') then

        dvd_ctr <= "00000", dvd2 <= '0';

      else

        if (dvd_ctr=00000) then dvd_ctr <= clock_div;

          if(tx_start_r1 ='0')then dvd2 <= not dvd2;

          end if;

        else dvd_ctr <= dvd_ctr-1;

        end if;

      end if;

    end if;

  end process;

  dvd_zero <= '1' when dvd_ctr=00000 else  '0';

  shift_clk <= dvd_zero and dvd2 and tx_run and not tx_start_r1;

  shift_clk_negedge <= dvd_zero and not dvd2 and tx_run;

  scko <= dvd2 xor polck;

  wr_data : process(wr_n,tx_run)

  begin

   if(tx_run='1')then spi_go<='0';

    elsif (wr_n'event and wr_n='1' ) then

        if( addr=spift_addr) then

          data_reg  <=  data, spi_go <='1';

        end if;

    end if;

  end process;

  wr_ctl : process(wr_n)

  begin

   if (wr_n'event and wr_n='1') then

      if addr=spic_addr then ctl_reg <= data;

      end if;

    end if;

  end process;

  slv_sel(2 downto 0)<= ctl_reg(2 downto 0);

  irq_en <= ctl_reg(7),  open_drain <= ctl_reg(6);

  phase <= ctl_reg(5),   polck <= ctl_reg(4);

  irq <= irq_flag and ctl_reg(7);

  stat_proc:process(rdy,irq_flag)

  begin

    stat_reg <= irq_flag & "0000" & rdy(2 downto 0);

     end process;                     

end spi;

5结论

随着SPI通信方式的广泛应用,但对于很多并行总线与之通信成了很大的障碍,本文提出的解决方案具有非常好的可移植性和产品开发能力。本系统既可以作为一个单独的系统运行,又可以作为一个通信模块植入一个大系统中,而其中的SPI接口又是一个可移植SPI接口。利用CPLD的逻辑可编程性,还可以在其剩下的资源中再开发所需要的逻辑器件,既能降低硬件成本又能大大减少系统主板的面积,使电路的设计更具灵活性。该设计已经被应用到转台速率校准装置中,在该设计中共有两个SPI模块,同时还利用了CPLD控制继电器等其它电路,在历次试验中其性能指标及稳定性均达到了要求。

参考文献

[1] Xilinx Limited. CoolRunner-II Serial Peripheral Interface Master. 2002

[2] 北京华夏龙科技有限公司.HXL/486II 技术手册.

[3] Altera. MAX 7000 Programmable Logic Device Family Data Sheet.1995

[4] 赵俊超  集成电路设计VHDL教程. —北京:北京希望电子出版社2002,8


 (全文结束)

信息发布:   转引自: 【 】 【打印】 【关闭
 相 关 文 章
容错系统中的自校验技术及实现方法 (12-01)
基于CPLD的Flash读取控制的设计与实现 (11-22)
用VHDL设计专用串行通信芯片 (12-24)
FLEX 10K系列EAD的应用 (12-14)
以CPLD为核心的定时器 (01-03)
I2C总线通信接口的CPLD实现 (01-03)
VHDL语言在EDA仿真中的应用 (12-07)
异步FIFO的VHDL设计 (01-03)
基于PCI总线的高速数据采集接口的设计与实现 (10-14)
SDH中E1接口数字分接复用器VHDL设计及FPGA实现 (01-04)
基于VHDL语言的智能拨号报警器的设计 (01-04)
VHDL设计中电路简化问题的探讨 (12-06)
通用异步串行接口的VHDL实用化设计 (11-22)
摩托罗拉MC683609与SDRAM接口逻辑设计 (10-20)
FCSR原理及其VHDL语言的实现 (10-18)
基于FPGA模糊控制芯片的设计 (10-22)
CPLD在数字频率测量中的应用 (10-27)
基于FPGA技术的数字相关器的设计与实现 (11-07)
基于PC/104总线的转台速率校准卡的设计 (10-27)
VHDL设计电路优化探讨 (11-28)
基于CPLD 120MHz高速A/D采集卡设计 (11-29)
CPLD在射频卡读写器中的应用 (12-16)
ARM微控制器LPC210X的LCD接口技术 (12-15)
可编程时钟发生器及其应用 (12-21)
基于CPLD器件的单稳态脉冲展电路 (12-21)
基于CPLD的VXI总线接口的研制 (01-03)
由可编程逻辑器件与单片机构成的双控制器 (12-13)
XC9500系列CPLD遥控编程的实现 (12-07)
基于C8051F SPI接口液晶触摸屏的控制设计 (09-19)
基于CPLD技术的PC104总线多功能扩展卡设计 (11-15)
循环冗余校验码的单片机及CPLD实现 (11-29)
CPLD在IGBT驱动设计中的应用 (12-06)
用CPLD实现FIR数字滤波器的设计 (12-06)
基于CPLD的自动门控电源的电路设计 (11-15)
关于我们 ┋ 友情链接


深圳市福田区海滨广场恒福花园恒华阁11F
电话:0755-88305872 传真:0755-88305880
Copyright©2005-2007 无忧电子开发网版权所有

粤ICP备05064233号