音影先锋亚洲天堂网|电影世界尽头的爱完整版播放|国产 熟女 91|高清无码免费观看欧美日韩|韩国一区二区三区黄色录像|美女亚洲加勒比在线|亚洲综合网 开心五月|7x成人在线入口|成人网站免费日韩毛片区|国产黄片?一级?二级?三级

VHDL設計的串口通信程序

出處:t14495716 發(fā)布于:2010-06-21 10:38:36

  本模塊的功能是驗證實現(xiàn)和PC機進行基本的串口通信的功能。需要在PC機上安裝一個串口調(diào)試工具來驗證程序的功能。程序?qū)崿F(xiàn)了一個收發(fā)一幀10個bit(即無奇偶校驗位)的串口控制器,10個bit是1位起始位,8個數(shù)據(jù)位,1個結(jié)束位。串口的波特律由程序中定義的p_par參數(shù)決定,更改該參數(shù)可以實現(xiàn)相應的波特率。程序當前設定的p_par 的值是0x104,對應的波特率是9600。用一個8倍波特率的時鐘將發(fā)送或接受每一位bit的周期時間劃分為8個時隙以使通信同步。

  程序的工作過程是:串口處于全雙工工作狀態(tài),按動key2,CPLD向PC發(fā)送皐elcome"字符串(串口調(diào)試工具設成按ASCII碼接受方式);PC可隨時向CPLD發(fā)送0-F的十六進制數(shù)據(jù),CPLD接受后顯示在7段數(shù)碼管上。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY UART IS
   PORT (
      clk                     : IN std_logic;  
      rst                     : IN std_logic;  
      rxd                     : IN std_logic;   串行數(shù)據(jù)接收端
      txd                     : OUT std_logic; 串行數(shù)據(jù)發(fā)送端 
      en                      : OUT std_logic_vector(7 downto 0); 數(shù)碼管使能
      seg_data                : OUT std_logic_vector(7 DOWNTO 0); 數(shù)碼管數(shù)據(jù) 
      key_input               : IN std_logic  按鍵輸入
      );
END UART;

ARCHITECTURE arch OF UART IS
   //////////////////inner reg////////////////////
   SIGNAL p_reg                  :  std_logic_vector(15 DOWNTO 0);分頻計數(shù)器,分頻值由波特率決定。分頻后得到頻率8倍波特率的時鐘  
   SIGNAL p8_tras_reg            :  std_logic_vector(2 DOWNTO 0);該寄存器的計數(shù)值對應發(fā)送時當前位于的時隙數(shù)  
   SIGNAL p8_rec_reg             :  std_logic_vector(2 DOWNTO 0);  寄存器的計數(shù)值對應接收時當前位于的時隙數(shù)
   SIGNAL state_tras               :  std_logic_vector(3 DOWNTO 0);  發(fā)送狀態(tài)寄存器
   SIGNAL state_rec                :  std_logic_vector(3 DOWNTO 0); 接受狀態(tài)寄存器
   SIGNAL clkbaud_tras             :  std_logic; 以波特率為頻率的發(fā)送使能信號 
   SIGNAL clkbaud_rec              :  std_logic; 以波特率為頻率的接受使能信號 
   SIGNAL clkbaud8x                :  std_logic; 以8倍波特率為頻率的時鐘,它的作用是將發(fā)送或接受一個bit的時鐘周期分為8個時隙 
   SIGNAL recstart                 :  std_logic; 開始發(fā)送標志
   SIGNAL recstart_tmp             :  std_logic; 開始接受標志 
   SIGNAL trasstart                :  std_logic;  
   SIGNAL rxd_reg1                 :  std_logic; 接收寄存器1 
   SIGNAL rxd_reg2                 :  std_logic; 接收寄存器2,因為接收數(shù)據(jù)為異步信號,故用兩級緩存 
   SIGNAL txd_reg                  :  std_logic; 發(fā)送寄存器 
   SIGNAL rxd_buf                  :  std_logic_vector(7 DOWNTO 0);接受數(shù)據(jù)緩存  
   SIGNAL txd_buf                  :  std_logic_vector(7 DOWNTO 0);發(fā)送數(shù)據(jù)緩存  
   SIGNAL send_state               :  std_logic_vector(2 DOWNTO 0);每次按鍵給PC發(fā)送"Welcome"字符串,這是發(fā)送狀態(tài)寄存器  
   SIGNAL cnt_delay                :  std_logic_vector(19 DOWNTO 0);延時去抖計數(shù)器  
   SIGNAL start_delaycnt           :  std_logic;  開始延時計數(shù)標志
   SIGNAL key_entry1               :  std_logic;  確定有鍵按下曛?
   SIGNAL key_entry2               :  std_logic;  確定有鍵按下標志
   //////////////////////////////////////////////
   C*TANT  p_par               :  std_logic_vector(15 DOWNTO 0) := "0000000100000100";
   分頻參數(shù),其值由對應的波特率計算而得,按此參數(shù)分頻的時鐘頻率是波倍特率的8倍,此處值對應9600的波特率,即分頻出的時鐘頻率是9600*8    
   SIGNAL txd_xhdl3                :  std_logic;  

BEGIN
   en <="01010101" ;7段數(shù)碼管使能信號賦值
   txd <= txd_xhdl3;  
   txd_xhdl3 <= txd_reg ;

   PROCESS(clk,rst)
   BEGIN
      
      IF (NOT rst = ’1’) THEN
         cnt_delay <= "00000000000000000000";   
         start_delaycnt <= ’0’;   
      ELSIF(clk’EVENT AND clk=’1’)THEN
         IF (start_delaycnt = ’1’) THEN
            IF (cnt_delay /= "11000011010100000000") THEN
               cnt_delay <= cnt_delay + "00000000000000000001";   
            ELSE
               cnt_delay <= "00000000000000000000";   
               start_delaycnt <= ’0’;   
            END IF;
         ELSE
            IF ((NOT key_input=’1’) AND (cnt_delay = "00000000000000000000")) THEN
               start_delaycnt <= ’1’;   
            END IF;
         END IF;
      END IF;
   END PROCESS;

   PROCESS(clk,rst)
   BEGIN
      
      IF (NOT rst = ’1’) THEN
         key_entry1 <= ’0’;   
      ELSIF(clk’EVENT AND clk=’1’)THEN
         IF (key_entry2 = ’1’) THEN
            key_entry1 <= ’0’;   
         ELSE
            IF (cnt_delay = "11000011010100000000") THEN
               IF (NOT key_input = ’1’) THEN
                  key_entry1 <= ’1’;   
               END IF;
            END IF;
         END IF;
      END IF;
   END PROCESS;

   PROCESS(clk,rst)
   BEGIN
      
      IF (NOT rst = ’1’) THEN
         p_reg <= "0000000000000000";   
      ELSIF(clk’EVENT AND clk=’1’)THEN
         IF (p_reg = p_par - "0000000000000001") THEN
            p_reg <= "0000000000000000";   
         ELSE
            p_reg <= p_reg + "0000000000000001";   
         END IF;
      END IF;
   END PROCESS;

   PROCESS(clk,rst)  分頻得到8倍波特率的時鐘
   BEGIN
      
      IF (NOT rst = ’1’) THEN
         clkbaud8x <= ’0’;   
      ELSIF(clk’EVENT AND clk=’1’)THEN
         IF (p_reg = p_par - "0000000000000001") THEN
            clkbaud8x <= NOT clkbaud8x;   
         END IF;
      END IF;
   END PROCESS;

   PROCESS(clkbaud8x,rst)
   BEGIN
      IF (NOT rst = ’1’) THEN
         p8_rec_reg <= "000";   
      ELSE IF(clkbaud8x’EVENT AND clkbaud8x = ’1’) THEN
         IF (recstart = ’1’) THEN  接收開始標志
            p8_rec_reg <= p8_rec_reg + "001";接收開始后,時隙數(shù)在8倍波特率的時鐘下加1循環(huán)   
         END IF;
    END IF;
      END IF;
   END PROCESS;

   PROCESS(clkbaud8x,rst)
   BEGIN
      IF (NOT rst = ’1’) THEN
         p8_tras_reg <= "000";   
      ELSE IF(clkbaud8x’EVENT AND clkbaud8x = ’1’) THEN
         IF (trasstart = ’1’) THEN
            p8_tras_reg <= p8_tras_reg + "001";發(fā)送開始后,時隙數(shù)在8倍波特率的時鐘下加1循環(huán)   
         END IF;
    END IF;
      END IF;
   END PROCESS;

   PROCESS(p8_rec_reg)
   BEGIN
      IF (p8_rec_reg = "111") THEN
         clkbaud_rec <= ’1’; -在第7個時隙,接收  
      ELSE
         clkbaud_rec <= ’0’;   
      END IF;
   END PROCESS;

   PROCESS(p8_tras_reg)
   BEGIN
      IF (p8_tras_reg = "111") THEN
         clkbaud_tras <= ’1’;  在第7個時隙,發(fā)送使能信號有效,將數(shù)據(jù)發(fā)出 
      ELSE
         clkbaud_tras <= ’0’;   
      END IF;
   END PROCESS;

   PROCESS(clkbaud8x,rst)
   BEGIN
      IF (NOT rst = ’1’) THEN
         txd_reg <= ’1’;   
         trasstart <= ’0’;   
         txd_buf <= "00000000";   
         state_tras <= "0000";   
         send_state <= "000";   
         key_entry2 <= ’0’;   
      ELSE IF(clkbaud8x’EVENT AND clkbaud8x = ’1’) THEN
         IF (NOT key_entry2 = ’1’) THEN
            IF (key_entry1 = ’1’) THEN
               key_entry2 <= ’1’;   
               txd_buf <= "01110111";   "w"
            END IF;
         ELSE
            CASE state_tras IS
               WHEN "0000" =>  發(fā)送起始位
                        IF ((NOT trasstart=’1’) AND (send_state < "111") ) THEN
                           trasstart <= ’1’;   
ELSE
                           IF (send_state < "111") THEN
                              IF (clkbaud_tras = ’1’) THEN
                                 txd_reg <= ’0’;   
                                 state_tras <= state_tras + "0001";   
                              END IF;
                           ELSE
                              key_entry2 <= ’0’;   
                              state_tras <= "0000";   
                           END IF;
                        END IF;
               WHEN "0001" => 發(fā)送第1位
                        IF (clkbaud_tras = ’1’) THEN
                           txd_reg <= txd_buf(0);   
                           txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);   
                           state_tras <= state_tras + "0001";   
                        END IF;
               WHEN "0010" =>  發(fā)送第2位
                        IF (clkbaud_tras = ’1’) THEN
                           txd_reg <= txd_buf(0);   
                           txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);   
                           state_tras <= state_tras + "0001";   
                        END IF;
               WHEN "0011" =>  發(fā)送第3位
                        IF (clkbaud_tras = ’1’) THEN
                           txd_reg <= txd_buf(0);   
                           txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);   
                           state_tras <= state_tras + "0001";   
                        END IF;
               WHEN "0100" => 發(fā)送第4位
                        IF (clkbaud_tras = ’1’) THEN
                           txd_reg <= txd_buf(0);   
                           txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);   
                           state_tras <= state_tras + "0001";   
                        END IF;
               WHEN "0101" => 發(fā)送第5位
                        IF (clkbaud_tras = ’1’) THEN
                           txd_reg <= txd_buf(0);   
                           txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);   
                           state_tras <= state_tras + "0001";   
                        END IF;
               WHEN "0110" => 發(fā)送第6位
                        IF (clkbaud_tras = ’1’) THEN
                           txd_reg <= txd_buf(0);   
                           txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);   
                           state_tras <= state_tras + "0001";   
                        END IF;
               WHEN "0111" => 發(fā)送第7位
                        IF (clkbaud_tras = ’1’) THEN
                           txd_reg <= txd_buf(0);   
                           txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);   
                           state_tras <= state_tras + "0001";   
                        END IF;
               WHEN "1000" =>  發(fā)送第8位
                        IF (clkbaud_tras = ’1’) THEN
                           txd_reg <= txd_buf(0);   
                           txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);   
                           state_tras <= state_tras + "0001";   
                        END IF;
               WHEN "1001" =>  發(fā)送停止位
                        IF (clkbaud_tras = ’1’) THEN
                           txd_reg <= ’1’;   
                           txd_buf <= "01010101";   
                           state_tras <= state_tras + "0001";   
                        END IF;
               WHEN "1111" =>
                        IF (clkbaud_tras = ’1’) THEN
                           state_tras <= state_tras + "0001";   
                           send_state <= send_state + "001";   
                           trasstart <= ’0’;   
                           CASE send_state IS
                              WHEN "000" =>
                                       txd_buf <= "01100101"; "e"  
                              WHEN "001" =>
                                       txd_buf <= "01101100"; "l"  
                              WHEN "010" =>
                                       txd_buf <= "01100011";  "c" 
                              WHEN "011" =>
                                       txd_buf <= "01101111"; "o" 
                              WHEN "100" =>
                                       txd_buf <= "01101101";  "m" 
                              WHEN "101" =>
                                       txd_buf <= "01100101"; "e"  
                              WHEN OTHERS  =>
                                       txd_buf <= "00000000"; 
                             
                           END CASE;
                        END IF;
               WHEN OTHERS  =>
                        IF (clkbaud_tras = ’1’) THEN
                           state_tras <= state_tras + "0001";   
                           trasstart <= ’1’;   
                        END IF;
              
            END CASE;
         END IF;
      END IF;
 END IF;
   END PROCESS;

   PROCESS(clkbaud8x,rst)  接受PC機的數(shù)據(jù)
   BEGIN
      IF (NOT rst = ’1’) THEN
         rxd_reg1 <= ’0’;   
         rxd_reg2 <= ’0’;   
         rxd_buf <= "00000000";   
         state_rec <= "0000";   
         recstart <= ’0’;   
         recstart_tmp <= ’0’;   
      ELSE IF(clkbaud8x’EVENT AND clkbaud8x = ’1’) THEN
         rxd_reg1 <= rxd;   
         rxd_reg2 <= rxd_reg1;   
         IF (state_rec = "0000") THEN
            IF (recstart_tmp = ’1’) THEN
               recstart <= ’1’;   
               recstart_tmp <= ’0’;   
               state_rec <= state_rec + "0001";   
            ELSE
               IF ((NOT rxd_reg1 AND rxd_reg2) = ’1’) THEN 檢測到起始位的下降沿,進入接受狀態(tài)
                  recstart_tmp <= ’1’;   
               END IF;
            END IF;
         ELSE
            IF (state_rec >= "0001" AND state_rec<="1000") THEN
               IF (clkbaud_rec = ’1’) THEN
                  rxd_buf(7) <= rxd_reg2;   
                  rxd_buf(6 DOWNTO 0) <= rxd_buf(7 DOWNTO 1);   
                  state_rec <= state_rec + "0001";   
               END IF;
            ELSE
               IF (state_rec = "1001") THEN
                  IF (clkbaud_rec = ’1’) THEN
                     state_rec <= "0000";   
                     recstart <= ’0’;   
                  END IF;
               END IF;
            END IF;
         END IF;
      END IF;
 END IF;
   END PROCESS;

   PROCESS(rxd_buf)   將接受的數(shù)據(jù)用數(shù)碼管顯示出來
   BEGIN
      CASE rxd_buf IS
         WHEN "00110000" =>
                  seg_data <= "00000011"; 0  
         WHEN "00110001" =>
                  seg_data <= "10011111"; 1 
         WHEN "00110010" =>
                  seg_data <= "00100101"; 2 
         WHEN "00110011" =>
                  seg_data <= "00001101"; 3      
         WHEN "00110100" =>
                  seg_data <= "10011001"; 4  
&nbs p;        WHEN "00110101" =>
                  seg_data <= "01001001"; 5 
         WHEN "00110110" =>
                  seg_data <= "01000001"; 6  
         WHEN "00110111" =>
                  seg_data <= "00011111"; 7  
         WHEN "00111000" =>
                  seg_data <= "00000001"; 8   
         WHEN "00111001" =>
                  seg_data <= "00001001"; 9  
         WHEN "01000001" =>
                  seg_data <= "00010001"; A  
         WHEN "01000010" =>
                  seg_data <= "11000001"; B  
         WHEN "01000011" =>
                  seg_data <= "01100011"; C  
         WHEN "01000100" =>
                  seg_data <= "10000101"; D 
         WHEN "01000101" =>
                  seg_data <= "01100001"; E  
         WHEN "01000110" =>
                  seg_data <= "01110001"; F   
         WHEN OTHERS  =>
                  seg_data <= "11111111";          
      END CASE;
   END PROCESS;
END arch;



  
關鍵詞:VHDL設計的串口通信程序VHDL串口通信程序CPLD

版權(quán)與免責聲明

凡本網(wǎng)注明“出處:維庫電子市場網(wǎng)”的所有作品,版權(quán)均屬于維庫電子市場網(wǎng),轉(zhuǎn)載請必須注明維庫電子市場網(wǎng),http://m.58mhw.cn,違反者本網(wǎng)將追究相關法律責任。

本網(wǎng)轉(zhuǎn)載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點或證實其內(nèi)容的真實性,不承擔此類作品侵權(quán)行為的直接責任及連帶責任。其他媒體、網(wǎng)站或個人從本網(wǎng)轉(zhuǎn)載時,必須保留本網(wǎng)注明的作品出處,并自負版權(quán)等法律責任。

如涉及作品內(nèi)容、版權(quán)等問題,請在作品發(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關權(quán)利。

FT232RL—性價比還不錯的USB轉(zhuǎn)串口通用芯片!
廣告
OEM清單文件: OEM清單文件
*公司名:
*聯(lián)系人:
*手機號碼:
QQ:
有效期:

掃碼下載APP,
一鍵連接廣大的電子世界。

在線人工客服

買家服務:
賣家服務:
技術客服:

0571-85317607

網(wǎng)站技術支持

13606545031

客服在線時間周一至周五
9:00-17:30

關注官方微信號,
第一時間獲取資訊。

建議反饋

聯(lián)系人:

聯(lián)系方式:

按住滑塊,拖拽到最右邊
>>
感謝您向阿庫提出的寶貴意見,您的參與是維庫提升服務的動力!意見一經(jīng)采納,將有感恩紅包奉上哦!