1. gzyueqian
      18529173453
      首頁 > 新聞中心 > > 正文

      基于PC/104總線與CPLD的SPI接口設計

      更新時間: 2007-05-09 11:43:16來源: 粵嵌教育瀏覽量:978


        摘 要:本文根據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所示。

       
      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 



       
       

      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 曰本久久免费精品 | 亚洲精品成AV人在线观看 | 中文字幕在线永久91 | 亚洲欧美日韩高清一区二区 | 五月天Av在线进入不卡 | 日本特黄特黄刺激免费大片 |