2033|1

80

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

安路SparkRoad 串口通信 [复制链接]

 

串口通信是常用的低速通信接口,调试中也试用比较多,首先实现串口端口。

UART 串口通信需要两根信号线来实现,一根用于串口发送,另外一根负责串口接收。UART 在发送或接收过程中的一帧数据由 4 部分组成,起始位、数据位、奇偶校验位和停止位。

协议如下所示:

 

因为串口是异步,因此收,发分别实现,下面是收端:

  • `timescale 1ns / 1ns
  • module uartrx(
  • input clk,
  • input rst_n,
  • //uart interface
  • input uart_rx,
  • //user interface
  • output dataout_vld ,
  • output [7:0] dataout
  • );
  • //localparam
  • localparam BPS = 9600 ;
  • localparam BPS_CNT = 2500 ; // T/BPS
  • //reg define
  • reg [12:0] pcnt ;
  • reg [2:0] rx_dly ;
  • reg [3:0] rx_cnt ;
  • reg [7:0] rx_reg ;
  • reg rx_en ;
  • //wire define
  • wire rx_falling ;
  • assign rx_falling = rx_dly[2] & ~rx_dly[1] ;
  • //打拍 同步
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • rx_dly <= 3'b000 ;
  • else
  • rx_dly <= {rx_dly[1:0], uart_rx} ;
  • end
  • //接收到起始信号,开始标志
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • rx_en <= 1'b0 ;
  • else if(rx_falling == 1'b1)
  • rx_en <= 1'b1 ;
  • else if(rx_cnt == 4'd9)
  • rx_en <= 1'b0 ;
  • else ;
  • end
  • //rx 接收字节计数
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • rx_cnt <= 4'd0;
  • else if(rx_en == 1'b1)
  • if(pcnt == BPS_CNT -1'b1)
  • rx_cnt <= rx_cnt + 1'b1;
  • else;
  • else
  • rx_cnt <= 4'd0;
  • end
  • //PBS CNT
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • pcnt <= 13'd0;
  • else if(rx_en == 1'b1)
  • if(pcnt == BPS_CNT -1'b1)
  • pcnt <= 13'd0 ;
  • else
  • pcnt <= pcnt + 1'b1 ;
  • else
  • pcnt <= 13'd0;
  • end
  • //rx 接收数据
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • rx_reg <= 8'b0;
  • else if(pcnt == BPS_CNT/2 -1'b1)
  • case(rx_cnt)
  • 4'd1: rx_reg[0] <= uart_rx ;
  • 4'd2: rx_reg[1] <= uart_rx ;
  • 4'd3: rx_reg[2] <= uart_rx ;
  • 4'd4: rx_reg[3] <= uart_rx ;
  • 4'd5: rx_reg[4] <= uart_rx ;
  • 4'd6: rx_reg[5] <= uart_rx ;
  • 4'd7: rx_reg[6] <= uart_rx ;
  • 4'd8: rx_reg[7] <= uart_rx ;
  • default : ;
  • endcase
  • else ;
  • end
  • assign dataout_vld = (rx_cnt == 4'd9) ? 1'b1 : 1'b0;
  • assign dataout = rx_reg ;
  • endmodule

 

发端与收端是类似的,就是一个是发数据,一个是收数据

  • `timescale 1ns / 1ns
  • module uarttx(
  • input clk,
  • input rst_n,
  • //uart interface
  • output uart_tx,
  • //user interface
  • input datain_vld,
  • input [7:0] datain,
  • output uart_ack
  • );
  • //localparam
  • localparam BPS = 9600 ;
  • localparam BPS_CNT = 2500 ; // T/BPS
  • //reg define
  • reg [12:0] pcnt ;
  • reg [2:0] tx_dly ;
  • reg [3:0] tx_cnt ;
  • reg [7:0] tx_reg ;
  • reg tx_en ;
  • reg uart_tx ;
  • //wire define
  • wire tx_rising ;
  • assign tx_rising = ~tx_dly[2] & tx_dly[1] ;
  • //打拍 同步
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • tx_dly <= 3'b000 ;
  • else
  • tx_dly <= {tx_dly[1:0], datain_vld} ;
  • end
  • //接收到起始信号,开始标志
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • tx_en <= 1'b0 ;
  • else if(tx_rising == 1'b1)
  • tx_en <= 1'b1 ;
  • else if(tx_cnt == 4'd9)
  • tx_en <= 1'b0 ;
  • else ;
  • end
  • //rx 接收字节计数
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • tx_cnt <= 4'd0;
  • else if(tx_en == 1'b1)
  • if(pcnt == BPS_CNT -1'b1)
  • tx_cnt <= tx_cnt + 1'b1;
  • else;
  • else
  • tx_cnt <= 4'd0;
  • end
  • //PBS CNT
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • pcnt <= 13'd0;
  • else if(tx_en == 1'b1)
  • if(pcnt == BPS_CNT -1'b1)
  • pcnt <= 13'd0 ;
  • else
  • pcnt <= pcnt + 1'b1 ;
  • else
  • pcnt <= 13'd0;
  • end
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • tx_reg <= 8'b0;
  • else if(tx_en == 1'b1)
  • // tx_reg <= 8'h55;
  • tx_reg <= datain;
  • else ;
  • end
  • //tx 接收数据
  • always @(posedge clk or negedge rst_n)
  • begin
  • if(rst_n == 1'b0)
  • uart_tx <= 1'b1;
  • else if(tx_en == 1'b1)
  • case(tx_cnt)
  • 4'd0: uart_tx <= 1'b0 ;
  • 4'd1: uart_tx <= tx_reg[0] ;
  • 4'd2: uart_tx <= tx_reg[1] ;
  • 4'd3: uart_tx <= tx_reg[2] ;
  • 4'd4: uart_tx <= tx_reg[3] ;
  • 4'd5: uart_tx <= tx_reg[4] ;
  • 4'd6: uart_tx <= tx_reg[5] ;
  • 4'd7: uart_tx <= tx_reg[6] ;
  • 4'd8: uart_tx <= tx_reg[7] ;
  • 4'd9: uart_tx <= 1'b1 ;
  • default : ;
  • endcase
  • else ;
  • end
  • assign uart_ack = (tx_en == 1'b1) ? 1'b0 : 1'b1;
  • assign dataout = tx_reg ;
  • endmodule

 其实TX与RX两者之间的波特率用一个module表示更加好,方便后期修改不同速率的波特率,实现波特率可调

再就是实现top文件,关联tx,rx,实现收与发,因为还没有实现其他的,就直接收到数据后字节发送

  • wire [7:0] datain ;
  • wire datain_vld;
  • wire [7:0] dataout ;
  • wire dataout_vld ;
  • assign datain = dataout ;
  • assign datain_vld = dataout_vld ;
  • uarttx u_uart_tx(
  • .clk ( CLK_24M ),
  • .rst_n ( rst_n ),
  • .uart_tx ( UART_TX ),
  • .datain_vld ( datain_vld ),
  • .datain ( datain ),
  • .uart_ack ( uart_ack )
  • );
  • uartrx u_uart_rx(
  • .clk ( CLK_24M ),
  • .rst_n ( rst_n ),
  • .uart_rx ( UART_RX ),
  • .dataout_vld ( dataout_vld),
  • .dataout ( dataout )
  • );

不仿真上板就是刷流氓,那用modelsim功能仿真,查看基本收发功能是否正常。

简单查看收发的数据位都是满足要求的,然后直接上板测试性能。

用串口通信工具虚拟接口链接,不停发送数据“Anlogic fpga”,查看串口工具接收的数据是否正常,

通过验证,串口通信工具基本功能正常。

后续增加UART转localbus协议,实现通过串口下发指令实现单板各芯片控制,也方便后期调试。

 

最新回复

串口通信工具基本功能测试如连接正常设置正确一般都能正常,接下来期待楼主的其他测试   详情 回复 发表于 2022-5-6 07:53
点赞 关注
 
 

回复
举报

7020

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

串口通信工具基本功能测试如连接正常设置正确一般都能正常,接下来期待楼主的其他测试

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
有奖探索 | 和村田一起,深挖 GNSS 开发!
活动时间:即日起-5月11日
活动奖励:智能手环、螺丝刀套装、双肩包

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 4

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表