可编程逻辑
串口的全程为串行接口,也称为串行通信接口,是采用串行通信方式的扩展接口。与串口对应的并行接口,例如高速AD和DA,
这些都是用的并行接口,而且在编程也简单一些。
串口有一下特点:
(1)通信线路简单,只要一对传输线就可以实现双向通信。
(2)布线简单,成本低。
(3)通信距离长,可以实现数米到数千米的通信距离。
(4)传输速率慢。
常见的串口速率如4800 , 9600 , 115200bps,代表每秒钟发送多少bit数据,例如9600bps就代表1秒内发送9600bit数据。

串口协议 :协议比较简单,一般都是10位数据,1个起始位 低电平 ,然后八个数据位,低位在前,一个奇偶校验位,平时
一般不用,最后是一位停止位高电平,这样一帧数据发送结束。
下面介绍一下我的程序框架:

整体框架分为两个部分:一个是串口驱动部分 另一个是串口数据控制部分。串口驱动部分负责串口驱动和波特率的选择,串口数据控制模块
负责控制数据内容的控制和发送速度的控制。

从上面时序图可以看出,每10ms发送一帧数据,这里data_en负责波特率驱动使能,uart_tx_end有两个功能,一个是关闭data_en使能,另一个是给10ms计数器
清零。
/*-----------------------------------------------------------------------
Date : 2017-09-03
Description : Design for uart_driver.
-----------------------------------------------------------------------*/
module uart_tx_driver
(
//global clock
input clk , //system clock
input rst_n , //sync reset
//uart interface
output reg uart_tx ,
//user interface
input [1:0] bps_select , //波特率选择
input [7:0] uart_data ,
input data_en , //发送数据使能
output reg uart_tx_end
);
//--------------------------------
//Funtion : 参数定义
parameter BPS_4800 = 14'd10417 ,
BPS_9600 = 14'd5208 ,
BPS_115200 = 14'd434 ;
reg [13:0] cnt_bps_clk ;
reg [13:0] bps ;
reg bps_clk_en ; //bps使能时钟
reg [3:0] bps_cnt ;
wire [13:0] BPS_CLK_V = bps >> 1 ;
//--------------------------------
//Funtion : 波特率选择
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
bps <= 1'd0;
else if(bps_select == 2'd0)
bps <= BPS_115200;
else if(bps_select == 2'd1)
bps <= BPS_9600;
else
bps <= BPS_4800;
end
//--------------------------------
//Funtion : 波特率计数
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_bps_clk <= 1'd0;
else if(cnt_bps_clk >= bps - 1 && data_en == 1'b0)
cnt_bps_clk <= 1'd0;
else
cnt_bps_clk <= cnt_bps_clk + 1'd1;
end
//--------------------------------
//Funtion : 波特率使能时钟
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
bps_clk_en <= 1'd0;
else if(cnt_bps_clk == BPS_CLK_V - 1)
bps_clk_en <= 1'd1;
else
bps_clk_en <= 1'd0;
end
//--------------------------------
//Funtion : 波特率帧计数
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
bps_cnt <= 1'd0;
else if(bps_cnt == 11)
bps_cnt <= 1'd0;
else if(bps_clk_en)
bps_cnt <= bps_cnt + 1'd1;
end
//--------------------------------
//Funtion : uart_tx_end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
uart_tx_end <= 1'd0;
else if(bps_cnt == 11)
uart_tx_end <= 1'd1;
else
uart_tx_end <= 1'd0;
end
//--------------------------------
//Funtion : 发送数据
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
uart_tx <= 1'd1;
else case(bps_cnt)
4'd0 : uart_tx <= 1'd1;
4'd1 : uart_tx <= 1'd0; //begin
4'd2 : uart_tx <= uart_data[0];//data
4'd3 : uart_tx <= uart_data[1];
4'd4 : uart_tx <= uart_data[2];
4'd5 : uart_tx <= uart_data[3];
4'd6 : uart_tx <= uart_data[4];
4'd7 : uart_tx <= uart_data[5];
4'd8 : uart_tx <= uart_data[6];
4'd9 : uart_tx <= uart_data[7];
4'd10 : uart_tx <= 1; //stop
default : uart_tx <= 1;
endcase
end
endmodule
/*-----------------------------------------------------------------------
Date : 2017-XX-XX
Description : Design for .
-----------------------------------------------------------------------*/
module uart_tx_control
(
//global clock
input clk , //system clock
input rst_n , //sync reset
//user interface
output reg [7:0] uart_data ,
output reg data_en ,
input uart_tx_end
);
//--------------------------------
//Funtion : 参数定义
parameter DELAY_10MS = 500_000 ;
reg [31:0] cnt_10ms ;
wire delay_10ms_done ;
//data define
reg [31:0] cnt_1s;
//--------------------------------
//Funtion : cnt_10ms
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_10ms <= 1'd0;
else if(cnt_10ms == DELAY_10MS - 1 && uart_tx_end == 1'd1)
cnt_10ms <= 1'd0;
else
cnt_10ms <= cnt_10ms + 1'd1;
end
assign delay_10ms_done = (cnt_10ms == DELAY_10MS - 1) ? 1'd1 : 1'd0;
//--------------------------------
//Funtion : data_en
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
data_en <= 1'd0;
else if(delay_10ms_done)
data_en <= 1'd1;
else if(uart_tx_end)
data_en <= 1'd0;
end
///////////////////////数据测试/////////////////////////////
//--------------------------------
//Funtion : cnt_1s
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_1s <= 1'd0;
else if(cnt_1s == 49_999_999)
cnt_1s <= 1'd0;
else
cnt_1s <= cnt_1s + 1'd1;
end
//--------------------------------
//Funtion : uart_data
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
uart_data <= 1'd0;
else if(uart_data >= 10)
uart_data <= 1'd0;
else if(cnt_1s == 49_999_999)
uart_data <= uart_data + 1'd1;
end
endmodule
编辑:黄飞
全部0条评论
快来发表一下你的评论吧 !