• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統 > 設計應用 > VHDL設計的串口通信程序

    VHDL設計的串口通信程序

    作者: 時間:2017-06-06 來源:網絡 收藏

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

    本文引用地址:http://www.czjhyjcfj.com/article/201706/349336.htm

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

    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; 串行數據接收端
    txd : OUT std_logic; 串行數據發(fā)送端
    en : OUT std_logic_vector(7 downto 0); 數碼管使能
    seg_data : OUT std_logic_vector(7 DOWNTO 0); 數碼管數據
    key_input : IN std_logic 按鍵輸入
    );
    END UART;

    ARCHITECTURE arch OF UART IS
    //////////////////inner reg////////////////////
    SIGNAL div_reg : std_logic_vector(15 DOWNTO 0);分頻計數器,分頻值由波特率決定。分頻后得到頻率8倍波特率的時鐘
    SIGNAL div8_tras_reg : std_logic_vector(2 DOWNTO 0);該寄存器的計數值對應發(fā)送時當前位于的時隙數
    SIGNAL div8_rec_reg : std_logic_vector(2 DOWNTO 0); 寄存器的計數值對應接收時當前位于的時隙數
    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,因為接收數據為異步信號,故用兩級緩存
    SIGNAL txd_reg : std_logic; 發(fā)送寄存器
    SIGNAL rxd_buf : std_logic_vector(7 DOWNTO 0);接受數據緩存
    SIGNAL txd_buf : std_logic_vector(7 DOWNTO 0);發(fā)送數據緩存
    SIGNAL send_state : std_logic_vector(2 DOWNTO 0);每次按鍵給PC發(fā)送Welcome字符串,這是發(fā)送狀態(tài)寄存器
    SIGNAL cnt_delay : std_logic_vector(19 DOWNTO 0);延時去抖計數器
    SIGNAL start_delaycnt : std_logic; 開始延時計數標志
    SIGNAL key_entry1 : std_logic; 確定有鍵按下曛?
    SIGNAL key_entry2 : std_logic; 確定有鍵按下標志
    //////////////////////////////////////////////
    C*TANT div_par : std_logic_vector(15 DOWNTO 0) := 0000000100000100;
    分頻參數,其值由對應的波特率計算而得,按此參數分頻的時鐘頻率是波倍特率的8倍,此處值對應9600的波特率,即分頻出的時鐘頻率是9600*8
    SIGNAL txd_xhdl3 : std_logic;

    BEGIN
    en =01010101 ;7段數碼管使能信號賦值
    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
    div_reg = 0000000000000000;
    ELSIF(clk’EVENT AND clk=’1’)THEN
    IF (div_reg = div_par - 0000000000000001) THEN
    div_reg = 0000000000000000;
    ELSE
    div_reg = div_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 (div_reg = div_par - 0000000000000001) THEN
    clkbaud8x = NOT clkbaud8x;
    END IF;
    END IF;
    END PROCESS;

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

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

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

    PROCESS(div8_tras_reg)
    BEGIN
    IF (div8_tras_reg = 111) THEN
    clkbaud_tras = ’1’; 在第7個時隙,發(fā)送使能信號有效,將數據發(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) 接受的數據
    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) 將接受的數據用數碼管顯示出來
    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 串口通信 PC機

    評論


    相關推薦

    技術專區(qū)

    關閉
    主站蜘蛛池模板: 佛冈县| 湛江市| 新建县| 昆山市| 砚山县| 山阳县| 松溪县| 开鲁县| 喜德县| 子长县| 远安县| 湘乡市| 枣强县| 建始县| 冷水江市| 尼玛县| 兴宁市| 宁安市| 丹棱县| 门头沟区| 安顺市| 吐鲁番市| 玉溪市| 罗定市| 涞源县| 明水县| 连州市| 白水县| 永善县| 双峰县| 舟山市| 藁城市| 邵东县| 离岛区| 聂拉木县| 洪泽县| 乌拉特后旗| 利川市| 丹棱县| 荥阳市| 乐昌市|