【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十二:串口模块① — 发送
实验十二:串口模块① — 发送
串口固然是典型的实验,想必许多同学已经作烂,不过笔者还要循例介绍一下。我们知道串口有发送与接收之分,实验十二的实验目的就是实现串口发送,然而不同的是 ... 笔者会用另一种思路去实现串口发送。
图12.1 PS/2发送时序与串口发送时序。
如图12.1所示,串口发送时序相较PS/2发送时序,串口发送时序就像断了翅膀的小鸟般,没有时钟信号控制整个传输协议。除此之外,串口发送时序与PS/2发送时序近似的地方也非常惊人 ... 默认下,一帧PS/2数据有11位,对此一帧串口数据也有11位,其中位分配如表12.1所示:
表12.1 一帧串口数据的位分配。
位分配 |
位定义 |
[0] |
起始位 |
[8:1] |
数据位 |
[9] |
校验位 |
[10] |
停止位 |
如表12.1所示,[0]为拉低的起始位,[8:1]为任意填充的数据位,[9]为任意填充的校验位,[10]为拉高的停止位。
图12.2 FPGA发送一帧串口数据(无视波特率)。
假设我们无视波特率,并且利用FPGA发送一帧串口数据的话 ... 如图12.2所示,一帧有11位的串口数据,一共使用了11个上升沿发送出去,为此Verilog则可以这样表示,结果如代码12.1所示:
reg [10:0]D1;
always @(posedge CLOCK)
case(i)
0,1,2,3,4,5,6,7,8,9,10:
begin TXD <= D1[i]; i <= i + 1'b1; end
......
endcase
代码12.1
如代码12.1所示,寄存器D为11位宽的寄存器,并且驱动TXD输出口,期间步骤0~11公按照i的位寻址,将D1的内容逐个发送出去。
虽然串口传输协议极为类似PS/2传输协议,但是串口传输协议也有区别的地方。其一串口传输协议有波特率的概念,而且串口协议有各种各样的波特率,常用的波特率有9600 bps或者115200 bps,波特率最低为 110 bps,最高为 256000 bps(目前暂定)。所谓波特率就是一秒内,串口可以发送多少位数据,此外波特率也是一位数据的周期,或者说是一位数据的保持时间,就拿115200 bps为例:
1/115200 = 8.68E-6
115200波特率的一位数据周期为 8.68us,如果用50Mhz 的时钟频率去量化的话:
( 1/115200 ) / (1/50E+6) = 8.68E-6 / 20E-9
= 434
图12.3 FPGA发送一帧串口数据(考虑波特率)。
如果图12.3考虑115200的波特率,结果如图12.3所示,每一位数据都保持434个时钟
,为此Verilog可以这样表示,如代码12.2所示:
reg [10:0]D1;
reg [8:0]C1;
always @(posedge CLOCK)
case(i)
0,1,2,3,4,5,6,7,8,9,10:
if( C1 == 9’d434 -1 ) begin C1 <= 9’d0; i <= i + 1’b1; end
else begin TXD <= D1[i]; C1 <= C1 + 1'b1; end
......
endcase
代码12.1
如代码12.1所示,步骤0~10不再保持一个时钟,换之每个步骤都保持434个时钟,因此每位TXD的发送数据也保持 8.68us。
除此此外,串口传输协议不仅可以自定义波特率,串口传输协议也可以自定义一帧数据的位宽,自定义内容如表12.2所示:
表12.2 自定义一帧数据。
自定义数据位 |
自定义内容 |
数据位 |
5~9 |
校验位 |
有/无 |
停止位 |
1~2 |
如表12.2所示,可以自定义的数据其中便包含数据位,默认下为1字节,自定义内容则是5~9位,校验位也可以设置为有或者无(默认下是有),停止位也可以增至2位(默认下是1位)。不管怎么样,表12.2是比较官方的自定义内容 ... 只要读者欢喜,任何畸形的自定义内容也有可能实现。
理解完毕以后,我们便可以开始建模了。
图12.4 实验十二的建模图。
图12.4是实验十二的建模图,不过内容较为寒酸 ... 组合模块 tx_demo 内容包括一段核心操作,还有一只TX功能模块。核心操作负责TX功能模块的调用,亦即控制沟通信号还有Data的输入。TX功能模块被使能以后,便将iData经由TXD输出端发送出去
,完后便反馈完成信号以示一次性的操作已经完毕。
tx_funcmod.v
图12.5 TX功能模块的建模图。
如图12.5所示,该模块的左方有问答信号,还有8位的iData,至于右方则是 TXD 顶层信号。此外,一帧数据的波特率为 115200 bps。
1. module tx_funcmod
2. (
3. input CLOCK, RESET,
4. output TXD,
5. input iCall,
6. output oDone,
7. input [7:0]iData
8. );
9. parameter B115K2 = 9'd434; // formula : ( 1/115200 )/( 1/50E+6 )
以上内容为相关的出入端声明,第9行则是波特率为115200的常量声明。
11. reg [3:0]i;
12. reg [8:0]C1;
13. reg [10:0]D1;
14. reg rTXD;
15. reg isDone;
16.
17. always @( posedge CLOCK or negedge RESET )
18. if( !RESET )
19. begin
20. i <= 4'd0;
21. C1 <= 9'd0;
22. D1 <= 11'd0;
23. rTXD <= 1'b1;
24. isDone <= 1'b0;
25. end
以上内容为相关的寄存器声明以及复位操作。
26. else if( iCall )
27. case( i )
28.
29. 0:
30. begin D1 <= { 2'b11 , iData , 1'b0 }; i <= i + 1'b1; end
31.
32. 1,2,3,4,5,6,7,8,9,10,11:
33. if( C1 == B115K2 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
34. else begin rTXD <= D1[i - 1]; C1 <= C1 + 1'b1; end
35.
36. 12:
37. begin isDone <= 1'b1; i <= i + 1'b1; end
38.
39. 13:
40. begin isDone <= 1'b0; i <= 4'd0; end
41.
42. endcase
43.
以上内容为部分核心操作。第26行的if( iCall ) 表示该模块不使能就不工作。步骤0用来准备发送数据,其中 2’b11 是停止位与校验位(随便填),1’b0则是起始位。步骤1~11用来发送一帧数据。步骤12~13用来反馈完成信号并返回步骤。
44. assign TXD = rTXD;
45. assign oDone = isDone;
46.
47. endmodule
以上内容为驱动输出的声明。
tx_demo.v
连线部署直接看代码比较具体一点。
1. module tx_demo
2. (
3. input CLOCK, RESET,
4. output TXD
5. );
6. wire DoneU1;
以上内容是相关的出入端声明。
8. tx_funcmod U1
9. (
10. .CLOCK( CLOCK ),
11. .RESET( RESET ),
12. .TXD( TXD ),
13. .iCall( isTX ),
14. .oDone( DoneU1 ),
15. .iData( D1 )
16. );
以上内容是TX功能模块的实例化,其中isCall由isTX驱动,iData由D驱动。
18. reg [3:0]i;
19. reg [7:0]D1;
20. reg isTX;
21.
22. always @ ( posedge CLOCK or negedge RESET )
23. if( !RESET )
24. begin
25. i <= 4'd0;
26. D1 <= 8'd0;
27. isTX <= 1'b0;
28. end
以上内容是相关的寄存器声明,第23~28行则是这些寄存器的复位操作。
29. else
30. case( i )
31.
32. 0:
33. if( DoneU1 ) begin isTX <= 1'b0; i <= i + 1'b1; end
34. else begin isTX <= 1'b1; D1 <= 8'hA1; end
35.
36. 1:
37. if( DoneU1 ) begin isTX <= 1'b0; i <= i + 1'b1; end
38. else begin isTX <= 1'b1; D1 <= 8'hA2; end
39.
40. 2:
41. if( DoneU1 ) begin isTX <= 1'b0; i <= i + 1'b1; end
42. else begin isTX <= 1'b1; D1 <= 8'hA3; end
43.
44. 3: // Stop
45. i <= i;
46.
47. endcase
48.
49. endmodule
以上内容是核心操作的内容,步骤0发送数据 8’hA1,步骤1发送数据8’hA2,步骤2发送数据 8’hA3。
编译完毕便下载程序,并且将串口线连接至电脑与开发板。打开串口调试助手,波特率设为115200,数据位为8,校验位随便,停止位为1位 ... 事后,显示方式设置为HEX(十六进制)。当程序下载完毕以后,串口调试助手便会出现 A1,A2与A3。
细节一: 完整的个体模块
实验十二的TX功能模块已经是完整的个体,可以直接拿来调用。
【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十二:串口模块① — 发送的更多相关文章
- [黑金原创教程] FPGA那些事儿《设计篇 III》- 图像处理前夕·再续
简介 一本为入门图像处理的入门书,另外还教你徒手搭建平台(片上系统),内容请看目录. 注意 为了达到最好的实验的结果,请准备以下硬件. AX301开发板, OV7670摄像模块, VGA接口显示器, ...
- [黑金原创教程] FPGA那些事儿《设计篇 II》- 图像处理前夕·续
简介 一本为入门图像处理的入门书,另外还教你徒手搭建平台(片上系统),内容请看目录. 注意 为了达到最好的实验的结果,请准备以下硬件. AX301开发板, OV7670摄像模块, VGA接口显示器, ...
- [黑金原创教程] FPGA那些事儿《设计篇 I》- 图像处理前夕
简介 一本为入门图像处理的入门书,另外还教你徒手搭建平台(片上系统),内容请看目录. 注意 为了达到最好的实验的结果,请准备以下硬件. AX301开发板, OV7670摄像模块, VGA接口显示器, ...
- [黑金原创教程] FPGA那些事儿《数学篇》- CORDIC 算法
简介 一本为完善<设计篇>的书,教你CORDIC算法以及定点数等,内容请看目录. 贴士 这本教程难度略高,请先用<时序篇>垫底. 目录 Experiment 01:认识CORD ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】原创教程连载导读【连载完成,共二十九章】
前言: 无数昼夜的来回轮替以后,这本<驱动篇I>终于编辑完毕了,笔者真的感动到连鼻涕也流下来.所谓驱动就是认识硬件,还有前期建模.虽然<驱动篇I>的硬件都是我们熟悉的老友记,例 ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十三:串口模块② — 接收
实验十三:串口模块② - 接收 我们在实验十二实现了串口发送,然而这章实验则要实现串口接收 ... 在此,笔者也会使用其它思路实现串口接收. 图13.1 模块之间的数据传输. 假设我们不考虑波特率,而 ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】连载导读
前言: 无数昼夜的来回轮替以后,这本<驱动篇I>终于编辑完毕了,笔者真的感动到连鼻涕也流下来.所谓驱动就是认识硬件,还有前期建模.虽然<驱动篇I>的硬件都是我们熟悉的老友记,例 ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二:按键模块① - 消抖
实验二:按键模块① - 消抖 按键消抖实验可谓是经典中的经典,按键消抖实验虽曾在<建模篇>出现过,而且还惹来一堆麻烦.事实上,笔者这是在刁难各位同学,好让对方的惯性思维短路一下,但是惨遭口 ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验七:PS/2模块① — 键盘
实验七:PS/2模块① — 键盘 实验七依然也是熟烂的PS/2键盘.相较<建模篇>的PS/2键盘实验,实验七实除了实现基本的驱动以外,我们还要深入解PS/2时序,还有PS/2键盘的行为.不 ...
随机推荐
- 边框颜色为 tintColor 的 UIButton
创建一个 UIButton 的子类,重写其方法: - (void)drawRect:(CGRect)rect { [[self layer] setCornerRadius:CORNER_RADIUS ...
- EasyUI的功能树之异步树
最近几个项目都用到了EasyUI这个Jquery框架,目前感觉起来还是很好使的,展示效果很好,帮助文档什么的资料很多,而且互联网上Easy粉很多,大多数拥护和喜爱EasyUI的粉丝们都愿意在网络平台互 ...
- vue select下拉框绑定默认值
vue select下拉框绑定默认值: 首先option要加value值,以便v-model可以获取到对应选择的值 一.当没有绑定v-model,直接给对应的option加selected属性 二.当 ...
- 关于测试中哪些信息需要放到jira上面
1.每个新需求的功能点,全部在jira上一一呈现 2.每个bug也一样在jira上一一呈现 3.任务一个需要优化改进的点也一一在jira上呈现 然后程序员一直开发新功能和修改新bug,测试人员负责bu ...
- GridFS实现原理
GridFS在数据库中,默认使用fs.chunks和fs.files来存储文件. 其中fs.files集合存放文件的信息,fs.chunks存放文件数据. 一个fs.files集合中的一条记录内容如下 ...
- Gulp--Less
摘要: 前面分享了一些less的是用方法,包括在grunt中,今天在分享下使用gulp来编译less文件.首先需要安装gulp,如何安装请看文章. 安装插件: gulp编译less使用了gulp-le ...
- 【scala】 scala 条件控制 和异常处理(二)
1.scala 变量定义 ,var val 区别. var 定义可变变量 val 定义不可变变量,scala 推荐使用.相当于Java的final 变量. scala中包含的基本数据类型详情如下表所示 ...
- Eclipse------使用Maven install出错:编码GBK的不可映射字符
使用Maven install时报错:编码GBK的不可映射字符 原因:Maven默认使用GBK进行编码 解决方法: 在pom.xml文件中添加如下代码即可 <project> <pr ...
- EventHandler中如何提升用户权限(模拟管理员权限)
不论是在工作流或是EventHandler中,我们经常希望模拟管理员权限,从而可以通过程序自定义列表项的权限. 在工作流中可以用如下代码来提升权限:(以下代码实现的功能是断开列表项所继承的权限,除管理 ...
- mybatis 之 parameterType="List" 2
<select id="queryGoodsByGoodsNoPcweb" parameterType="List" resultMap="si ...