1965|1

81

帖子

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
点赞 关注
 
 

回复
举报

6828

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

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

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

北京市海淀区中关村大街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
快速回复 返回顶部 返回列表