RS232串口通信(UART的发送机部分)
置顶
新人博主,创作不易,波形图手绘,请给个点赞关注吧,非常感谢!
串口的基本简介
串口的基本知识介绍在上一章已经讲过了。
具体链接:RS232串口通信(UART的接收部分)_笙歌丶的博客-优快云博客
串口的发送模块
发送模块框图
信号说明
信号 | 位宽 | 类型 | 信号说明 |
---|---|---|---|
sys_clk | 1bit | input | 工作频率,系统时钟50Mhz |
sys_rst_n | 1bit | input | 系统复位信号 |
Pi_data | 8bit | input | 要发送的8bit数据 |
Pi_data_flag | 1bit | input | 要发送的8bit数据的有效标志信号 |
Tx | 1bit | output | 串口发送信号 |
波形设计及其波形
工作使能信号
work_en信号的作用:当work_en=1的时候,数据开始传输(开始发送)。从前面的框图中可以看出,输入信号中有一个Pi_data_flag信号,这个信号是发送有效标志信号,所以当这个信号为1时,就代表可以开始发送了,此时,work_en=1。至于work_en什么时候拉低,后面会有说明。
//work_en:接收数据工作使能信号
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
work_en <= 1'b0;
else if(pi_flag == 1'b1)
work_en <= 1'b1;
else if((bit_flag == 1'b1) && (bit_cnt == 4'd9))
work_en <= 1'b0;
波特率计数信号
这个信号在前面接收部分说明过,我们使用的时9600bps的波特率,系统时钟为50Mhz,得出1bit需要的5208个时钟周期(发送1bit的时间)。
//baud_cnt:波特率计数器计数,从0计数到BAUD_CNT_MAX - 1
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
baud_cnt <= 13'b0;
else if((baud_cnt == BAUD_CNT_MAX - 1) || (work_en == 1'b0))
baud_cnt <= 13'b0;
else if(work_en == 1'b1)
baud_cnt <= baud_cnt + 1'b1;
位标志信号
band_cnt数据在0和5027这两个点的时候是不太稳定的,所以我采用的是中间的点作为bit_flag的高电平的开始。
//bit_flag:当baud_cnt计数器计数到1时让bit_flag拉高一个时钟的高电平
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
bit_flag <= 1'b0;
else if(baud_cnt == 13'd1)
bit_flag <= 1'b1;
else
bit_flag <= 1'b0;
数据bit传输个数
通过数据帧,可以看出,完整的传输一个数据除了8位的数据位,还需要一个空闲状态和一个起始位,总共为10个状态。
我们前面说过发送1bit需要5208个周期,当计数值达到5208个周期时,bit_flag=1,所以当bit_flag=1的时候,bit_cnt+1,当bit_cnt=10,并且,bit_flag=1时,即一个8位数据发送完成。此时,work_en信号置为低。
//bit_cnt:数据位数个数计数,10个有效数据(含起始位和停止位)到来后计数器清零
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
bit_cnt <= 4'b0;
else if((bit_flag == 1'b1) && (bit_cnt == 4'd9))
bit_cnt <= 4'b0;
else if((bit_flag == 1'b1) && (work_en == 1'b1))
bit_cnt <= bit_cnt + 1'b1;
数据输出
每次bit_flag=1时,tx发送一位,发送的数据来源于pi_data[7:0]中的一位,从低位到高位传输
//tx:输出数据在满足rs232协议(起始位为0,停止位为1)的情况下一位一位输出
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
tx <= 1'b1; //空闲状态时为高电平
else if(bit_flag == 1'b1)
case(bit_cnt)
0 : tx <= 1'b0;
1 : tx <= pi_data[0];
2 : tx <= pi_data[1];
3 : tx <= pi_data[2];
4 : tx <= pi_data[3];
5 : tx <= pi_data[4];
6 : tx <= pi_data[5];
7 : tx <= pi_data[6];
8 : tx <= pi_data[7];
9 : tx <= 1'b1;
default : tx <= 1'b1;
endcase
整体波形图
总结
若有啥疑问和想要完整的工程文件请私聊我 QQ:330965825 ,谢谢!