PLD串口通信实验报告DOCWord文件下载.docx
《PLD串口通信实验报告DOCWord文件下载.docx》由会员分享,可在线阅读,更多相关《PLD串口通信实验报告DOCWord文件下载.docx(22页珍藏版)》请在冰豆网上搜索。
比如,标准的ASCII码是0~127(7位)。
扩展的ASCII码是0~255(8位)。
如果数据使用简单的文本(标准ASCII码),那么每个数据包使用7位数据。
每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。
由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。
停止位:
用于表示发送串行数据的最后一位。
典型的值为1,1.5和2位。
由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。
因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。
奇偶校验位:
在串口通信中一种简单的检错方式。
有四种检错方式:
偶、奇、高和低。
当然没有校验位也是可以的。
对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。
例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。
如果是奇校验,校验位位1,这样就有3个逻辑高位。
串口通信的数据传输时序如图:
图2串口通信时序图
例如0x55是传输的方式如下:
图3异步串行通信格式
0x55的二进制表示为:
01010101。
但是由于先发送的是最低有效位,所以发送序列是这样的:
1-0-1-0-1-0-1-0。
2.3液晶显示模块
实验使用无字库的12864LCD显示,对12864的操作都是围绕着几根引脚展开的。
包括写命令、写数据、读数据、读状态就是通过这些引脚的高低电平搭配来实现的。
以下是关于显示屏的一些参数:
图4内部结构图
图5写时序图
图6基本操作时序
3实验仪器
XUP(FPGA:
spartan3S400AN)实验开发板
安装ISE软件的电脑及串口线一根
串口调试助手小软件
4实验主要操作步骤
4.1实验设计思想
实验采用分层次设计的方法,用硬件描述语言分别实现串口发送接收的功能及液晶显示的功能模块,最后用对顶层原理图进行综合的方法实现整个设计。
具体方法如下:
1.通过ISE开发工具,新建2个模块,分别为串口通信模块,lcd12864液晶显示模块,另外再加一个顶层原理图输入文件。
2.串口通信模块主要分为四个进程部分:
波特率
产生部分(发射和接收)、串行数据接收部分、串行数据发送部分。
3.波特率产生部分:
主要是通过计数来实现波特率产生,并对数据进行采样。
为了保证接收串行数据的准确性,一般使用比波特率高数倍的时钟作为接收数据的采样时钟。
此处采用9600*8hz的信号,并且在计数到每个脉宽的第七个时隙对数据进行采样。
4.串行数据接收部分:
当检测到接收信的低电平时,对数据进行采集。
5.串行数据发送部分:
当接收到发送信号的低电平时,对数据进行发送。
6.液晶显示模块:
上位机发送到的数据由液晶屏显示。
4.2各模块设计实现
在理解串口通信协议、LCD液晶显示的使用方法后,使用Verilog语言描述出各部分要实现的功能,完成实验的要求。
4.2.1串口通信模块的设计
下面是该模块功能实现的部分Verilog源程序:
always@(posedgeclk)//波特率产生部分
begin
if(!
nrst)
div_reg<
=0;
elsebegin
if(div_reg==div_par-1)
div_reg<
//分频计数器div_reg
else
=div_reg+1;
end
end
always@(posedgeclk)//分频得到8倍波特率的时钟clkbaud8x
clkbaud8x<
elseif(div_reg==div_par-1)
=~clkbaud8x;
//接受PC机串行数据
always@(posedgeclkbaud8xornegedgenrst)
nrst)begin
rxd_reg1<
rxd_reg2<
rxd_buf<
state_rec<
recstart<
recstart_tmp<
=rxd;
=rxd_reg1;
if(state_rec==0)begin
if(recstart_tmp==1)begin
recstart<
=1;
recstart_tmp<
state_rec<
=state_rec+1;
end
elseif(!
rxd_reg1&
&
rxd_reg2)//检测到起始位的下降沿,进入接受数据状态
elseif(state_rec>
=1&
state_rec<
=8)begin
if(clkbaud_rec)begin
rxd_buf[7]<
=rxd_reg2;
rxd_buf[6:
0]<
=rxd_buf[7:
1];
state_rec<
elseif(state_rec==9)begin
if(clkbaud_rec)begin
recstart<
//数据发送部分
always@(posedgeclkbaud8xornegedgenrst)
txd_reg<
trasstart<
txd_buf<
state_tras<
key_entry2<
if(!
key_entry2)begin
if(key_entry1)begin
key_entry2<
txd_buf<
=rxd_buf;
//发送接受到的数据
end
elsebegin
case(state_tras)
4'
b0000:
begin//发送起始位,检测起始位的低电平
if(!
trasstart)
trasstart<
else//if(send_state<
7)begin
if(clkbaud_tras)begin
txd_reg<
state_tras<
=state_tras+1;
end
//end
elsebegin
key_entry2<
state_tras<
end
b0001:
begin//发送第1位
if(clkbaud_tras)begin
txd_reg<
=txd_buf[0];
txd_buf[6:
=txd_buf[7:
b0010:
begin//发送第2位
b0011:
begin//发送第3位
b0100:
begin//发送第4位
b0101:
begin//发送第5位
b0110:
begin//发送第6位
b0111:
begin//发送第7位
b1000:
begin//发送第8位
b1001:
begin//发送停止位
txd_buf<
=8'
h55;
default:
begin
endcase
//将接受的数据用lcd显示出来,本实验只写了部分字符的编码
always@(rxd_buf)
case(rxd_buf)
8'
h30:
wordnum<
=0;
//转化成12864显示的字符0
8'
h31:
=1;
h32:
=2;
h33:
=3;
h34:
=4;
h35:
=5;
default:
=6;
//其他按键转换成显示字符*
endcase
endmodule
经过语法检查和综合等步骤后,在当前资源管理窗口中的Designutilities项目中,生成电路模块符号,如下图所示:
图7串口通信模块电路图
4.2.2显示模块的设计
12864液晶屏的控制主要分为指令控制和显示控制两个部分,使用状态机和计数器的结合方法实现指令的控制。
部分源程序如下:
reg[31:
0]count;
integeri;
reg[7:
0]X,Y,X0;
always@(posedgeclk)
begin
/*放置字库处*/写入字符‘0’
word[0]<
=8'
h00;
word[1]<
hE0;
word[2]<
h10;
word[3]<
h08;
word[4]<
word[5]<
word[6]<
word[7]<
word[8]<
word[9]<
h0F;
word[10]<
word[11]<
h20;
word[12]<
word[13]<
word[14]<
word[15]<
//有限状态机
state<
=S_initial;
CS1_CS2<
=2'
b11;
X<
hb8;
Y<
h40;
X0<
hb8;
i<
=0;
count<
else
case(state)
S_initial:
begin
DataIn<
h3f;
//FunctionSet
ID<
startflag<
count<
=count+1;
if(count>
=100)//2us确保能写进去
begin
state<
=S_initial_1;
count<
end
else
state<
end
S_initial_1:
//等待写完
state<
if(finishflag)
begin
if(count>
=2000)//等待39us
begin
state<
=S_initial_2;
count<
end
end
S_initial_2:
h0f;
//DisplayON/OFFControl
=S_initial_3;
S_initial_3:
=2000)//?
?
待39us
=S_initial_4;
end
S_initial_4:
h01;
//DisplayClear
=S_initial_5;
S_initial_5:
//waitfor1.5ms
=100000)//2ms
=S_initial_6;
end
S_initial_6:
h06;
//EntryModeSet
=100)
=S_initial_7;
S_initial_7:
//InitialFinish
CS1_CS2<
b10;
//对第一块操作
=2000)
=S_operate;
end//等待39us
//////////////////////////////////////////////////////////////
S_operate:
//设计Y
=Y;
//8'
startflag<
=3000)//60us//等待的39us加上执行的8us提供足够的时间余量
=S_operate_1;
S_operate_1:
//设计X
=X;
state