uart原理与verilog实现

1. UART介绍

UART全称为通用异步接收-发送器,嵌入式中说的串口,一般是指UART口。
在传输的过程中,UART传输端将字节数据以串行的方式逐个比特的发送出去,UART接收端诸葛比特地接收数据,然后将其重新组合为字节数据。
常见的传输数据格式如图所示:
在这里插入图片描述

  • 在空闲时,UART输出保持高电平(在早期的发展历史中,电信传输用高电平表示线路没有被破坏掉),如果是低电平,就无法判定。
  • UART在传输一个字节时,应发送一个低电平表示起始位。
  • 在发送起始位之后,通常从低位到高位的顺序诸位传输一个字节的数据。(某些UART会以相反顺序进行传输)
  • 传输完一个字节之后,可选地会传输一位或者多位奇偶校验位。
  • 最后则是一位高电平停止位。

1.1 波特率

波特率是衡量串口传输速度的主要标准,与比特率区分开来。

  • 在信息传输通道中,携带数据信号的单元称为码元(脉冲),每秒通过信道传输的码元叫做码元传输速率,简称波特率。波特率是传输通道频宽的指标。单位为Baud(波特)
  • 每秒通过信道传输的信息称为位传输速率,简称比特率。比特率表示有效数据的传输速率。单位为bit/s(位/秒)
  • 两者的关系:比特率=波特率*单个调制状态对应的二进制位数。

常见的串口通信波特率有2400 、9600、115200等,发送和接收波特率必须保持一致才能正确通信。波特率是指1 秒最大传输的数据位数,包括起始位、数据位、校验位、停止位。
如果波特率设定为9600,那么一个数据位的传输时间长度是1/9600秒。

2.RISCV-UART 特性

E203支持两个串口模块,分别位UART0和UART1。这两个模块基本相同。

  • 支持发送和接受数据能力。
  • 支持8-n-1和8-n-2的数据传输格式:即8位数据位,没有奇偶校验位,一位起始位和1(2)位停止位。
  • 支持8个深度的发送和接受FIFO缓存,同时支持软件可编程的阈值。
  • 在接受端(Rx),采用 16倍波特率的采样频率采样接受数据线,并且对于前后连续三次的采样结果进行判断,选择最多数的数值作为采样结果。

这一段是照搬《RISC-V架构与嵌入式快速开发入门》中关于UART的介绍,因蜂鸟E203的UART是有别的语言转到Verilog的,里面混杂了巨量的寄存器,我实在看不懂,理不清,就直接照搬了。

3.ASCII

ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符.
UART串口通信在传输字母时,采用ASCII编码将其转化成01信号进行传输。

4. 程序设计

顶层模块


module uart_test(
	//Differential system clocks
	input                        sys_clk_p,
	input                        sys_clk_n,
	input                        rst_n,
	input                        uart_rx,
	output                       uart_tx
);

parameter                        CLK_FRE = 200;//Mhz
localparam                       IDLE =  0;
localparam                       SEND =  1;   //send HELLO ALINX\r\n
localparam                       WAIT =  2;   //wait 1 second and send uart received data
reg[7:0]                         tx_data;
reg[7:0]                         tx_str;
reg                              tx_data_valid;
wire                             tx_data_ready;
reg[7:0]                         tx_cnt;
wire[7:0]                        rx_data;
wire                             rx_data_valid;
wire                             rx_data_ready;
reg[31:0]                        wait_cnt;
reg[3:0]                         state;
wire                             sys_clk;

IBUFDS sys_clk_ibufgds
(
	.O                          (sys_clk                  ),
	.I                          (sys_clk_p                ),
	.IB                         (sys_clk_n                )
);

assign rx_data_ready = 1'b1;//always can receive data,
							//if HELLO ALINX\r\n is being sent, the received data is discarded

always@(posedge sys_clk or negedge rst_n)
begin
	if(rst_n == 1'b0)
	begin
		wait_cnt <= 32'd0;
		tx_data <= 8'd0;
		state <= IDLE;
		tx_cnt <= 8'd0;
		tx_data_valid <= 1'b0;
	end
	else
	case(state)
		IDLE:
			state <= SEND;
		SEND:
		begin
			wait_cnt <= 32'd0;
			tx_data <= tx_str;

			if(tx_data_valid == 1'b1 && tx_data_ready == 1'b1 && tx_cnt < 8'd12)//Send 12 bytes data
			begin
				tx_cnt <= tx_cnt + 8'd1; //Send data counter
			end
			else if(tx_data_valid && tx_data_ready)//last byte sent is complete
			begin
				tx_cnt <= 8'd0;
				tx_data_valid <= 1'b0;
				state <= WAIT;
			end
			else if(~tx_data_valid)
			begin
				tx_data_valid <= 1'b1;
			end
		end
		WAIT:
		begin
			wait_cnt <= wait_cnt + 32'd1;

			if(rx_data_valid == 1'b1
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值