基于FPGA的UART串口通信实验(VHDL语言实现)
一、前言:
最近在做UART串口通信的相关实验时,在网上查了很多资料,发现网上的大部分文章只注重理论,不注重代码,很多代码有错误不说,而且难以理解。故在完成此实验后,起了写一篇博客的心思,以供有想做相关实验且基础比较薄弱的朋友参阅。
二、实验要求:
(1)实现和 PC 双向通信
(2)可通过 FPGA 的键盘扫描,在开发板上设置控制参数,输入发送内容
(3)通信波特率可调
(4)LCD 液晶屏实现菜单、接收到的数据显示
注:关于UART串口通信实验的相关理论网上很多,而且都很详细,我在这里都不赘余了,我的重点是代码及其分析。本次使用到的FPGA开发板为: Cyclone Ⅱ EP2C5Q208C8 核心的MAGIC3200_EP2C5 开发板。
三、引脚分配:
四、代码及其分析:
注:此处代码有两个文件,一个是主文件,另外一个是按键消抖文件。
先上按键消抖文件,此处代码比较好理解。
------------------------------------------------按键消抖文件---------------------------------------------------------library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;entity key5 is --按键防抖动port(CLK,RESET: in std_logic; --时钟以及有效位din: in std_logic; --是按键,可能与防抖动有关!dout: out std_logic --'0'有效 );
end key5;architecture Behavioral of key5 issignal count : integer range 0 to 3000000 ; --分频器signal keyclk : std_logic ; --分频器type state is(s0,s1); --定义两种状态signal pre_s,next_s:state; --状态机指针beginprocess(CLK,RESET) --时钟进程,产生各种时钟信号beginif RESET='0' then keyclk<='0';count<=0; elsif CLK'event and CLK='1' then count<=count+1;if count=3000000 then keyclk<=not keyclk; count<=0;else count<=count+1;end if;end if; --毫秒时钟end process;process(keyclk,RESET) --状态机激励源beginif RESET='0' then pre_s<=s0; elsif keyclk'event and keyclk='1' then pre_s<=next_s; else null;end if; end process;process(pre_s,next_s,din) --begincase pre_s iswhen s0=>dout<='1';if din='0' then next_s<=s1; --检测到按键else next_s<=s0;end if;when s1=>dout<='1';if din='0' then dout<='0'; --检测到按键else next_s<=s0;end if;when others => next_s<=s0;end case;end process;
end Behavioral;------------------------------------------------按键消抖文件---------------------------------------------------------
下面是主程序文件,我们重点来分析这一块。
------------------------------------------------主程序文件-----------------------------------------------------------library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;entity RS232 is
port(RESET : in std_logic; --复位信号CLK : in std_logic; --时钟输入,50MHZKeyIn : in std_logic_vector(3 downto 0); --column列电平KeyOut : out std_logic_vector(3 downto 0); --row行电平KEYA : in std_logic; UART0_RX : in std_logic;UART0_TX : out std_logic;LCD_RESET : out std_logic ; LCD_RW : out std_logic ;LCD_RS : out std_logic ;LCD_E : out std_logic ;LCD_D : buffer std_logic_vector ( 7 downto 0) );end RS232;architecture Behavioral of RS232 is --此处代码均和LCD显示屏字符设置有关type states is ( set ,clr ,set_d ,open1,set_addr,set_ddrom1,set_ddrom2,set_ddrom3,set_ddrom4,set_ddrom5,set_1,set_ddrom6,set_ddrom7,set_ddrom8,set_ddrom9,set_ddrom10,set_ddrom11,set_ddrom12,set_ddrom13,s1,s2,set_addrh4,set_ddrom1h4,set_ddrom2h4,set_ddrom3h4,set_ddrom4h4,set_ddrom5h4,set_1h4,set_ddrom6h4,set_ddrom7h4,set_ddrom8h4);signal current_state : states :=set ; Signal timecnt : integer range 0 to 100000; --分频计数器,用来得到10ms时钟Signal time10ms : std_logic ; --10ms时钟Signal scanvalue : std_logic_vector(3 downto 0);--记录扫描数据Signal combvalue : std_logic_vector(7 downto 0);--KeyIn、KeyOut组合值Signal cpy_scanvalue : std_logic_vector(3 downto 0);--备份扫描数据 Signal JX : std_logic_vector(2 downto 0);Signal Data00 : std_logic_vector(9 downto 0); Signal Clock9600 : std_logic; --9600波特率时钟,发送Signal Clock3 : std_logic; --9600三倍频采样时钟,用于接收采用Signal Send_data : std_logic_vector(9 downto 0); --发送寄存器Signal Send_en : std_logic; --串口发送使能,0有效Signal Send_over : std_logic; --串口发送完成,0有效Signal Rx_Hold : std_logic; --串口接收到起始位标志Signal Rx_Valid : std_logic; --标志接收到一字节有效数据Signal Rx_Data : std_logic_vector(7 downto 0); --接收寄存器Signal Data1 : std_logic_vector(3 downto 0);Signal Data2 : std_logic_vector(3 downto 0);Signal count : integer range 0 to 100000 ; --分频器,产生毫秒时钟基准Signal dout : std_logic; --A键Signal clkcnt : std_logic_vector(13 downto 0);Signal LCD_Clk : std_logic;component key5 --按键防抖动port(CLK,RESET:in std_logic;din:in std_logic;dout:out std_logic --'0'有效 );end component;------------------------------------------------波特率设置部分-------------------------------------------------------- beginLCD_RESET <='1';LCD_RW <= '0' ;process(CLK,RESET,Rx_Hold) --时钟产生进程variable ClockCount : integer range 0 to 5208 :=0;variable ClockCount_Rx : integer range 0 to 314 :=0;variable ClockCount1 : integer range 0 to 5208 :=0;variable ClockCount_Rx1 : integer range 0 to 314 :=0;begin if RESET='0' then time10ms<='0'; elsif (rising_edge(CLK)) then ClockCount:=ClockCount+1;ClockCount_Rx:=ClockCount_Rx+1;timecnt<=timecnt+1;--产生9600时钟,1/50MHZ*5208=1/9600case JX is --波特率选择when "100" => ClockCount1:=5208;ClockCount_Rx1:=314;when "010" => ClockCount1:=2604;ClockCount_Rx1:=157;when "001" => ClockCount1:=1302;ClockCount_Rx1:=78;when others => null;end case;if ClockCount=ClockCount1 then Clock9600<='1'; ClockCount:=0;else Clock9600<='0';end if;if timecnt=100000 then time10ms<=not time10ms; timecnt<=0;end if;--16倍超采样,5208/16=325if ClockCount_Rx=ClockCount_Rx1 then Clock3<='1';ClockCount_Rx:=0;else Clock3<='0';end if;if(clkcnt="10000000000000")then clkcnt<="00000000000000";else clkcnt<=clkcnt+1;end if;end if;end process;--注:以上代码注释 均是以波特率9600为例,case语句部分即为波特率选择部分。LCD_Clk<=clkcnt(6);------------------------------------------------键盘扫描部分-------------------------------------------------------- --进程2:键盘扫描输出process( time10ms,RESET)beginif RESET='0' then scanvalue<="0001";combvalue<="00000000"; Data00<="0000000000"; --初始化elsif time10ms'event and time10ms='1' then --每10ms进行一次键盘扫描KeyOut<=scanvalue; --输出扫描值 cpy_scanvalue<=scanvalue; --备份扫描值,为了进程3对扫描结果进行比较 case scanvalue is --扫描值移位when "0001" => scanvalue<="0010";when "0010" => scanvalue<="0100";when "0100" => scanvalue<="1000";when "1000" => scanvalue<="0001"; when others => scanvalue<="0001";end case; combvalue<= (KeyIn & cpy_scanvalue); --组合键盘扫描的输入和输出case combvalue is --翻译扫描结果when "00010001" => Data00<="1000000010"; --对应键盘“1”when "00100001" => Data00<="1000000100"; --对应键盘“2”when "01000001" => Data00<="1000000110"; --对应键盘“3”when "10000001" => JX<="100"; --对应键盘“X”when "00010010" => Data00<="1000001000"; --对应键盘“4”when "00100010" => Data00<="1000001010"; --对应键盘“5”when "01000010" => Data00<="1000001100"; --对应键盘“6”when "10000010" => JX<="010"; --对应键盘“Y”when "00010100" => Data00<="1000001110"; --对应键盘“7”when "00100100" => Data00<="1000010000"; --对应键盘“8”when "01000100" => Data00<="1000010010"; --对应键盘“9”when "10000100" => JX<="001"; --对应键盘“Z”when "00011000" => Data00<="1000001000"; --对应键盘“0”when "00101000" => null; --对应键盘“+”when "01001000" => null; --对应键盘“-”when "10001000" => null; --对应键盘“=”when others => null; --无键盘按下end case; end if;end process;------------------------------------------------串口发送部分-------------------------------------------------------- process(Clock9600) --串口发送程序variable Send_count : integer range 0 to 9 :=0; --位发送计数 beginif Send_en='1' then Send_count:=0;UART0_TX<='1';Send_over<='1';elsif rising_edge(Clock9600) thenif Send_count=9 then UART0_TX<=Send_data(9); Send_over<='0';else UART0_TX<=Send_data(Send_count); Send_count:=Send_count+1; end if;end if;end process;Key0:key5 port map(CLK=>CLK,RESET=>RESET,din=>KEYA,dout=>dout); --元件例化process(dout,Clock9600,RESET) --发送激励beginif RESET='0' then Send_en<='1';Send_data<="1000000000";elseif rising_edge(dout) then Send_en<='0'; Send_data<=Data00; end if;if Send_over='0' then Send_en<='1'; end if;end if;end process;------------------------------------------------串口接收部分-------------------------------------------------------- process(RESET,CLK,Rx_Valid) --串口接收检测起始位beginif RESET='0' then Rx_Hold<='0';else if UART0_RX='0' and Rx_Hold='0' then Rx_Hold<='1'; --挂起串口接收elsif Rx_Valid'event and Rx_Valid='0' then Rx_Hold<='0';end if;end if; end process;process(RESET,Clock3) --variable m:integer range 0 to 168 :=0;beginif RESET='0' then Rx_Valid<='0';m:=0;elsif rising_edge(Clock3) and Rx_Hold='1'then case m iswhen 24 => Rx_Data(0)<=UART0_RX;when 40 => Rx_Data(1)<=UART0_RX;when 56 => Rx_Data(2)<=UART0_RX;when 72 => Rx_Data(3)<=UART0_RX;when 88 => Rx_Data(4)<=UART0_RX;when 104 => Rx_Data(5)<=UART0_RX;when 120 => Rx_Data(6)<=UART0_RX;when 136=> Rx_Data(7)<=UART0_RX; when 152 => Rx_Valid<='1';when 168=> m:=0;Rx_Valid<='0';when others => null;end case;m:=m+1;end if;end process;process(Rx_Valid,CLK)beginif RESET='0' then Data1<="0000"; Data2<="0000";elseif rising_edge(Rx_Valid) then Data1<=Rx_Data(3)&Rx_Data(2)&Rx_Data(1)&Rx_Data(0);Data2<=Rx_Data(7)&Rx_Data(6)&Rx_Data(5)&Rx_Data(4);end if;end if;end process;---------------------------------------LCD12864基本参数设置--------------------------------------------------------- control: process ( LCD_Clk,current_state )variable fanwei:integer:=2500;variable cnt : integer:=0 ;beginif LCD_Clk'event and LCD_Clk='1' then case current_state iswhen set => LCD_RS<='0'; --功能设定LCD_D<="00110000" ; ----30hLCD_E<='0';if cnt=2 then LCD_E<='1' ;cnt:=cnt+1 ;else LCD_E<='0' ; cnt:=cnt+1 ;end if ;if cnt=fanwei*2 thencurrent_state<=clr ;cnt:=0 ;else current_state<=set ;end if ;when clr => LCD_E<='0' ;LCD_RS<='0' ;LCD_D<="00000001"; ---清除显示 ,01Hif cnt=2 then LCD_E<='1'; cnt:=cnt+1 ;else LCD_E<='0'; cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_d ;cnt:=0 ; else current_state<=clr ;end if ;when set_d => LCD_E<= '0' ; -----设定显示的移动方向,06HLCD_RS<= '0' ;LCD_D<="00000110";if cnt=2 then LCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state <=open1; cnt :=0 ; else current_state<=set_d;end if ;when open1=> LCD_E<='0' ; -----显示状态开或关 0FHLCD_RS<='0' ;LCD_D<="00001100";if cnt=2 then LCD_E<= '1'; cnt:=cnt+1 ;else LCD_E<='0'; cnt:=cnt+1 ;end if ;if cnt=fanwei*2 thencurrent_state<=set_addr ;cnt:=0 ; else current_state<=open1;end if ;--------------------------------第一行 显示“波特率:(波特率数值)”------------------------------------------ when set_addr=>LCD_E<='0' ;LCD_RS<='0' ; LCD_D<=X"80"; ----设定地址 80Hif cnt=2 then LCD_E<='1'; cnt:=cnt+1 ;else LCD_E<='0'; cnt :=cnt+1 ;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom1 ;cnt:=0; else current_state<=set_addr;end if ;when set_ddrom1=>LCD_E<='0' ;LCD_RS<='1' ;LCD_D<=X"B2"; ----‘波’高字节if cnt=2 then LCD_E<='1'; cnt:=cnt+1 ;else LCD_E<='0'; cnt :=cnt+1 ;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom2 ;cnt:=0; else current_state<=set_ddrom1;end if ;when set_ddrom2=> LCD_E<='0';LCD_RS<='1';LCD_D<=X"A8"; ----‘波’低字节if cnt=2 then LCD_E<='1';cnt:=cnt+1; else LCD_E<='0';cnt:=cnt+1; end if;if cnt=fanwei*2 thencurrent_state<=set_ddrom3;cnt:=0; else current_state<=set_ddrom2; end if;when set_ddrom3=> LCD_E<='0'; ----‘特’高字节LCD_RS<='1';LCD_D<=X"CC";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom4;cnt:=0;else current_state<=set_ddrom3;end if;when set_ddrom4=> LCD_E<='0'; ----‘特’低字节LCD_RS<='1';LCD_D<=X"D8";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom5;cnt:=0;else current_state<=set_ddrom4;end if;when set_ddrom5=> LCD_E<='0'; ----‘率’高字节LCD_RS<='1'; LCD_D<=X"C2";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom6;cnt:=0;else current_state<=set_ddrom5;end if;when set_ddrom6=> LCD_E<='0'; ----‘率’低字节LCD_RS<='1'; LCD_D<=X"CA";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom7;cnt:=0;else current_state<=set_ddrom6;end if;when set_ddrom7=> LCD_E<='0'; ----‘:’高字节LCD_RS<='1';LCD_D<=X"A3";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom8;cnt:=0;else current_state<=set_ddrom7;end if;when set_ddrom8=> LCD_E<='0'; ----‘:’低字节LCD_RS<='1';LCD_D<=X"BA";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom9;cnt:=0;else current_state<=set_ddrom8;end if;when set_ddrom9=> LCD_E<='0'; ----‘9’LCD_RS<='1';case JX is when "100" => LCD_D<=X"39";when "010" => LCD_D<=X"31";when "001" => LCD_D<=X"33";when others => null;end case;if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom10;cnt:=0;else current_state<=set_ddrom9;end if;when set_ddrom10=> LCD_E<='0'; ----‘6’LCD_RS<='1';case JX is when "100" => LCD_D<=X"36";when "010" => LCD_D<=X"39";when "001" => LCD_D<=X"38";when others => null;end case;if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom11;cnt:=0;else current_state<=set_ddrom10;end if;when set_ddrom11=> LCD_E<='0';LCD_RS<='1'; ----‘0’高字节case JX is when "100" => LCD_D<=X"30";when "010" => LCD_D<=X"32";when "001" => LCD_D<=X"34";when others => null;end case;if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom12;cnt:=0;else current_state<=set_ddrom11;end if;when set_ddrom12=> LCD_E<='0';LCD_RS<='1'; ----‘0’低字节LCD_D<=X"30";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom13;cnt:=0;else current_state<=set_ddrom12;end if;when set_ddrom13=> LCD_E<='0'; ----‘ ’高字节LCD_RS<='1';case JX is when "100" => LCD_D<=X"D7";when "010" => LCD_D<=X"30";when "001" => LCD_D<=X"30";when others => null;end case;if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_addrh4;cnt:=0;else current_state<=set_ddrom13;end if;--注:以上代码注释 均是以波特率9600为例,case语句部分即为波特率选择部分。 ---------------------------------第二行 显示:“数字:(传送值)”---------------------------------when set_addrh4=>LCD_E<='0' ;LCD_RS<='0' ; LCD_D<=X"8A"; ----设定地址 8AHif cnt=2 then LCD_E<='1'; cnt:=cnt+1 ;else LCD_E<='0'; cnt :=cnt+1 ;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom1h4 ;cnt:=0; else current_state<=set_addrh4;end if ;when set_ddrom1h4=>LCD_E<='0' ;LCD_RS<='1' ;LCD_D<="11001010"; ----‘数’高字节if cnt=2 then LCD_E<='1'; cnt:=cnt+1 ;else LCD_E<='0'; cnt :=cnt+1 ;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom2h4 ;cnt:=0; else current_state<=set_ddrom1h4;end if ;when set_ddrom2h4=> LCD_E<='0';LCD_RS<='1';LCD_D<="11111101"; ----‘数’低字节if cnt=2 then LCD_E<='1';cnt:=cnt+1; else LCD_E<='0';cnt:=cnt+1; end if;if cnt=fanwei*2 thencurrent_state<=set_ddrom3h4;cnt:=0; else current_state<=set_ddrom2h4; end if;when set_ddrom3h4=> LCD_E<='0'; ----‘字’高字节LCD_RS<='1';LCD_D<=X"D7";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom4h4;cnt:=0;else current_state<=set_ddrom3h4;end if;when set_ddrom4h4=> LCD_E<='0'; ----‘字’低字节LCD_RS<='1';LCD_D<=X"D6";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom5h4;cnt:=0;else current_state<=set_ddrom4h4;end if;when set_ddrom5h4=> LCD_E<='0'; ----‘:’高字节LCD_RS<='1';LCD_D<=X"A3";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom6h4;cnt:=0;else current_state<=set_ddrom5h4;end if;when set_ddrom6h4=> LCD_E<='0'; ----‘:’低字节LCD_RS<='1';LCD_D<=X"BA";if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom7h4;cnt:=0;else current_state<=set_ddrom6h4;end if;when set_ddrom7h4=> LCD_E<='0'; ----‘传送的代码值’LCD_RS<='1';LCD_D<=X"20";case Data2 is when "0000" => LCD_D<=X"30";when "0001" => LCD_D<=X"31";when "0010" => LCD_D<=X"32";when "0011" => LCD_D<=X"33";when "0100" => LCD_D<=X"34";when "0101" => LCD_D<=X"35";when "0110" => LCD_D<=X"36";when "0111" => LCD_D<=X"37";when "1000" => LCD_D<=X"38";when "1001" => LCD_D<=X"39";when others => null; end case;if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=set_ddrom8h4;cnt:=0;else current_state<=set_ddrom7h4;end if;when set_ddrom8h4=> LCD_E<='0'; ----‘传送的代码值’LCD_RS<='1';LCD_D<=X"20";case Data1 is when "0000" => LCD_D<=X"30";when "0001" => LCD_D<=X"31";when "0010" => LCD_D<=X"32";when "0011" => LCD_D<=X"33";when "0100" => LCD_D<=X"34";when "0101" => LCD_D<=X"35";when "0110" => LCD_D<=X"36";when "0111" => LCD_D<=X"37";when "1000" => LCD_D<=X"38";when "1001" => LCD_D<=X"39";when others => null;end case;if cnt=2 thenLCD_E<='1';cnt:=cnt+1;else LCD_E<='0';cnt:=cnt+1;end if ;if cnt=fanwei*2 thencurrent_state<=open1;cnt:=0;else current_state<=set_ddrom8h4;end if; when others=>current_state<=open1;end case;end if;
end process control;
end Behavioral;------------------------------------------------主程序文件-----------------------------------------------------------
五、实验结果:
本次试验的波特率通过键盘上的“X”“Y”“Z”分别更改为:“9600、19200、38400”;LCD屏幕第一行显示“波特率: ”,第二行显示:“数字: ”;发送数字时按键盘中“A”键即可,在这里,只能发送和接收两位数的数字。以上功能,读者均可根据自身需求增添删改。在使用LCD12864时,需要知道汉字、数字和标点符号的内码,使用到的汉字内码查询器站内有很多,读者自行下载使用即可。
注明:本文章仅供学习参考之用,代码简单,但贵在易于理解和更改。作者水平有限,不免有错漏之处,如有问题或建议,可留言告之。
基于FPGA的UART串口通信实验(VHDL语言实现)相关推荐
- 基于FPGA Uart串口通信实验
基于FPGA Uart串口通信实验 首先需要了解uart串口通信协议,根据个人专业需求不同,了解的层面可以不同. UART简介 通用异步收发传输器(Universal Asynchronous Rec ...
- 基于 FPGA 的 UART 控制器设计(VHDL)(下)
今天给大侠带来基于FPGA的 UART 控制器设计(VHDL)(下),由于篇幅较长,分三篇.今天带来第三篇,下篇,使用 FPGA 实现 UART.话不多说,上货. 之前有关于 Veriliog HDL ...
- 【正点原子MP157连载】 第十六章 UART串口通信实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7
1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...
- 基于FPGA实现uart串口模块(Verilog)--------发送模块及整合
基于FPGA实现uart串口模块(Verilog)--------发送模块及整合 当接收模块接收到数据后,需要重新发送形成回环验证模块正确性.思路和结束模块有一点点的小差异.接收模块最终输出的是一个并 ...
- 基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结
基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结 uart通信协议简单理解为串转并和并转串的两个模块.同时必须保证数据的正确性.且输入输出端为串行. 此次实现uar ...
- 【FPGA练习】(一): UART串口通信实验
由于之前学习FPGA的过程中,没有做一个良好的记录,以及已学知识的扩展,所以从今天开始每一个实验例程和扩展应用,都要做文档记录.本实验,是基于正点原子达芬奇xc7a35tfgg484-2开发板.开发板 ...
- UART 串口通信实验
串口是"串行接口"的简称,即采用串行通信方式的接口.串行通信将数据字节分成一位一位的形式在一条数据线上逐个传送,其特点是通信线路简单,但传输速度较慢.因此串口广泛应 ...
- 【FPGA】UART串口通信
目录 前言 一丶通信方式 1.串行通信 2.并行通信 二丶UART 串口通信 三丶模块设计 四丶发送模块 1.代码 2.仿真 五丶接收模块 1.代码 2.仿真 六丶顶层模块 1.代码 2.模块原理图 ...
- 【FPGA】——UART串口通信
UART串口简介 串行通信分为两种方式:同步串行通信和异步串行通信.同步串行通信要求通信双方使用同一时钟,异步则没有这个要求.UART是一种采用异步串行通信方式的通用异步收发传输器(univers ...
最新文章
- PyQt5 技术篇-调用字体对话框(QFontDialog)获取字体,控件设置字体。
- 【蚁群路径规划】基于MATLAB的蚁群算法的二维路径规划
- C++ Primer 5th笔记(chap 19 特殊工具与技术)两种不可移植的特性之“位域”
- php 客户端上传图片,php上传图片客户端和服务器端实现方法
- 上班族吐槽大集合:那些发生在公司的傻X奇遇
- 使用SynchronousQueue实现生产者/消费者
- 关于chrome控制台警告:Synchronous XMLHttpRequest on the main thread终极解决办法
- 高德联手饿了么:外卖小哥跑出偏远地区活地图
- 设置将Maven的jar包发布到lib
- CSS布局:让页脚始终保持底部的方法
- 弱监督学习-snorkel
- java 日语文档翻译_日语文档怎么翻译?我来教会你日语翻译
- 旋转木马图片效果图,轮播图
- 阿拉伯数字转换为英语
- 独家爆料!在美团搞安全,是种怎样的体验?
- 逆向经验 + 逆向工具
- ACM素数打表(模版)
- pcie gen3 bios设置_u盘pe设置联想台式机lenovo BIOS从u盘启动教程
- div样式之margin
- 谷歌卫星地图下载器有哪些那款好用