《基于VHDL的RS232串口通信控制器.docx》由会员分享,可在线阅读,更多相关《基于VHDL的RS232串口通信控制器.docx(27页珍藏版)》请在三一办公上搜索。
1、基于VHDL的RS232串口通信控制器目录 摘要 . 2 正文 . 2 1. RS232协议简介 . 2 1.1 串口 . 2 1.2 RS232串口 . 3 1.3 数据帧 . 4 2. 系统设计 . 5 2.1 总体设计 . 5 2.2 各模块设计及参数 . 5 3. 系统调试 . 9 3.1 仿真调试 . 9 3.2 下载调试 . 10 4. 系统指标测试 . 10 4.1 功能说明 . 10 4.2 管教分布及说明 . 10 4.3 元件清单及资源利用情况 . 11 RS232串口通信控制器 摘要 本实验使用VHDL语言设计了一个串口通信控制器,实现了CPLD和PC机通过RS232协议
2、进行数据通信。利用MAXII EPM1270T144C5为核心芯片的数电实验开发板下载实现。串口的波特率选择9600bit,处于双工工作状态。按“发送键”CPLD向PC发送字符串“welcome”;PC课随时向CPLD发送0F的十六进制数据,CPLD接收后译码显示在7段数码管上。 Abstract In this study, using the VHDL language designed a serial communications controller, to achieve the CPLD and the PC through RS232 protocol for data com
3、munication. Core chip using MAXII EPM1270T144C5 several power board download experimental development to achieve. Serial port baud rate selection 9600bit, in the duplex working condition. Press the Send button CPLD send the string to the PC welcome; PC class at 0 F to the CPLD send the hexadecimal d
4、ata, CPLD decoding after receiving the 7-segment display on. 关键词: VHDL RAS232串口通信 CPLD 正文 1. RS232协议简介 1.1 串口 串口是计算机上一种非常通用设备通信的协议。大多数计算机包含两个基于RS232的串口。串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。同时,串口通信协议也可以用于获取远程采集设备的数据。 串口通信的概念非常简单,串口按位发送和接收字节。尽管比按字节的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离
5、通信。比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。 典型地,串口用于ASCII码字符的传输。通信使用3根线完成:地线,发送,接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通行的端口,这些参数必须匹配: a,波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。例如300波特表示每秒钟发送300个bit。当我们提到时钟周期时,我们就是指波特率例如如果协议
6、需要4800波特率,那么时钟是4800Hz。这意味着串口通信在数据线上的采样率为4800Hz。通常电话线的波特率为14400,28800和36600。波特率可以远远大于这些值,但是波特率和距离成反比。高波特率常常用于放置的很近的仪器间的通信,典型的例子就是GPIB设备的通信。 b,数据位:这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据不会是8位的,标准的值是5、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码是0127。扩展的ASCII码是0255。如果数据使用简单的文本,那么每个数据包使用7位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。
7、由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。 c,停止位:用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。 d,奇偶校验位:在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位,用一个值确保传输的数据有偶个或者奇个逻辑高位。例如,如果数据是011,那
8、么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。如果是奇校验,校验位位1,这样就有3个逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步。 1.2 RS232串口 RS-232是IBM-PC及其兼容机上的串行连接标准。可用于许多用途,比如连接鼠标、打印机或者Modem,同时也可以接工业仪器仪表。用于驱动和连线的改进,实际应用中RS-232的传输长度或者速度常常超过标准的值。RS-232只限于PC串口和设备间点对点的通信。RS-232串口通信最远距离是50英尺。 DB-9针连
9、接头 - 1 2 3 4 5 / 6 7 8 9 / - 从计算机连出的线的截面。 RS-232针脚的功能: 数据: TXD:串口数据输出(Transmit Data) RXD:串口数据输入(Receive Data) 握手: RTS:发送数据请求(Request to Send) CTS:清除发送(Clear to Send) DSR:数据发送就绪(Data Send Ready) DCD:数据载波检测(Data Carrier Detect) DTR:数据终端就绪(Data Terminal Ready) 地线: GND:地线 其他 RI:铃声指示 1.3 数据帧 异步串行通信方式是把一个
10、字符看作一个独立的信息单元,并且字符出现在数据流中的相对时间是任意的,而每一个字符中的各位是以固定的时间传送。因此这种方式在同一字符内部是同步的,而字符间是异步的。 异步通信的主要特点是字符帧的传输格式,这样就使得发送方可以在字符之间可根据实际的需要插入不同的时间间隔,即每一个字符的发送是随机的。异步串行通信是以数据帧的格式传送的,1个字符开始传输前,输出线必须在逻辑上处于1状态,这称为标识态。传输一开始,输出线由标识态变为o,状态,从而作为起始位。起始位后面为58个信息位,信息位由低到高排列,即第1位为字符的最低位,在同一传输系统中,信息位的数目是固定的。信息位后面为校验位,校验位可以按奇校
11、验设置,也可以按偶校验设置,不过,校验位也可以不设置。最后的数位为1,它作为停止位,停止位可为1位、15位或者2位。如果传输完1个字符以后,立即传输下一个字符,那么,后一个字符的起始位便紧挨着前一个字符的停止位了,否则,输出线又会立即进入标识态,即逻辑上处于l。2. 系统设计 2.1 总体设计 CPLD key_input clk,rst 发送模块 分频 clkbaud8x 模块 txd PC 显示 模块 rxd 接收模块 2.2 各模块设计及参数 本实验是串口异步通信的典型应用,串口工作在全双工模式,采用正确的分频系数得出串口通信所需的波特率时钟。把每一位的发送接受分成了8个时隙,这样更好的
12、实现质量可靠的通信,在每次的第7个时隙时,发送接受使能信号有效。 发送部分采用并串转换,在先发送完一个低电平的起始位后,从LSB到MSB的顺序逐个发出,再发一个高电平结束发送过程。 接受部分采用串并转换,在检测到起始位的下降沿后,进入接受,接受采用两级缓存模式,保证高质量的通信。 显示部分,接受到的是相应数字和字符的ASCLL码,所以必须进行译码显示部分,在数码管上显示接受到的信息。 综上所述:本实验大体上分为四个模块: 分频模块:产生正确的满足实验要求的8波特率的时钟。 发送模块:把发送寄存器里的内容按正确的时序通过串口发送到计算机上。 接受模块:通过串口把计算机发送过来的内容按着正确的时序
13、存放在接受寄存器中。 显示模块:把接受寄存器中的内容,正确译码显示在数码管上。 2.2.1 分频模块 通过本模块要产生8波特率的时钟,波特率时钟,以及完成可靠性判断。 系统时钟是50M,波特率是9600,所以得出分频系数=50M/(8*9600*2)=325,转换为二进制为0000000101000101;用div_par表示,分频计数器为div_reg,时隙寄存器div8_tras_reg、div8_rec_reg,分别代表发送,接受两个过程。 开始 1 rst=1? clkbaud8x上升沿? div_reg=0 div8_tras_reg=0 div8_rec_reg=0 div8_tr
14、as_reg+1 div8_rec_reg+1 clk上升? 第七个时隙? div_reg+1 收发使能 div_reg=div_par-1结束 div_reg+0 clkbaud8x= not clkbaud8x 1 2.2.2 发送模块 发送过程其实是一个并转串的过程,在每到来一个发送使能信号后,发送出每一位,最先发送起始位-一个低电平信号,紧接着发送LSB,发送完8位数据位后,因为题目不要求发送奇偶校验位,所以直接发送一位结束位停止发送。 在每发送一帧数据前,先要检测译码,检测到拨码开关所输入的ASCll码,然后把正确的数据装入发送缓存寄存器txd_buf 中。本模块需要用到的信号量如下
15、:trasstart- 开始发送标志,state_tras-发送状态寄存器。初始化状态如下:txd_reg = 1; trasstart = 0; txd_buf = 00000000; state_tras = 0000; 开始 复位? Y 初始化 N N 有按键? Y 进入发送状态,位循环计数,字母循环计数 N 发送完成 Y 结束 2.2.3 接收模块 接受过程恰好是发送过程的逆过程,实现一个串并转换,把rxd上的来自PC的数据存放在rxd_buf中,实现通信。由于接受为异步通信方式,故设计两级缓存来检测起始信号。与此过程相关的信号量为:rxd_reg1 和rxd_reg2两级缓存,sta
16、te_rec接受状态寄存器,初始化状态如下: rxd_reg1 = 0; rxd_reg2 = 0; rxd_buf = 00000000; state_rec = 0000; recstart = 0; recstart_tmp = 0; 开始 N复位? Y 初始化 N起始位? Y 进入接收,位循环计数 N接收完成 Y 结束 2.2.4 显示模块 实验中用到的7段数码管是共阴极数码管,共6个。数码管的共阴极端是各自独立的,当共阴极端CATn为低电平时,该数码管就亮。6个数码管的8个输入端是并联在一起的,起名为AAAG,AP,输入端为高电平时,对应段位就亮 对相应的输入十六进制数,进行译码后,
17、使能数码管,即可显示。 3. 系统调试 3.1 仿真调试 3.1.1 分频仿真 3.1.2 发送仿真 从上图可以看出,在没有复位信号且按下key_input键后,时钟分频得到在8倍波特率的时钟,且在8倍波特率时钟下,每当第七个时隙时,发送出一位数据,从最开始的起始位,紧接着是LSB到 MSB再到停止位高电平,共10位数据。之后,send_state计数加一,传送下一个字母。 3.1.3 接收和显示仿真 从上面这张图能完全看出接受和显示两部分的时序关系,同样从起始位开始,到最后9箭头所对应的rxd_buf和实际rxd上的数据是一致的,都是00110000,是接受到了数字0的ASCLL码,最后显示
18、译码输出的是11111100,即在数码管上显示0. 3.2 下载调试 3.2.1 按键抖动 使用按键作为key_input会出现按键抖动问题。后增加延时去抖的代码。也可以使用拨码开关做输入。 3.2.2 实验仪器问题 本实验虽然涉及硬件仪器较少,但还是应当仔细阅读CPLD个模块使用说明。特别注意区分COM1与COM2,切勿接错,白白浪费时间。 4. 系统指标测试 4.1 功能说明 本模块的功能是验证实现和PC机进行基本的串口通信的功能。需要在PC机上安装一个串口调试工具来验证程序的功能。 程序实现了一个收发一帧10个bit的串口控制器,10个bit是1位起始位,8个数据位,1个结束位。串口的波
19、特律由程序中定义的div_par参数决定,更改该参数可以实现相应的波特率。程序当前设定的div_par 的值是0x104,对应的波特率是9600。用一个8倍波特率的时钟将发送或接受每一位bit的周期时间划分为8个时隙以使通信同步.程序的工作过程是:串口处于全双工工作状态,按动key_input,CPLD向PC发送字符串“welcome”;PC可随时向CPLD发送0-F的十六进制数据,CPLD接受后显示在7段数码管上。 具体实现如下:按下键rst(124)进行复位,然后通过input(拨码开关)输入想要发送的字符的ASCLL码,然后按下键key(123)进行发送。 接受时,直接在串口调试工具上输
20、入自己想要发送的数字即可。 4.2 管脚分布及说明 4.3 元件清单及资源利用情况 所用元件分硬件和软件:其中硬件包括MAX实验板一个,USB下载线,以及针串口线。软件包括QUARTUS集成开发环境以及串口调试工具。 资料利用情况如下: 5. 附录 5.1 源程序 - - 本模块的功能是验证实现和PC机进行基本的串口通信的功能。需要在 -PC机上安装一个串口调试工具来验证程序的功能。 - 程序实现了一个收发一帧10个bit的串口控 -制器,10个bit是1位起始位,8个数据位,1个结束 -位。串口的波特律由程序中定义的div_par参数决定,更改该参数可以实 -现相应的波特率。程序当前设定的d
21、iv_par 的值是0x104,对应的波特率是 -9600。用一个8倍波特率的时钟将发送或接受每一位bit的周期时间 -划分为8个时隙以使通信同步. -程序的工作过程是:串口处于全双工工作状态,按动key2,CPLD向PC发送皐elcome -字符串;PC可随时向CPLD发送0-F的十六进制 -数据,CPLD接受后显示在7段数码管上。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY UART IS PORT ( clk
22、 : IN std_logic; rst : IN std_logic; rxd : IN std_logic; -串行数据接收端 txd : OUT std_logic; -串行数据发送端 en : OUT std_logic_vector(5 downto 0); - 数码管使能 seg_data : OUT std_logic_vector(7 DOWNTO 0); -数码管数据 key_input : IN std_logic -按键输入 ); END UART; ARCHITECTURE arch OF UART IS -/inner reg/ SIGNAL div_reg : st
23、d_logic_vector(15 DOWNTO 0);-分频计数器,分频值由波特率决定。分频后得到频率8倍波特率的时钟 SIGNAL div8_tras_reg : std_logic_vector(2 DOWNTO 0);-该寄存器的计数值对应发送时当前位于的时隙数 SIGNAL div8_rec_reg : std_logic_vector(2 DOWNTO 0); -寄存器的计数值对应接收时当前位于的时隙数 SIGNAL state_tras : std_logic_vector(3 DOWNTO 0); - 发送状态寄存器 SIGNAL state_rec : std_logic_v
24、ector(3 DOWNTO 0); - 接受状态寄存器 SIGNAL clkbaud_tras : std_logic; -以波特率为频率的发送使能信号 SIGNAL clkbaud_rec : std_logic; -以波特率为频率的接受使能信号 SIGNAL clkbaud8x : std_logic; -以8倍波特率为频率的时钟,它的作用是将发送或接受一个bit的时钟周期分为8个时隙 SIGNAL recstart : std_logic; - 开始发送标志 SIGNAL recstart_tmp : std_logic; -开始接受标志 SIGNAL trasstart : std_
25、logic; SIGNAL rxd_reg1 : std_logic; -接收寄存器1 SIGNAL rxd_reg2 : std_logic; -接收寄存器2,因为接收数据为异步信号,故用两级缓存 SIGNAL txd_reg : std_logic; -发送寄存器 SIGNAL rxd_buf : std_logic_vector(7 DOWNTO 0);-接受数据缓存 SIGNAL txd_buf : std_logic_vector(7 DOWNTO 0);-发送数据缓存 SIGNAL send_state : std_logic_vector(2 DOWNTO 0);-每次按键给PC
26、发送Welcome字符串,这是发送状态寄存器 SIGNAL cnt_delay : std_logic_vector(19 DOWNTO 0);-延时去抖计数器 SIGNAL start_delaycnt : std_logic; -开始延时计数标志 SIGNAL key_entry1 : std_logic; -确定有键按下曛? SIGNAL key_entry2 : std_logic; -确定有键按下标志 -/ CONSTANT div_par : std_logic_vector(15 DOWNTO 0) := 0000000101000101; -分频参数,其值由对应的波特率计算而得
27、,按此参数分频的时钟频率是波倍特率的8倍,此处值对应9600的波特率,即分频出的时钟频率是9600*8 SIGNAL txd_xhdl3 : std_logic; BEGIN en =111110 ;-7段数码管使能信号赋值 txd_xhdl3 = txd_reg ; txd = txd_xhdl3; PROCESS(clk,rst) BEGIN IF ( rst = 1) THEN -如果重新开始 cnt_delay = 00000000000000000000; start_delaycnt = 0; ELSIF(clkEVENT AND clk=1)THEN -否则在时钟上升沿 IF (
28、start_delaycnt = 1) THEN -每800000次,检测一次是否有按键按下 IF (cnt_delay /= 00001100001101010000) THEN cnt_delay = cnt_delay + 00000000000000000001; -每次时钟到来加1 ELSE cnt_delay = 00000000000000000000; start_delaycnt = 0; END IF; ELSE IF ( key_input=1) AND (cnt_delay = 00000000000000000000) THEN start_delaycnt = 1;
29、 END IF; END IF; END IF; END PROCESS; PROCESS(clk,rst) BEGIN IF ( rst = 1 ) THEN key_entry1 = 0; ELSIF(clkEVENT AND clk=1)THEN IF (key_entry2 = 1) THEN -如果key2=1 key_entry1 = 0; -有键输入? ELSE -如果key2=0, IF (cnt_delay = 00001100001101010000) THEN -检测键输入 IF (NOT key_input = 1) THEN -如果没有键输入 key_entry1 =
30、 1; END IF; END IF; END IF; END IF; END PROCESS; PROCESS(clk,rst) BEGIN IF ( rst = 1) THEN div_reg = 0000000000000000; ELSIF(clkEVENT AND clk=1)THEN -div_reg是某个延时 IF (div_reg = div_par - 0000000000000001) THEN div_reg = 0000000000000000; ELSE div_reg = div_reg + 0000000000000001; END IF; END IF; END
31、 PROCESS; PROCESS(clk,rst) -分频得到8倍波特率的时钟 BEGIN IF ( rst = 1) THEN clkbaud8x = 0; ELSIF(clkEVENT AND clk=1)THEN IF (div_reg = div_par - 0000000000000001) THEN clkbaud8x = NOT clkbaud8x; -产生时钟脉冲 END IF; END IF; END PROCESS; PROCESS(clkbaud8x,rst) BEGIN IF ( rst = 1) THEN div8_rec_reg = 000; ELSE IF(cl
32、kbaud8xEVENT AND clkbaud8x = 1) THEN IF (recstart = 1) THEN -接收开始标志 div8_rec_reg = div8_rec_reg + 001;-接收开始后,时隙数在8倍波特率的时钟下加1循环 END IF; END IF; END IF; END PROCESS; PROCESS(clkbaud8x,rst) BEGIN IF ( rst = 1) THEN div8_tras_reg = 000; ELSE IF(clkbaud8xEVENT AND clkbaud8x = 1) THEN IF (trasstart = 1) T
33、HEN div8_tras_reg = div8_tras_reg + 001;-发送开始后,时隙数在8倍波特率的时钟下加1循环 END IF; END IF; END IF; END PROCESS; PROCESS(div8_rec_reg) BEGIN IF (div8_rec_reg = 111) THEN clkbaud_rec = 1; -在第7个时隙,接收鼓苄藕庞行荽蛉? ELSE clkbaud_rec = 0; END IF; END PROCESS; PROCESS(div8_tras_reg) BEGIN IF (div8_tras_reg = 111) THEN clk
34、baud_tras = 1; -在第7个时隙,发送使能信号有效,将数据发出 ELSE clkbaud_tras = 0; END IF; END PROCESS; PROCESS(clkbaud8x,rst) BEGIN IF ( rst = 1) THEN txd_reg = 1; trasstart = 0; txd_buf = 00000000; state_tras = 0000; send_state = 000; key_entry2 = 0; ELSE IF(clkbaud8xEVENT AND clkbaud8x = 1) THEN IF (NOT key_entry2 = 1) THEN -key2=0,key1=1 IF (key_entry1 = 1) THEN key_entry2 = 1; -key2=1 txd_buf -发送起始位 IF (NOT trasstart=1) AND (send_sta