NJ8888 发表于 2010-11-21 09:25:39

原创:再发一个简单的串口输出,每次SEND打入一个16位数据,然后启动两次UART过程(当然改成

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

entity SERIAL is
    Port (         clk,exreset,send :in STD_LOGIC;                                                               
                                          datain:in STD_LOGIC_vector(15 downto 0);
                                          sendfinish :buffer STD_LOGIC;
                                          tx : outSTD_LOGIC);
end SERIAL;

architecture Behavioral of SERIAL is
        signal sendprocess,serialclk:STD_LOGIC;
        signal clkcount :integer range 0 to 511;
        signal bitcount:integer range 0 to 31;
        signal shift:STD_LOGIC_vector(15 downto 0);
begin
        serialclkout:process(exreset,clk)
        begin
                if exreset='1' then
                        clkcount<=0;
                        serialclk<='1';
                elsif rising_edge(clk) then
                        --if clkcount=433 then
                        if clkcount=3 then
                                clkcount<=0;
                                serialclk<='1';
                        else
                                clkcount<=clkcount+1;
                                --if clkcount=216 then
                                if clkcount=1 then
                                        serialclk<='0';
                                end if;
                        end if;              
                end if;
        end process serialclkout;

        txout:process(send,serialclk)
        begin
                if exreset='1' then
                        sendfinish<='1';
                        tx<='1';
                        bitcount<=20;
                        sendprocess<='0';
                else       
                        if (send='1') or (sendprocess<='1') then
                                sendprocess<='1';       
                                        if rising_edge(serialclk) then
                                                case bitcount is
                                                        when 0=>
                                                                tx<='0';
                                                                bitcount<=bitcount+1;
                                                        when 10=>
                                                                tx<='0';
                                                                bitcount<=bitcount+1;
                                                        when 9=>
                                                                tx<='1';
                                                                bitcount<=bitcount+1;
                                                        when 19=>
                                                                sendfinish<='1';
                                                                bitcount<=bitcount+1;
                                                                tx<='1';
                                                        when others=>
                                                                tx<=shift(0);
                                                                shift(14 downto 0)<=shift(15 downto 1);
                                                                bitcount<=bitcount+1;
                                                        end case;
                                        end if;
                        end if;       
                        if sendfinish='1' then
                                tx<='1';
                                if (send='1') then
                                        sendfinish<='0';
                                        shift<=datain;
                                        bitcount<=0;
                                end if;       
                        end if;       
                end if;
        end process txout;

end Behavioral;

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_599403S6S2M5.JPG
(原文件名:串口发送控制.JPG)

NJ8888 发表于 2010-11-21 09:28:52

可以看出,比通常的状态机要简单多了,串口接收我以后再发

yuphone 发表于 2010-11-21 10:59:45

mark

AG17 发表于 2010-11-21 11:04:36

mark

NJ8888 发表于 2010-11-21 11:42:31

先写串口接收思路

超过9个字符的高电平进入READY状态
READY状态,收到低电平开始计数,记下当前时间并修正到T2,T3,T4,数据连续低电平达到6us(8.7*70%)认可起始位,进入RECEIVE状态
在RECEIVE状态,每T2+8.67,T3+8.67,T4+8.67分别采样三次,数据相加,大于1则判断数据位为1,否则位为0,每次处理后加1
第9次,结果是1则认可数据,并行打出,并出接收成功标志,否则出停止位错的标志,状态恢复到READY状态以便等待下一次数据

sytu_xww 发表于 2010-11-22 08:37:20

mark

NJ8888 发表于 2010-11-22 21:36:40

改了下

txout:process(send,serialtxclk,exreset)
        begin
                if exreset='1' then
                        sendfinish<='1';
                        tx<='1';
                        txbitcount<=0;
                        sendprocess<='0';
                else       
                        if (send='1') or (sendprocess='1') then
                                if sendprocess='0' then
                                        sendfinish<='0';
                                        txshift<=datain;
                                        tx<='0';
                                        sendprocess<='1';
                                end if;       
                                        if rising_edge(serialtxclk) then
                                                case txbitcount is
                                                        when 0=>
                                                                tx<='0';
                                                                txbitcount<=txbitcount+1;
                                                        when 10=>
                                                                tx<='0';
                                                                txbitcount<=txbitcount+1;
                                                        when 9=>
                                                                tx<='1';
                                                                txbitcount<=txbitcount+1;
                                                        when 19=>
                                                                sendfinish<='1';
                                                                sendprocess<='0';
                                                                txbitcount<=0;
                                                                tx<='1';
                                                        when others=>
                                                                tx<=txshift(0);
                                                                txshift(14 downto 0)<=txshift(15 downto 1);
                                                                txbitcount<=txbitcount+1;
                                                end case;
                                        end if;       
                                end if;
                        end if;
        end process txout;

NJ8888 发表于 2010-11-26 14:39:49

原创经过实际硬件运行过的FPGA 串口基本功能,输入50MHz时钟,波特115200,演示功能会吧串口RX收到的数据从TX输出两次,对其他时钟和波特要换参数



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

entity SERIAL is
    Port (         clk,exreset,rx :in STD_LOGIC;                                                               
                                          datain:in STD_LOGIC_vector(15 downto 0);
                                          sendfinish,rxtest1:buffer STD_LOGIC;
                                          rxbuf:buffer std_logic_vector(7 downto 0);
                                          tx,receivesuccess,stopbiterr,clkrxouttest,rxtest: outSTD_LOGIC);
end SERIAL;

architecture Behavioral of SERIAL is

        TYPE sreg IS (ready,startbitpending,startbitsure,receive);

        signal sendprocess,serialtxclk,serialrxclk,success:STD_LOGIC;
        signal clktxcount,overcount :integer range 0 to 511;
        signal txbitcount,pendingcount:integer range 0 to 31;
        signal shiftcount:integer range 0 to 15;
        signal txshift:STD_LOGIC_vector(15 downto 0);
        signal rxbitcount,clkrxcount,t2,t3,t4,t5:integer range 0 to 127;
        signal bittemp:integer range 0 to 3;
        signal rxshift:std_logic_vector(7 downto 0);
        signal currentstate,nextstate:sreg;
begin
        serialtxclkout:process(exreset,clk)
        begin
                if exreset='0' then
                        clktxcount<=0;
                        serialtxclk<='1';
                elsif rising_edge(clk) then
                        if clktxcount=433 then
                        --if clktxcount=3 then
                                clktxcount<=0;
                                serialtxclk<='1';
                        else
                                clktxcount<=clktxcount+1;
                                if clktxcount=216 then
                                --if clktxcount=1 then
                                        serialtxclk<='0';
                                end if;
                        end if;              
                end if;
        end process serialtxclkout;

        serialrxclkout:process(exreset,clk)
        begin
                if exreset='0' then
                        clkrxcount<=0;
                        clkrxouttest<='1';
                        serialrxclk<='1';
                elsif rising_edge(clk) then
                        if clkrxcount=61 then
                                clkrxcount<=0;
                                clkrxouttest<='1';
                                serialrxclk<='1';
                        else
                                clkrxcount<=clkrxcount+1;
                                if clkrxcount=30 then
                                        serialrxclk<='0';
                                        clkrxouttest<='0';
                                end if;
                        end if;              
                end if;
        end process serialrxclkout;
       
        rxin:process(exreset,serialrxclk)
        begin
                if exreset='0' then
                        overcount<=0;
                        currentstate<=ready;
                        nextstate<=ready;
                        pendingcount<=0;
                        rxbitcount<=0;
                        success<='0';
                elsif rising_edge(serialrxclk) then
                        if sendfinish='0' then
                                success<='0';
                        end if;       
                        if overcount>70 then
                                currentstate<=ready;
                                nextstate<=ready;
                                pendingcount<=0;
                                rxbitcount<=0;
                                nextstate<=ready;
                        end if;
                        --rxtest1<=not rxtest1;
                        overcount<=overcount+1;
                        rxtest<=rx;
                        case currentstate is
                                when ready=>
                                        if rx='0' then
                                                rxbitcount<=0;
                                                nextstate<=startbitpending;
                                                pendingcount<=0;
                                                overcount<=0;
                                                rxtest1<='0';
                                                t2<=8;
                                                t3<=9;
                                                t4<=10;
                                                t5<=11;
                                        end if;
                       
                               when startbitpending=>
                                        rxbitcount<=rxbitcount+1;
                                        if rx='0' then
                                                pendingcount<=pendingcount+1;
                                                if pendingcount>3 then
                                                        nextstate<=startbitsure;
                                                        bittemp<=0;
                                                        shiftcount<=0;
                                                        receivesuccess<='0';
                                                        stopbiterr<='0';
                                                else
                                                        rxtest1<='1';
                                                end if;
                                               
                                        else
                                                pendingcount<=0;
                                                nextstate<=ready;
                                        end if;               
                                when startbitsure=>
                                        rxbitcount<=rxbitcount+1;
                                        nextstate<=receive;
                                        rxtest1<='0';
                                       
                                when receive=>
                                        --rxtest1<=not rxtest1;
                                        rxbitcount<=rxbitcount+1;
                                        if rxbitcount=t2 then
                                                rxtest1<=not rxtest1;
                                                if rx='1' then
                                                        bittemp<=bittemp+1;
                                                end if;
                                                t2<=t2+7;                                      
                                        end if;
                                        if rxbitcount=t3 then
                                                rxtest1<=not rxtest1;
                                                if rx='1' then
                                                        bittemp<=bittemp+1;
                                                end if;
                                                t3<=t3+7;                                      
                                        end if;
                                        if rxbitcount=t4 then
                                                rxtest1<=not rxtest1;
                                                if rx='1' then
                                                        bittemp<=bittemp+1;
                                                end if;
                                                t4<=t4+7;                                      
                                        end if;
                                        if rxbitcount=t5 then
                                                rxtest1<=not rxtest1;
                                                rxshift(6 downto 0)<=rxshift(7 downto 1);
                                                if bittemp>1 then
                                                        rxshift(7)<='1';
                                                else
                                                        rxshift(7)<='0';
                                                end if;
                                                bittemp<=0;
                                                if shiftcount=8 then                                                                        --对
                                                        if bittemp>1 then
                                                                receivesuccess<='1';
                                                                success<='1';
                                                                rxbuf<=rxshift(7 downto 0);
                                                        else
                                                                stopbiterr<='1';
                                                        end if;               
                                                        nextstate<=ready;       
                                                else       
                                                        nextstate<=receive;
                                                        shiftcount<=shiftcount+1;
                                                        t5<=t5+7;                                      
                                                end if;       
                                        end if;
                               
                                when others=>       
                                        nextstate<=ready;
                        end case;
                end if;
       
        currentstate<=nextstate;
       
        end process rxin;
       
        txout:process(success,serialtxclk,exreset)
        begin
                if exreset='0' then
                        sendfinish<='1';
                        tx<='1';
                        txbitcount<=0;
                        sendprocess<='0';
                else       
                        --if (send='0') or (sendprocess='1') then
                        --if (rx='0') or (sendprocess='1') then
                        if (success='1') or (sendprocess='1') then
                                if rising_edge(serialtxclk) then
                                                case txbitcount is
                                                        when 0=>
                                                                --txshift<=datain;
                                                                txshift<=rxbuf & rxbuf;
                                                                tx<='0';
                                                                sendfinish<='0';
                                                                sendprocess<='1';
                                                                txbitcount<=txbitcount+1;
                                                        when 10=>
                                                                tx<='0';
                                                                txbitcount<=txbitcount+1;
                                                        when 9=>
                                                                tx<='1';
                                                                txbitcount<=txbitcount+1;
                                                        when 19=>
                                                                sendfinish<='1';
                                                                sendprocess<='0';
                                                                txbitcount<=0;
                                                                tx<='1';
                                                        when others=>
                                                                tx<=txshift(0);
                                                                txshift(14 downto 0)<=txshift(15 downto 1);
                                                                txbitcount<=txbitcount+1;
                                                end case;
                                        end if;       
                                end if;
                        end if;
        end process txout;

end Behavioral;

lsw0136 发表于 2010-11-27 13:54:07

有注释就爽了mark

40130064 发表于 2010-11-27 15:02:42

好东西!

guke 发表于 2010-11-28 15:19:57

学习了

zoto 发表于 2010-11-28 17:59:45

caicaidabing 发表于 2011-6-20 21:23:51

MARK学习一下

xmjulytiger 发表于 2011-6-21 14:55:32

学习了
页: [1]
查看完整版本: 原创:再发一个简单的串口输出,每次SEND打入一个16位数据,然后启动两次UART过程(当然改成