UARTVerilogHDL文档格式.docx
- 文档编号:21897805
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:14
- 大小:135.17KB
UARTVerilogHDL文档格式.docx
《UARTVerilogHDL文档格式.docx》由会员分享,可在线阅读,更多相关《UARTVerilogHDL文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
串口模块组成
2.1波特率发生模块
UART的接收和发送是按照相同的波特率进行收发的(当然也可以实现成对的不同波特率进行收发)。
波特率是通过对硬件时钟分频得到。
波特率发生器产生的时钟频率不是波特率时钟频率,而是波特率时钟频率的8倍或者16倍,目的是为在接收时进行精确地采样,送出异步的串行数据。
根据给定的晶振时钟和要求的波特率算出波特率分频数,即假定当前按照9600bps进行收发,那么波特率发生器输出的时钟频率应为9600×
8/16Hz,当然这也是可以改变的。
本实验中,波特率发生模块提供多种时钟,以配合发送和接收模块的工作。
硬件提供的时钟为40MHz,用计数器的方式生成所需要的各种时钟,这个值的计算原则就是40000000/(N*9600),其中N是想要得到的时钟为波特率(本实验被9600)的N倍。
如果希望输出9600Hz的时钟,那么这个值就是40000000/9600≈4160。
时钟产生模块代码如下:
always@(posedgeclk)
begin
if(out8==12'
d260)
out8<
=0;
baud8x<
=!
baud8x;
//产生9600*8Hz的时钟
end
else
=out8+1;
波特率发生模块仿真波形
2.2发送模块
发送部分的用途是将准备输出的并行数据,按照基本帧格式,转为txd信号串行输出,这里的串行化时的时钟信号使用对应要求的波特率的本地时钟即可。
本实验为简化操作,数据格式为1位起始位+8位数据位+1位停止位的格式。
并且发送数据采用寄存器中预存数据。
当按钮Key_input按下,首先进行延迟计数,避免信号是毛刺产生的。
延时结束后,如果Key_input仍为按下状态,则判定为发送数据,将移位使能shift_en置为1。
在波特率时钟下,发送起始位,再依次移位发送预存的8位数据,然后发送停止位。
期间发送状态由2个计数器协调。
由计数器当前值判断发送是否结束,如果结束则将发送缓冲区置1然后送给发送端口rxd。
这样就实现了一帧数据的发送。
最后将各寄存器和计数器清零,等待下次发送。
部分发送代码如下:
if(txd_state<
4'
b1001)//发送状态,标识发送到该帧数据//的第几位
txd_state<
=txd_state+1;
if(txd_buf_state<
=3'
b111&
&
txd_state==4'
b1001)
txd_buf_state<
=txd_buf_state+1;
//若发送完该帧数据第十位,则发送下一帧数据
=txd_buf_state;
//否则保持该帧数据发送状态
发送模块仿真波形
(由于按硬件要求设计,延迟时间太长,此图为将延时计数值改为适中后的仿真波形)
2.3接收模块
UART接收部分接收rxd串行信号,并将其转化为并行数据。
串行数据帧和接收时钟是异步的,发送来的数据由逻辑1变为逻辑0可以视为一个数据帧的开始。
接收器先要捕捉起始位,确定rxd输入由1到0,延时2-3个八倍波特率时钟,判断确定为零,在波特率时钟控制下开始接收结下来的8位数据,并依次移位存储到接收缓存中。
数据位接收完成后,判断第9位是否为高电平,确定接收结束,将接收缓存中数据送给数码管,同时数码管使能en置1。
这样就完成了一帧数据的接收。
最后将各缓存和计数器置清零,接收使能置0等待下次接收。
部分接收代码如下:
第一小段:
if(shift_reg>
=4'
b0001&
shift_reg<
b1001)
shift_data[0]<
=rxd2;
//移位操作
shift_data[7:
1]<
=shift_data[6:
0];
第二小段:
=shift_reg+1;
if(shift_reg==4'
b1000)
rxd_buf<
=shift_data;
//移位计数到8,则将移位数据保存到接收缓存
//移位计数到9,将计数器清零,进行下次移位计数
end
接收模块仿真波形
(为简化仿真,rxd信号采用周期信号,故seg_data无输出)
三、小结
通过波特率发生器、发送器和接收器模块的设计与仿真,能较容易地实现通用异步收发器总模块,对于收发的数据帧和发生的波特率时钟频率能较灵活地改变,而且硬件实现不需要很多资源,尤其能较灵活地嵌入到FPGA/CPLD的开发中。
在EDA技术平台上进行设计、仿真与实现具有较好的优越性。
附录
顶层模块代码
`include"
baud.v"
send.v"
receive.v"
moduleUART(clk,rst,rxd,txd,en,seg_data,key_input);
inputclk,rst,rxd,key_input;
outputen,txd;
output[7:
0]seg_data;
wirebaud1x,baud4x,baud8x;
baudb1(baud1x,baud4x,baud8x,clk);
receiver1(clk,baud4x,baud8x,rxd,en,seg_data,rst);
sends1(clk,baud1x,rst,txd,key_input);
endmodule
波特率发生模块代码
modulebaud(baud1x,baud4x,baud8x,clk);
inputclk;
outputbaud1x,baud4x,baud8x;
regbaud1x,baud4x,baud8x;
reg[13:
1]out1;
reg[12:
1]out4;
1]out8;
always@(posedgeclk)//8x波特率时钟
always@(posedgeclk)//4x波特率时钟
if(out4==12'
d2080)
out4<
baud4x<
baud4x;
=out4+1;
always@(posedgeclk)//波特率时钟
if(out1==13'
d4160)
out1<
baud1x<
baud1x;
=out1+1;
发送模块代码
modulesend(clk,baud1x,rst,txd,key_input);
inputbaud1x,rst,key_input,clk;
outputtxd;
reg[20:
1]delay;
regtxd_reg;
//发送缓存
regtxd_en;
//发送使能
regtxd;
reg[2:
0]txd_buf_state;
//发送缓存状态计数器
reg[3:
0]txd_state;
//发送状态计数器
reg[7:
0]txd_buf;
//数据缓存
txd<
=txd_reg;
always@(posedgeclkornegedgerst)//延时模块
if(!
rst)
delay<
=20'
b0;
if(!
key_input)
begin
delay<
=delay+1;
if(delay==20'
d800000)//20ms延时
end
else
always@(posedgeclkornegedgerst)//发送使能判断
txd_en<
begin
if(delay==20'
d800000)//按键延时20ms后使能位置1
=1;
if(txd_buf_state==3'
//发送结束后使能位置0
end
always@(posedgebaud1xornegedgerst)//发送单元
begin
txd_buf_state<
txd_reg<
txd_state<
txd_buf<
=8'
if(txd_en)
begin
if(txd_state<
b1001)//发送状态,记录发送到该帧数据的第几位
txd_state<
else
end
if(txd_buf_state<
txd_buf_state<
//若发送完该帧数据第十位,则发送下一帧数据
//否则保持该帧数据发送状态
txd_buf_state<
txd_reg<
txd_state<
txd_buf<
case(txd_state)//由发送状态判断将该帧数据第几位送给发送缓存
d0:
txd_reg<
d1:
=txd_buf[0];
d2:
=txd_buf[1];
d3:
=txd_buf[2];
d4:
=txd_buf[3];
d5:
=txd_buf[4];
d6:
=txd_buf[5];
d7:
=txd_buf[6];
d8:
=txd_buf[7];
d9:
b1;
default:
endcase
case(txd_buf_state)//由发送缓存状态判断将发送第几帧数据
3'
txd_buf<
b01110111;
b01100101;
b01101100;
b01100011;
b01101111;
b01101101;
endcase
接收模块代码
modulereceive(clk,baud4x,baud8x,rxd,en,seg_data,rst);
inputbaud4x,baud8x,rxd,rst,clk;
outputen;
regrxd1,rxd2,shift_en,en;
0]shift_reg;
//移位计数器
0]shift_data,seg_data,rxd_buf;
//移位缓存、发送端、接受缓存
always@(posedgebaud8x)
rxd1<
=rxd;
rxd2<
=rxd1;
//rxd1和rxd2分别代表rxd中相邻两位,用来判断下降沿
always@(posedgebaud8x)//移位使能判断
rxd1&
rxd2)//开始位到来,移位使能置1
shift_en<
en<
else
if(shift_reg==4'
b1001)//接收结束,移位使能置0
always@(posedgebaud4xornegedgerst)
shift_data<
if(shift_reg>
shift_data[0]<
//移位操作
shift_data[7:
shift_data<
always@(negedgebaud4x)
shift_en)
shift_reg<
rxd_buf<
//移位计数到8,则将移位数据保存到接收缓存
//移位计数到9,将计数器清零,进行下次移位计数
case(rxd_buf)//将接收到的数据译码后送数码管
8'
b00110000:
seg_data=8'
b00000011;
b00110001:
b10011111;
b00110010:
b00100101;
b00110011:
b00001101;
b00110100:
b10011001;
b00110101:
b01001001;
b00110110:
b01000001;
b00110111:
b00011111;
b00111000:
b00000001;
b01000001:
b00011001;
b01000010:
b00010001;
b01000011:
b11000001;
b01000100:
b01000101:
b10000101;
b01000110:
b01100001;
b01000111:
b01110001;
b11111111;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- UARTVerilogHDL