网站推销策划方案网页微博怎么看直播

当前位置: 首页 > news >正文

网站推销策划方案,网页微博怎么看直播,wordpress自定义导航菜单,长沙房价一览表基于bi站正点原子讲解视频#xff1a; 系统框图#xff08;基于串口的数据回环#xff09;如下#xff1a; 以下#xff0c;是串口接收端的波形图#xff0c;系统时钟和波特率时钟不同#xff0c;为异步时钟#xff0c;#xff0c;需要先延时两拍#xff0c;将时钟同…基于bi站正点原子讲解视频 系统框图基于串口的数据回环如下 以下是串口接收端的波形图系统时钟和波特率时钟不同为异步时钟需要先延时两拍将时钟同步过来取到start_flag信号由start_flag信号结合clk_cnt、bps_cnt两个计数器取到rx_flag信号随后在rx_flag高电平时计算clk_cnt以及bps_cnt两个信号。最后两个信号uart_done、uart_data则在串口发送模块有所体现。 实际上uart_done在串口发送模块中也就是uart_en信号而uart_data也就是发送模块中的uart_din信号。 timescale 1ns / 1ps // Create Date: 2025/01/06 09:38:08 // Design Name: // Module Name: uart_recv module uart_recv(input sys_clk , //50Mhz系统时钟input sys_rst_n ,input uart_rxd , //接收到的数据output reg [7:0] uart_data , //输出的并行数据output reg uart_done //一帧信号接收完成);parameter sys_freq 50_000_000;parameter uart_bps 115_200;parameter bps_cnt sys_freq/uart_bps - 1;//从0开始计算reg uart_rxd_d0;reg uart_rxd_d1;wire start_flag;reg rx_flag;reg [15:0] clk_cnt;reg [3:0] rx_cnt;reg [7:0] rx_data;//中间变量存储提取到的每个位的数据来实现串口端的串并转换//由高电平向低电平的跳变下降沿相当于d1延时2个时钟周期d0延时1个时钟周期//因此判断d1是否为高且d0是否为低即可。assign start_flag uart_rxd_d1 (~uart_rxd_d0);//异步时钟同步化处理always(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginuart_rxd_d0 1b1;uart_rxd_d1 1b1;endelse beginuart_rxd_d0 uart_rxd;uart_rxd_d1 uart_rxd_d0;endend//rx_flagalways(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)rx_flag 1b0;else if(start_flag 1b1)rx_flag 1b1;else if((rx_cnt 4d9) (clk_cnt bps_cnt/2 - 1b1)) //为监测到下一帧数据的起始位留半个周期的时间rx_flag 1b0;else rx_flag 1b1;end//clk_cntalways(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)clk_cnt 16d0;else if(rx_flag 1b1) // begin //效果相同否 // if(clk_cnt uart_bps) // clk_cnt 16d0; // else // clk_cnt clk_cnt 16d1; // endbegin if(clk_cnt uart_bps - 16d1) clk_cnt clk_cnt 16d1; else clk_cnt 16d0; end else clk_cnt 16d0; end//rx_cntalways(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)rx_cnt 4d0;else if(rx_flag 1b1)beginif(clk_cnt uart_bps - 16d1)rx_cnt rx_cnt 4d1;else rx_cnt rx_cnt;endelserx_cnt 4d0;end//rx_dataalways(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)rx_data 8d0;else if((rx_flag 1b1)(clk_cnt uart_bps/2)) begincase(rx_cnt)//数据的串转并_uart_rxd是异步信号//所以要需要两拍之后的信号uart_rxd_d1。4d1: rx_data[0] uart_rxd_d1;4d2: rx_data[1] uart_rxd_d1;4d3: rx_data[2] uart_rxd_d1;4d4: rx_data[3] uart_rxd_d1;4d5: rx_data[4] uart_rxd_d1;4d6: rx_data[5] uart_rxd_d1;4d7: rx_data[6] uart_rxd_d1;4d8: rx_data[7] uart_rxd_d1;endcaseendendalways(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginuart_data 8d0;uart_done 1d0;endelse if(rx_cnt 4d9)begin uart_data rx_data; uart_done 1d1; end elsebegin uart_data 8d0; uart_done 1d0; end end endmodule以下如何在程序中捕获信号的高低电平可实现异步时钟的同步处理以及信号的边沿检测 d0 1b1; d1 1b1; d0 uart_rxd; d1 d0;  也就是说在初始状态时将d0、d1拉高通过两次打拍将d0延时1个时钟周期d1延时2个时钟周期从而根据d0和d1的状态设置wire型的标志位flag来捕获需要的高低电平。 以下是是串口发送端的波形图整体过程和接收端基本类似只需要进行某些变量名称的修改即可但需要注意接收到的数据实际上是串口接收端的发送的数据uart_datauart_done信号也在发送端检测边沿电平过程中以uart_en的形式完成了两次打拍延迟。 timescale 1ns / 1ps // Create Date: 2025/01/06 14:50:27 // Design Name: // Module Name: uart_sendmodule uart_send(input sys_clk , //50Mhz系统时钟 input sys_rst_n , output reg uart_txd , //准备发送的数据 input uart_en , input [7:0] uart_din //从发送模块接收到的数据 );parameter sys_freq 50_000_000;parameter uart_bps 115_200;parameter bps_cnt sys_freq/uart_bps - 1;//从0开始计算reg uart_en_d0;reg uart_en_d1; reg tx_flag;reg [15:0] clk_cnt;reg [3:0] tx_cnt; reg [7:0] tx_data;//中间变量存储提取到的每个位的数据来实现串口端的串并转换wire en_flag;//由高电平向低电平的跳变下降沿相当于d1延时2个时钟周期d0延时1个时钟周期//因此判断d1是否为高且d0是否为低即可。assign en_flag (~uart_en_d1) uart_en_d0;//边沿信号检测检测上升沿always(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginuart_en_d0 1b1;uart_en_d1 1b1;endelse beginuart_en_d0 uart_en;uart_en_d1 uart_en_d0;endend//tx_dataalways(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)tx_data 8d0; else if(en_flag 1b1) tx_data uart_din;else tx_data tx_data;end//tx_flagalways(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)tx_flag 1b0;else if(en_flag 1b1)tx_flag 1b1;else if((tx_cnt 4d9) (clk_cnt bps_cnt/2 - 1))tx_flag 1b0;else //tx_flag tx_flag; //这两句话在这里作用相同否tx_flag 1b1;end//clk_cntalways(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)clk_cnt 16d0;else if(tx_flag 1b1) // begin // if(clk_cnt uart_bps) // clk_cnt 16d0; // else // clk_cnt clk_cnt 16d1; // endbegin if(clk_cnt uart_bps - 16d1) clk_cnt clk_cnt 16d1; else clk_cnt 16d0; end else clk_cnt 16d0; end//tx_cntalways(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)tx_cnt 4d0;else if(tx_flag 1b1)beginif(clk_cnt uart_bps - 16d1)tx_cnt tx_cnt 4d1;else tx_cnt tx_cnt;endelserx_cnt 4d0;end//uart_txdalways(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)uart_txd 1b1;else if((tx_flag 1b1)(clk_cnt 16d0)) begincase(tx_cnt)//数据并转串首先判断起始位赋值低电平//随后将tx_data一次赋值给输出端口uart_txd//最后注意一帧数据的停止位赋值高电平。4d0: uart_txd 1b0;4d1: uart_txd tx_data[0];4d2: uart_txd tx_data[1];4d3: uart_txd tx_data[2];4d4: uart_txd tx_data[3];4d5: uart_txd tx_data[4];4d6: uart_txd tx_data[5];4d7: uart_txd tx_data[6];4d8: uart_txd tx_data[7];4d9: uart_txd 1b1;endcaseendendendmodule以下是顶层文件分别将串口发送端和接收端两部分程序例化。 timescale 1ns / 1ps // Create Date: 2025/01/06 15:49:15 // Design Name: // Module Name: top_uartmodule top_uart(input sys_clk , //50Mhz系统input sys_rst_n , input uart_rxd , //接收到的数据output uart_txd //准备发送的数据 );wire [7:0] uart_data;wire uart_done;//串口接收模块的例化uart_recv uart_recv_u(.sys_clk (sys_clk ) , //50Mhz系统时钟.sys_rst_n (sys_rst_n ) ,.uart_rxd (uart_rxd ) , //接收到的数据.uart_data (uart_data ) , //输出的并行数据.uart_done (uart_done ) //一帧信号接收完成);// wire uart_en ; // wire [7:0] uart_din;//串口发送模块的例化;uart_send uart_send_u(.sys_clk (sys_clk ) , //50Mhz系统时钟 .sys_rst_n (sys_rst_n) , .uart_txd (uart_txd ) , //准备发送的数据 .uart_en (uart_done ) , .uart_din (uart_data ) //从发送模块接收到的数据 );endmodule以下是对应程序的RTL视图 另注意1 打两拍的异步时钟的同步处理打一拍是为了将异步时钟转为同步时钟如上本例子是将波特率时钟115200bps转换为系统时钟50Mhz打两拍则是为了消除亚稳态0 1之间的状态。 参考连接【Chips】跨时钟域的亚稳态处理、为什么要打两拍不是打一拍、为什么打两拍能有效_跨时钟域为什么打两拍-CSDN博客 另注意2 为什么在程序中最后1位的停止位需要延时半个周期而不是一个完整的周期也就是发送模块的如下程序 always(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)tx_flag 1b0;else if(en_flag 1b1)tx_flag 1b1;else if((tx_cnt 4d9) (clk_cnt bps_cnt/2 - 1))//停止位只有半个波特率周期tx_flag 1b0;else //tx_flag tx_flag; //tx_flag 1b1;end 首先延时半个周期是为了给下一帧数据接收时检测起始位留够时间在数据回环过程中不会出现太大问题但是如果单独调用串口的发送模块或者接收模块时就会出现问题在单独调用发送模块时因为停止位只有半个周期所以发送1帧数据过程总会先于上位机正常接收而提前结束造成错误。 所以选择将停止位周期设置为1个时钟周期但是实际上位机的波特率和实际计算的波特率仍有微小误差在将停止位设置为1个时钟周期时上位机串口助手的波特率实际会和自己设置的波特率如9600115200等存在或多或少的误差因此需要将停止位周期设置为1/2–1之间和上位机什么时候检测到1帧数据的停止位有关。 另附加上视频中给出得数据环回模块的程序 timescale 1ns / 1ps // Create Date: 2025/01/07 10:50:37 // Intrduction: 将串口接收到的数据进行缓存消除上位机和串口模块之间的时间误差 // Module Name: uart_loopmodule uart_loop(input sys_clk , //50Mhz系统时input sys_rst_n , input recv_done , //接收完成信号 input [7:0] recv_data , //接收到的数据 input tx_busy ,output reg send_en , output reg [7:0] send_data //待发送数据);reg recv_done_d0 ;reg recv_done_d1 ;reg tx_ready ;wire recv_done_flag; //捕获上升沿assign recv_done_flag (~recv_done_d0) recv_done_d1;//打两拍实现边沿检测always(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginrecv_done_d0 1b0;recv_done_d1 1b0;endelse begin recv_done_d0 recv_done;recv_done_d1 recv_done_d0;end end//判断接收完成信号并在串口发送模块空闲时发送是使能信号always(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)begintx_ready 1b0;send_en 1b0; send_data 8d0;endelsebeginif(recv_done_flag) begintx_ready 1b1; send_en 1b0; send_data recv_data; end else if(tx_ready(~tx_busy))begintx_ready 1b0;send_en 1b1;endendend endmodule再者vivado中串口默认波特率115200bps在调试过程需要注意如哦需要修改可参考下链接 https://zhuanlan.zhihu.com/p/633150036