已阅读5页,还剩13页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于VHDL的串口收发设计20161227在quartus里面没找到SCI的LPM部件,又不想自己从头编写,在网上找到了一个verilog的程序,也找到了和这个实现方法相同的VHDL程序。都是接收到按键按下时候,启动串口发送,发送welcom但是都是发现一个,并延时重新读取按键,然后再重新启动发送。数据格式是9600 boud rate、 8数据位、 1启动位、 1停止位,每16个bit周期发送一个byte,接收程序,没有中间多位判断部分,考虑接收的有效性和可靠性,对程序进行了修改,改为每11个bit周期发送一个byte,这样也可以兼容接收2个停止位的接收程序,在接收程序中进行了多相判断。程序和截图如下:-本模块的功能是验证实现和PC机进行基本的串口通信的功能。需要在PC机上安装一个串口调试工具来验证程序的功能。-程序实现了一个收发一帧10个bit(即无奇偶校验位)的串口控制器,10个bit是1位起始位,8个数据位,1个结束位。-串口的波特律由程序中定义的div_par参数决定,更改该参数可以实现相应的波特率。程序当前设定的div_par 的值-是0x145,对应的波特率是9600。用一个8倍波特率的时钟将发送或接受每一位bit的周期时间划分为8个时隙以使通-信同步.-程序的基本工作过程是,按动一个按键key1 控制器向PC的串口发送“welcome,-PC机接收后显示验证数据是否正确(串口调试工具设成按ASCII码接受方式).-PC可随时向FPGA发送0-F的十六进制数据,FPGA接受后显示在7段数码管上.library ieee;- design by jiaolonglan20161227use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity myserial isgeneric ( boud_rate:integer := 9600;clk_rate :integer := 50_000_000);port( clk : in std_logic;rstn : in std_logic;rxd : in std_logic; -receive bittxd : out std_logic; -send bit -txd_buff :in std_logic_vector(7 downto 0); - buffer write in-write_data: in std_logic; - write data en :out std_logic_vector(7 downto 0); seg_data:out std_logic_vector(7 downto 0);-rxd_buff :out std_logic_vector(7 downto 0);key_input:in std_logic-testout: out std_logic-read_data: in std_logic);end entity myserial; architecture bhv of myserial is SIGNAL div_reg : integer range 0 to 2*16-1;-分频计数器,分频值由波特率决定。分频后得到频率8倍波特率的时钟 SIGNAL div8_tras_reg : std_logic_vector(2 DOWNTO 0);-该寄存器的计数值对应发送时当前位于的时隙数 SIGNAL div8_rec_reg : std_logic_vector(2 DOWNTO 0);- 寄存器的计数值对应接收时当前位于的时隙数 SIGNAL state_tras : std_logic_vector(3 DOWNTO 0);- 发送状态寄存器 SIGNAL state_rec : std_logic_vector(3 DOWNTO 0);- 接受状态寄存器 SIGNAL clkbaud_tras : std_logic; -以波特率为频率的发送使能信号 SIGNAL clkbaud_rec : std_logic;- 以波特率为频率的接受使能信号 SIGNAL clkbaud8x : std_logic; -以8倍波特率为频率的时钟,它的作用是将发送或接受一个bit的时钟周期分为8个时隙 SIGNAL recstart : std_logic; -开始发送标志 SIGNAL recstart_tmp : std_logic; -开始接受标志 SIGNAL trasstart : std_logic; - SIGNAL rxd_reg : std_logic_vector(7 downto 0); -接收寄存器1 SIGNAL txd_reg : std_logic; -发送寄存器 SIGNAL rxd_buf : std_logic_vector(7 DOWNTO 0);-接受数据缓存 SIGNAL txd_buf : std_logic_vector(7 DOWNTO 0);-发送数据缓存 SIGNAL send_state : std_logic_vector(2 DOWNTO 0);-每次按键给PC发送Welcome字符串,这是发送状态寄存器 SIGNAL cnt_delay : integer range 0 to 2*20-1;- std_logic_vector(19 DOWNTO 0);-延时去抖计数器 SIGNAL start_delaycnt : std_logic; - 开始延时计数标志 SIGNAL key_entry1 : std_logic; - 确定有键按下曛? SIGNAL key_entry2 : std_logic; - 确定有键按下标志 CONSTANT div_par : integer :=8; -for test :=clk_rate/(8*boud_rate); - 分频参数,其值由对应的波特率计算而得,按此参数分频的时钟频率是波倍特率的8倍,此处值对应9600的波特率,即分频出的时钟频率是9600*8 beginen =01010101 ;-7段数码管使能信号赋值txd = txd_reg ;PROCESS(clk,rstn)- delay counter BEGIN IF( rstn =0) THEN cnt_delay = 0; start_delaycnt=0; - key_entry1 =0; ELSIF(clkEVENT AND clk = 1)THEN IF (key_entry2 =1) THEN - start transmit and clear key_entry1 key_entry1 =0; - ELSEIF (cnt_delay = 98) THEN IF ( key_input = 1) THEN key_entry1 = 1; END IF; END IF; END IF; IF (start_delaycnt = 1) THEN - key press IF (cnt_delay 99 ) THEN -20D800000 cnt_delay = cnt_delay + 1; ELSE -rejudge key cnt_delay = 0; start_delaycnt =0; END IF; ELSE IF (key_input=1) AND (cnt_delay = 0) THEN-judge key press start start_delaycnt =1; END IF; END IF; END IF; END PROCESS; PROCESS(clk,rstn) -recycle counter分频得到8倍波特率的时钟 div_par BEGIN IF (rstn =0) THEN div_reg = 0; clkbaud8x =0; ELSIF(clkEVENT AND clk=1)THEN IF (div_reg = div_par - 1) THEN div_reg = 0; clkbaud8x = NOT clkbaud8x; ELSE div_reg = div_reg + 1; END IF; END IF; END PROCESS; PROCESS(clkbaud8x,clkbaud8x,rstn) BEGIN IF (rstn =0) THEN div8_rec_reg = 000; div8_tras_reg = 000; ELSE IF(clkbaud8xEVENT AND clkbaud8x =1) THEN IF (recstart =1) THEN - 接收开始标志 div8_rec_reg = div8_rec_reg + 001;-接收开始后,时隙数在8倍波特率的时钟下加1循环 END IF; IF (trasstart =1) THEN div8_tras_reg = div8_tras_reg + 001;-发送开始后,时隙数在8倍波特率的时钟下加1循环 END IF; END IF; END IF; END PROCESS; PROCESS(div8_rec_reg,div8_tras_reg) - creat receive and transmit data clk BEGIN IF (div8_rec_reg = 111) THEN clkbaud_rec =1; -在第7个时隙,接收 ELSE clkbaud_rec =0; END IF; IF (div8_tras_reg = 111) THEN clkbaud_tras =1; - 在第7个时隙,发送使能信号有效,将数据发出 ELSE clkbaud_tras =0; END IF; END PROCESS; PROCESS(clkbaud8x,rstn) -trsnsmit data BEGIN IF (rstn =0) THEN txd_reg =1; trasstart =0; txd_buf = 00000000; state_tras = 0000; send_state = 000; key_entry2 =0; ELSE IF(clkbaud8xEVENT AND clkbaud8x =1) THEN IF ( key_entry2 = 0) THEN IF (key_entry1 = 1) THEN key_entry2 = 1; txd_buf -发送起始位 IF ( trasstart=0) AND (send_state 111) ) THEN - havent send all data then continue transmit trasstart = 1; ELSE IF (send_state 111) THEN - send_state is char counter IF (clkbaud_tras = 1) THEN - enable transmit every data bit flag txd_reg = 0; - start bit state_tras = state_tras + 0001; - state_tras is bit counter END IF; ELSE - =7 key_entry2 = 0; state_tras -发送第1位 IF (clkbaud_tras = 1) THEN txd_reg = txd_buf(0); -under send regis txd_buf(6 DOWNTO 0) = txd_buf(7 DOWNTO 1); state_tras - 发送第2位 IF (clkbaud_tras = 1) THEN txd_reg = txd_buf(0); txd_buf(6 DOWNTO 0) = txd_buf(7 DOWNTO 1); state_tras - 发送第3位 IF (clkbaud_tras = 1) THEN txd_reg = txd_buf(0); txd_buf(6 DOWNTO 0) = txd_buf(7 DOWNTO 1); state_tras - 发送第4位 IF (clkbaud_tras = 1) THEN txd_reg = txd_buf(0); txd_buf(6 DOWNTO 0) = txd_buf(7 DOWNTO 1); state_tras - 发送第5位 IF (clkbaud_tras = 1) THEN txd_reg = txd_buf(0); txd_buf(6 DOWNTO 0) = txd_buf(7 DOWNTO 1); state_tras -发送第6位 IF (clkbaud_tras = 1) THEN txd_reg = txd_buf(0); txd_buf(6 DOWNTO 0) = txd_buf(7 DOWNTO 1); state_tras - 发送第7位 IF (clkbaud_tras = 1) THEN txd_reg = txd_buf(0); txd_buf(6 DOWNTO 0) = txd_buf(7 DOWNTO 1); state_tras - 发送第8位 IF (clkbaud_tras = 1) THEN txd_reg = txd_buf(0); txd_buf(6 DOWNTO 0) = txd_buf(7 DOWNTO 1); state_tras - 发送停止位 IF (clkbaud_tras = 1) THEN txd_reg = 1; txd_buf = 01010101; state_tras - 1111run to 15 IF (clkbaud_tras = 1) THEN state_tras = 0000; - state_tras + 0001; - next is 0000 send_state = send_state + 001; - judge send byte trasstart txd_buf txd_buf txd_buf txd_buf txd_buf txd_buf txd_buf - run to 10 and 14 IF (clkbaud_tras = 1) THEN - state_tras = state_tras + 0001; /old state_tras = 0000; trasstart = 1; END IF; END CASE; END IF; END IF; END IF; END PROCESS; PROCESS(clkbaud8x,rstn) - receive PC机的数据 variable temp:integer range 0 to 8; variable rcv_data: std_logic; BEGIN IF (rstn = 0) THEN rxd_reg 0); rxd_buf = 00000000; -every phase state_rec = 0000; recstart = 0; recstart_tmp = 0; ELSE IF(clkbaud8xEVENT AND clkbaud8x = 1) THEN rxd_reg = rxd_reg(6 downto 0) & rxd; IF (state_rec = 0000) THEN IF (recstart_tmp = 1) THEN -have capture start bit recstart = 1; recstart_tmp = 0; state_rec = state_rec + 0001; ELSE IF (rxd_reg(7 downto 4 )=1100) THEN -检测到起始位的下降沿,进入接受状态 recstart_tmp = 0001 AND state_rec= 2 thenrcv_data := 1;elsercv_data :=0;end if; end loop; rxd_buf(7) = rcv_data; rxd_buf(6 DOWNTO 0) = rxd_buf(7 DOWNTO 1); state_rec = state_rec + 0001; END IF; ELSE - stop bit IF (state_rec = 1001) THEN IF (clkbaud_rec = 1) THEN IF rxd_reg(2) = 0 THEN - stop bit errorrxd_buf 0); END IF; state_rec = 0000; recstart seg_data seg_data seg_data seg_data seg_data seg_data seg_data seg_data seg_data seg_data seg_data seg_data seg_data seg_data seg_data seg_data seg_data = 11111111; END CASE;end if; END PROCESS;end bhv;-本模块的功能是验证实现和PC机进行基本的串口通信的功能。需要在PC机上安装一个串口调试工具来验证程序的功能。-程序实现了一个收发一帧10个bit(即无奇偶校验位)的串口控制器,10个bit是1位起始位,8个数据位,1个结束位。-串口的波特律由程序中定义的div_par参数决定,更改该参数可以实现相应的波特率。程序当前设定的div_par 的值-是0x145,对应的波特率是9600。用一个8倍波特率的时钟将发送或接受每一位bit的周期时间划分为8个时隙以使通-信同步.-程序的基本工作过程是,按动一个按键key1 控制器向PC的串口发送“welcome,-PC机接收后显示验证数据是否正确(串口调试工具设成按ASCII码接受方式).-PC可随时向FPGA发送0-F的十六进制数据,FPGA接受后显示在7段数码管上.library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity myserial isgeneric ( boud_rate:integer := 9_600;clk_rate :integer := 50_000_000);port( clk : in std_logic;rstn : in std_logic;rxd : in std_logic; -receive bittxd : out std_logic; -send bit -write_data: in std_logic; - write data-enable :in std_logic_vector(7 downto 0);- send_data:in std_logic_vector(7 downto 0); receive_data:out std_logic_vector(7 downto 0);- transmit_fifo_deep: out std_logic_vector(3 downto 0); -under transmit data num- receive_fifo_deep:out std_logic_vector(3 downto 0);- have received data num- rint: out std_logic; - - xint: out std_logic; -test_send:in std_logic);end entity myserial; architecture bhv of myserial is SIGNAL div_reg : integer range 0 to 2*16-1;-分频计数器,分频值由波特率决定。分频后得到频率8倍波特率的时钟 SIGNAL trans_time_slot_cnt : std_logic_vector(2 DOWNTO 0);-该寄存器的计数值对应发送时当前位于的时隙数 SIGNAL receve_time_slot_cnt : std_logic_vector(2 DOWNTO 0);- 寄存器的计数值对应接收时当前位于的时隙数 SIGNAL send_bit_cnt : std_logic_vector(3 DOWNTO 0);- 发送状态寄存器 SIGNAL receive_bit_cnt: std_logic_vector(3 DOWNTO 0);- 接受状态寄存器 SIGNAL transmit_bit_enable : std_logic; -以波特率为频率的发送使能信号 SIGNAL receive_bit_enable : std_logic;- 以波特率为频率的接受使能信号 SIGNAL clkbaud8x : std_logic; -以8倍波特率为频率的时钟,它的作用是将发送或接受一个bit的时钟周期分为8个时隙 SIGNAL recstart : std_logic; -开始接收标志 SIGNAL trasstart : std_logic; -开始发送标志 SIGNAL rxd_reg : std_logic_vector(8 downto 0); -接收寄存器 SIGNAL txd_bit : std_logic; -发送寄存器 SIGNAL rxd_slot_buf : std_logic_vector(7 DOWNTO 0);-接受数据缓存 SIGNAL txd_buf : std_logic_vector(7 DOWNTO 0);-发送数据缓存 SIGNAL send_char_cnt : std_logic_vector(2 DOWNTO 0);-3 每次按键给PC发送Welcome字符串,这是发送状态寄存器 -CONSTANT div_par : integer := 8; - 50000000/(9600*8) - for test CONSTANT div_par : integer := clk_rate/(8*boud_rate); - 50000000/(9600*8) -every time slot clk num - 分频参数,其值由对应的波特率计算而得,按此参数分频的时钟频率是波倍特率的8倍,此处值对应9600的波特率,即分频出的时钟频率是9600*8 begintxd = txd_bit ; - send out PROCESS(clk,rstn) -recycle counter分频得到8倍波特率的时钟 div_par BEGIN IF (rstn =0 ) THEN div_reg = 0; clkbaud8x =0; ELSIF(clkEVENT AND clk=1)THEN IF (div_reg = div_par - 1) THEN div_reg = 0; clkbaud8x = NOT clkbaud8x; ELSE div_reg = div_reg +
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年青岛本土人才题库及答案
- 2025年吉林补考化学试卷及答案
- 合同范本客户写模板
- 医院公司合作协议书
- 司机的劳动合同范本
- 口腔医疗赔偿协议书
- 变更合同名称的协议
- 九龙公务员面试题及答案
- 2025-2030中国液体危险品物流供应链优化与风险管理研究报告
- 临大运动营养学教案第9讲 改变一生的饮食习惯
- 《ABB工业机器人编程与操作》课件-项目五 工业机器人涂胶装配编程与操作
- 女性私护抗衰课件
- 2025年党员干部党的理论知识应知应会题库及答案
- 2025年招录考试-工会招聘考试历年参考题库含答案解析(5套典型题)
- V型滤池技术介绍
- 2024年黑龙江大学招聘笔试真题及答案
- 胸痛健康知识宣教要点
- 初三语文老师家长会课件
- 2025年党史党建知识测试题库100题(含标准答案)
- 污水管网深基坑钢板桩支护施工方案
- 施工领域排查安全隐患简报
评论
0/150
提交评论