Verilog编写的RS232(Uart)程序

合集下载

rs串口verilog代码

rs串口verilog代码

UART是通用异步收发器的简称,其中有一种电平规范较RS232规范,它用-3~-15V表示正逻辑,3~15V表示负逻辑,通过FPGA芯片实现RS232通信首先要解决的就是FPGA电平和RS232电平之间的矛盾,通常采用MAX3232作为物理层的电平接口,根据MAX3232提供的标准配制方式把物理电路设计好后,接下来的通信就是要实现逻辑的接收和发送……设计最简单的RS232通信逻辑,FPGA实现将接收到的数据会发出去,总共两个数据传输引脚,一收一发。

将此通信模块分为三个部分:接收模块,波特率控制模块,发送模块。

工作原理:此模块接收MAX3232传过来的串行数据,对齐进行判断采样,校验,最后将数据流中的串行数据转换为八位并行数据,将此八位数据储存,或送给发送模块发送出去。

根据RS232通信标准器串行数据分为起始位、数据位、校验位、停止位,空闲时为高电平,起始位通常为低电平,数据位通常为8位,校验位分为奇校验、偶校验等,停止位一位或两位且为高电平。

FPGA接收模块对此数据进行异步接收,首先就要检测其数据传输开始标识,当然就是检测开始位,于是要有下降沿检测电路,检测到下降沿是输出一高脉冲,此电路可以用两个D触发器加上基本门电路实现,脉冲触发开始进入接收状态,输出接收状态标志位,使其为1,此标志位使能波特率控制模块输出采样脉冲,此计数脉冲触发接收模块中的计数器计数,加到相应的位就把当前的串行总线上的值赋给缓冲器,或对其判断,当计数完成11次计数后,已将8位串行数据转成并行数据到缓冲器中,且进行了校验的判断和停止位的判别,这是接收状态结束,接收状态位置0,计数器清零。

对于波特率产生模块用于控制采样数据脉冲的周期,其周期就为串行数据传送一个bit所用的时间,根据此时间和时钟周期设置计数值。

当接收模块完成工作时,接收状态位为0时可以触发发送模块,发送模块检测接收状态的下降沿,由此产生一高脉冲,与发送模块类似,根据波特率控制模块产生的计数脉冲将并行数据转成串行数据,并加上开始位、校验位、停止位。

UART RS232 RS485过电线通信转接器模块用户手册说明书

UART RS232 RS485过电线通信转接器模块用户手册说明书

UART/RS232/RS485Over Powerline Communication Transceiver ModuleUser Manual.LinkSprite Technologies, IncJuly, 2008Table of ContentⅠSummary (3)1 Introduction (3)2 Features (4)3 Specifications (5)4 Applications (5)ⅡDiagram (6)1 Functional Diagram (6)2 Board Layout (6)3 LED (7)4 Definition of Pin (7)ⅢCommand Interface (8)1 Command Mode (8)1.1 Enter command mode (8)1.2 Exit command mode (8)2 Arguments and Responses (8)2.1 Arguments and Responses (8)2.2 Commands without Arguments (9)2.3 Modified arguments (9)3 Command List (10)ⅣRepeater Function (13)1 Introduction (13)2 Function Setting (14)2.1Start repeater function (14)2.2Turn off repeater function (15)2.3 Setting Illustration (15)3 Repeater Grade (15)ⅤLogic Address (17)1 Logic Address (17)2 Address Setting (18)ⅥApplication Illustration (20)ⅠSummary1. IntroductionUART/RS232/RS485 are widely used in industrial control and instrument fields. PLC-UART, PLC-RS232/RS485 transceiver modules from LinkSprite (LinkSprite modules) are transceiver modules designed to send/receiver UART/RS232/RS485 data over the powerline network.PLC-RS232/RS485 is designed to transparently move serial data over the powerline network, and achieves the target of replacing RS232/RS485 cables by the ubiquitous powerline network.LinkSprite modules have the built-in packet-level repeater function.This feature can greatly extend the coverage of the powerline communication.LinkSprite modules has both physical and logic addresses. In a network, both physical and logic addresses can be used to address different nodes in the network.2 Features●Fully transparent mode, plug and play coming out of the box withoutthe need to do any programming.● Built-in error correction codes.● Built-in repeater function to extend the coverage.●Physical and logic address●AT commands used for advanced configuration.● UART, RS232 interface and RS485 bus●FSK(Frequency Shift Keying)modulation used in physical layer● Low power● RoHS● Small module size, and easy to be implemented into existingproducts.3 SpecificationsProduct name PLC-UART/RS232/RS485Transceiver ModuleInterface UART, RS232 or RS485Operating Voltage 230VAC/50Hz,110VAC/60HzModulation FSK(Frequency Shift Keying)Carrier frequency 262K/144KHzError Correction FEC(Forward Error Correction)Data rate on Powerline 30KbpsMaximum packet data length 320bytesRepeater Hops 3 HopsTransmission distance 300 feets(no repeater)Support nodes number 65535LED Power Line Activity LEDsystem LEDserial port LED4 Applications●AMR●Industry manufacture and control●Safeguard, fire alarm, smoke alarm●Collect and transmit instrument data●Safeguard and monitor●Home automationⅡDiagram 1 Functional Diagram2 Board Layout3 LEDL1PLC LED: green mans module is sending data to PLC; red means module is receiving data from PLCL2 System LED ,green means system is in normalL3Serial port LED ,green means module is receiving data from aerial port; red means module is sending data to serial port4 Definition of Pin1 VAC 220VAC/50Hz or 110VAC/60Hz Power lines2 VAC 220VAC/50Hz or 110VAC/60Hz3 18V+ +18VDC Module power4 18V- -18VDC5 RS485 B RS485busB RS485 bus6 RS485 A RS485 bus A GND7 GNDGND8RS232TXD RS232 data transmission should link to PC’sRXDRS232 interface9RS232 RXD RS232 data receiving should link to PC’s RXDⅢCommand Interface1 Command Mode1.1 Enter command modeThe module can be put into command mode by sending “+++” through serial port. The module will respond with an “ok”. In order to prevent the situation where the user data” +++”mistakenly triggers the command mode, there must be no serial port data input one second before and after the receiving of "+++". At the same time, the gap between the three”+” should not be more than one second, otherwise, it will be considered as a data rather than a command.1.2 Exit command modeThere are two approaches to exit command mode. One way is to input command “ATEX”. The other is to timeout and automatically exit. In either case, the modules will response "exited". The timeout value can be set by command "ATTO"2 Arguments and Responses2.1 Arguments and ResponsesFor all the commands with arguments: if the parameters are correct, the module will respond with an “ok”. Otherwise, the modules will response with an “invalid para”. If there are no arguments associated with the commands, it will be treated as polling modem and the module will respond with the existing arguments residing in the module.2.2 Commands without ArgumentsThere are four commands without arguments.● + + +: enter command mode; will directly return “ok”.● ATEX: exit the command mode, return “exited”.● ATRS: software reset, will reset the module immediately, no return.● ATSR: in search for other modules on the power lines, this will return thename of the found module. Please wait for two seconds after sending a command. The name of module received in two seconds will be shown in the serial port, otherwise, the name received after two seconds will be ignored. Note: In the course of searching, all bytes input from serial port also will also be ignored.2.3 Modified argumentsExcept for serial arguments, the modified arguments will be immediately saved into eeprom and take effect. The serial arguments won’t take effect immediately after being modified to avoid user from modifying PC serial arguments before inputting command. Serial arguments will take effect through automatically resetting module when exiting the command mode.3 Command ListCommand Description Arguments Description DefaultControl Class+++ none Enter commandmodeATEX Exit none Exit command modeATTO Time out 1-30Timeout value,unit: second5 ATRS Reset none Software resetNetwork classATDA DomainAddress1-32767Domain Address ofLogic Address1ATNANodeAddress1-65535Node Address oflogical address1Function classATRP Repeater Y,N Relay function, Y ison, N for offYATNM NameA stringwith lengthless than 15Set the name of themodulePU-R485A Communication classATBD Baud Rate 1200, 2400,4800, 9600,19200Baud Rate 9600ATDB Data Bit 5,6,7,8 Data bit 8ATPA Parity N, O, E Parity bit,N = no, O= odd, E = evenNATST Stop Bit 1,2 Stop bit 1Debug classATRW Raw Y,NThe raw data for debugging. Themodule will outputsent raw packetsfrom host to the module, and not justthe payload. Ymeans turn on this function, N meansturning off.NATMI MIOpattern Y,N Support compatibleissue with ArianeMIO-RS232 format.The header of thedata package will be"A3 04".NATSR Search noneSearch for peer module on the power line networkⅣRepeater Function1 IntroductionTo extend the coverage, Linksprite modules have built-in repeater function.When the module's repeater function is turned on (ON is the default setting), the module echos the data packet from the power line, while entertaining the data sent by host through the serial port.Transceiver function is not influenced by repeater function, that is to say, each module can be used as a separate repeater or can be seen as repeater when sending and receiving data. It can not only send and receive data from the power line, but also repeat other data packets.In order to prevent network congestion, the module is smart enough to know the data were sent or repeated by itself and will discard the datapackets when receiving the duplicated ones.Note: Due to the fact that repeaters will resent the received data packets, if the number of repeater is too large, a number of repeaters will seize the channel, and lead to increased communication time. When deploying the repeater, one should take full account of the balance of reliability and real-time.2 Function SettingAT command ‘ATRP’ is designed to set up the repeater function.2.1Turn on repeater functionSteps input response description1 +++ ok Enter command mode2 ATRP Y or N Poll current repeater status, Y is on,N for off3 ATRP Y ok Turn on repeater function4 ATRP Y Check present repeat status, ON5 ATEX exit Exit command mode2.2Turn off repeater functionsteps input response description1 +++ ok Enter command mode2ATRPY or NCheck current repeater status, Y is on, N for off3 ATRP N okTurn off repeater function4 ATRP N Check current repeater status, OFF 5ATEXexitExit command mode2.3 Setting Illustration●Repeater function is available in the factory.●Once repeater function is modified; it will immediately take effect and be preserved permanently, even if the module is restarted.3 Repeater HopsA data packet could at most pass through third repeater three times. It is shown as follows :Data packet is sent from module A to module B. From module B to module C is the first time, to module D is the second time, and to module E is the third time. Module F is the termination. Therefore, data packet won’t be sent to module F.ⅤLogic Address1 Logic AddressModule data packets are transmitted in the way of broadcasting in power lines. All modules will receive the data packets issued by the module and sent them, through the serial port under carrier signals area.When multiple modules are installed on the same power line network, however, one does not want them to communicate directly; thus, the networks can be addressed by the logic address.Logic address is composed of two parts: domain and nodes. For example, the logic address (10:200) means that the domain value is 10, node value is 200. Logic address is the default setting (1:1).Module data packets can only be received and processed by the module at the same domain. Other modules, even detecting the carrier signal will not receive, nor to transmit to the serial port or repeater.On the above figure, A, E are at the same network, their domain values are 1; B, D, F, H are at the same network, its domain values are10;C, G are at the same network, their domain values are 2002. Although in the physically speaking, all the modules are in a power line network, the packet issued by A, will only be received and processed by E, other modules will not respond. Similarly, packet issued by F, only B, D, H will receive and process packet issued by F, other modules will not work.2 Address Settingstep input response description1 +++ ok Enter command mode2 ATDA 1-32767 Check domain values of presentlogic address. Default factory settingis 1.3 ATNA 1-65535 Check nodes values of present logicaddress. Default factory setting is 1.4 ATDA 2 ok Set domain value of logic address as25 ATNA 45 ok Set nodes of logic address as 456 ATDA 2 Check domain values of logicaddress7 ATNA 45 Check node values of logic address8 ATEX exited Exit command modeⅥApplication IllustrationIntelligent instruments widely adopt RS485 bus to communicate. For example, the power meter automatic meter reading systems, data concentrator through the RS485 bus read the message from power meter.In order to automatically meter reading, RS485 bus needs to be deployed. Here, using PU-R485A module, one can use the existed power lines to directly complete data transmission.LinkSprite Technolgies, Inc. 1410 Cannon Mountain Dr. Longmont, CO 80503 (Voice) 720-949-4-932 (Email)******************** 。

uart通信原理与程序

uart通信原理与程序

uart通信原理与程序UART(通用异步收发传输器)是一种串行通信协议,用于在电子设备之间传输数据。

它广泛应用于各种通信设备和嵌入式系统中,是实现设备间通信的一种基本方式。

本文将详细介绍UART的工作原理和编写UART通信程序的步骤。

一、UART的工作原理UART通信是一种简单的、异步的、串行通信方式。

它使用一个数据线(TXD)和一个时钟线(CLK)实现数据的收发。

UART通信的工作原理如下:1.数据传输格式:UART通信使用帧来表示一个完整的数据包,每个帧由起始位、数据位、校验位和停止位组成。

起始位是一个低电平信号,用来告诉接收方接下来的数据的开始。

数据位是实际要传输的数据,可以是一个字节或多个字节。

校验位用于检查数据的准确性,常用的校验方式有奇偶校验和循环冗余校验(CRC)。

停止位是一个高电平信号,用来表示数据的结束。

2.波特率:3.串行传输:UART通信使用串行传输方式,即每个bit按顺序依次传输。

发送方将数据一位一位地发送到TXD线上,接收方通过CLK线来同步数据的传输。

发送方和接收方都在预定的时钟频率下将数据从一个电平变为另一个电平,以便接收方正确地接收数据。

4.启动和停止:UART通信在数据的开始和结束位置需要一些额外的控制位来标识。

当数据传输开始时,发送方发送一个起始位(低电平),接收方通过检测起始位来确定数据传输的开始。

当数据传输完毕时,发送方发送一个或多个停止位(高电平)来表示数据的结束。

5.同步与异步:UART通信是一种异步通信方式,即发送方和接收方的时钟不同步。

发送方和接收方使用各自的时钟来同步数据的传输,接收方通过检测起始位和停止位来确定数据的开始和结束位置。

二、编写UART通信程序的步骤下面是编写UART通信程序的一般步骤:1.设置波特率:首先,需要设置UART的波特率,确保发送方和接收方使用相同的波特率。

波特率的设置通常是通过设置寄存器完成的,具体的方法可以参考芯片的数据手册。

基于AD9914的多参数可控频率源设计

基于AD9914的多参数可控频率源设计

基于A D 9914的多参数可控频率源设计曾超林,李希密,尹红波,王洪林(中国船舶重工集团公司第七二三研究所,江苏扬州225101)摘要:针对某型号捷变频脉冲雷达设备,设计了一种基于A D 9914的多参数可调节频率源㊂该组件不局限于单一波形,它支持正负线性调频㊁脉冲调制和相位编码,其中,中心频点㊁调频带宽㊁调频时间㊁重频等参数均可调节㊂测试结果表明该组件的指标性能优越,频率切换时间低于250n s ,杂散抑制达到75d B c ,1k H z 信号相噪在-120d B C /H z,可以满足雷达设备的应用㊂关键词:雷达设备;A D 9914;直接数字合成器中图分类号:T N 74 文献标识码:B 文章编号:C N 32-1413(2021)02-0115-06D O I :10.16426/j .c n k i .jc d z d k .2021.02.024D e s i g n o f a M u l t i -p a r a m e t e r C o n t r o l l a b l e F r e q u e n c yS o u r c e B a s e d o n A D 9914Z E N G C h a o -l i n ,L I X i -m i ,Y I N H o n g -b o ,WA N G H o n g-l i n (T h e 723I n s t i t u t e o f C S I C ,Y a n gz h o u 225101,C h i n a )A b s t r a c t :A i m i n g a t a c e r t a i n t y p e o f f r e q u e n c y a g i l e p u l s e r a d a r e q u i p m e n t ,a m u l t i -pa r a m e t e r a d -j u s t ab l e f r e q u e nc y s o u r c e i sde s i g n e d b a s e d o n A D 9914.T h e m o d u l e i s n o t l i m i t e d t o a s i n gl e w a v e -f o r m ,s u p p o r t s p o s i t i v e a n d n e g a t i v e l i n e a r f r e q u e n c y m o d u l a t i o n (F M ),pu l s e m o d u l a t i o n a n d p h a s e e n c o d i n g ,i n w h i c h p a r a m e t e r s s u c h a s t h e c e n t e r f r e q u e n c y p o i n t ,F M b a n d w i d t h ,F M t i m e ,r e p e t i t i o n f r e q u e n c y c a n b e a d j u s t e d .T e s t r e s u l t s s h o w t h a t t h e m o d u l e h a s a e x c e l l e n t pe rf o r m a n c e o f i n d e x ,f r e q u e n c y s w i t c h t i m e i s l e s s t h a n 250n s ,s p u r i o u s s u p pr e s s i o n r e a c h e s 75d B c a n d 1k H z p h a s e n o i s e i s -120d B c /H z ,w h i c h c a n m e e t t h e a p p l i c a t i o n o f t h e r a d a r e q u i p m e n t .K e y wo r d s :r a d a r e q u i p m e n t ;A D 9914;d i r e c t d i g i t a l s y n t h e s i z e r 收稿日期:202011050 引 言在现代雷达系统和电子对抗设备中,频率源起着无可比拟的作用㊂传统的频率合成器波形单一,参数不可调节,无法适应现代战场复杂多样的电磁环境,而基于现场可编程门阵列(F P G A )+直接数字频率合成(D D S )技术的D D S 设备具有参数可控制,发生方式简单,灵活多样等优点,能够快速实现复杂的波形发生系统[1]㊂D D S 是一种新型的频率合成技术,具有相对带宽大㊁频率转换时间短㊁分辨率高和相位连续性好等优点,较容易实现频率㊁相位以及幅度的数控调制,广泛应用于通信领域㊂基于D D S 的以上特点,选用A D I 公司的多功能集成芯片A D 9914完成了多参数可调节的频率源设计㊂1 硬件设计整个系统电路如图1所示,包括上位机㊁外部控制模块㊁F P G A 外围电路㊁A D 9914电路㊁时钟管理电路㊁低压差分信号(L V D S )驱动电路㊁电源管理㊁远程加载模块以及滤波电路㊂1.1 系统工作原理上位机软件使用R S 232串口实现计算机和外部控制模块的信息交换,它按照通信协议向控制模2021年4月舰船电子对抗A pr .2021第44卷第2期S H I P B O A R D E L E C T R O N I C C O U N T E R M E A S U R EV o l .44N o .2图1 系统结构框图块发送不同的指令,X i l i n x F P G A 加载A D 9914,从而使频率源处于合适的工作状态㊂外部控制模块采用I n t e l 公司的E P M 570T 144I 5作为主芯片,产生波形触发信号,负责通用异步收发传输器(U A R T )信号向串行外设接口(S P I )信号的转换,并将频率源的状态信号上报给上位机软件㊂为了保证信号传输成功并且降低信号之间的串扰,选用MA X 9122芯片将单端信号转成差分L V D S 信号,L V D S 在2根导线中都传输了电压,具有很好的抗干扰性㊂X i l i n x F P G A 型号为X C 6S L X 100,它工作时仅需3.3V 供电,供电方式简单,有利于模块的小型化㊂此外,B A N K 2同时支持低压T T L (L V T T L )和L V D S 2种电平标准,将外部输入的L V D S 信号接入B A N K 2,利用F P G A 内部输入缓冲器完成电平转换工作㊂由于F P G A 芯片一般不能掉电保持固件,因此需要外部F L A S H 存储F P G A 固件,在上电的时候再将固件配置到F P G A 中㊂同时,使用了1片远程加载芯片,它采用封装内系统(S I P )技术集成了单片机和千兆以太网物理层,将J T A G 链路转换成网口信号,可以远程升级代码,具有体积小㊁易于远程维护升级等突出优势,极大降低了外场试验㊁微波暗室等条件下雷达整机调试的难度㊂温度传感器型号为D S 18B 20,测温精度达到0.1ħ,测温范围在-70ħ~+150ħ之间㊂D S 18B 20采用单一数字总线通信,仅需使用一个输入/输出(I O )资源,便能实现环境温度的监测㊂1.2 D D S 原理A D 9914内部的D D S 结构如图2所示㊂图2 D D S 基本结构图由图2可知,D D S 主要由相位累加器㊁相位调制器㊁波形数据表以及D /A 转换器组成㊂相位累加器由N 位加法器与N 位寄存器构成,它输出的数据就是合成信号的相位㊂相位累加器的溢出频率就是D D S 输出的信号频率㊂用相位累加器输出的数据作为波形存储器的相位采样地址,这样就可以把存储在波形存储器里的波形采样值经查表找出,完成相位到幅度的转换,并通过在采样点序号上加一个相位控制字实现相位的调整,最后由波形存储器输出数据,并由幅度控制字调节数据大小㊂波形存储器的输出数据送到D /A 转换器,由D /A 转换器将数字信号转换成模拟信号输出㊂若D D S 的时钟频率为F c l k ,频率控制字为1,则输出频率F o u t =F c l k/2N,这个频率是1个基频㊂若设频率控制字为B ,B 只能是整数,且有以下公式:B =2N㊃F o u t F c l k(1) 理论上由以上3个参数就可以得出任意频率和幅度的输出波形,且可得到频率分辨率由时钟频率和累加器的位宽决定㊂参考时钟频率越高,累加器位数越多,输出频率分辨率越高㊂611舰船电子对抗第44卷1.3 A D9914工作方式A D9914共有5种工作模式[2-3],本文使用了并行数据端口模式㊁P R O F I L E调制模式和数字斜坡调制模式㊂在并行数据端口模式中,D D S的控制参数直接由32位并行端口调制,功能引脚F0~F3定义了32位并行端口控制D D S的哪个参数㊂此种模式适用于相位编码信号的产生㊂在P R O F I L E调制模式中[4],D D S控制参数直接由32位并行端口控制,利用外部P R O F I L E控制引脚P S0~P S2选择整机想要的P R O F I L E,实现对D D S控制参数的调制㊂若需要对幅度参数进行调节,需要开启外部输出幅度键控引脚O S K㊂此种模式适用于脉冲调制,当不需要输出波形时,配置幅度控制字对应的P F O F I L E为最小值;当需要输出波形时[5-9],配置幅度控制字对应的P F O F I L E为最大值㊂在数字斜坡模式中,D D S控制参数由数字斜坡发生器D R G直接提供,斜坡发生参数由并行I O端口控制,它控制着斜坡的上升和下降斜率㊁斜坡上下限值㊁上升和下降的步长和步率㊂通过并行编程方式对A D9914内部寄存器进行配置,即可控制D R G 的各种参数[10]㊂选用数字斜坡模式中的非驻留斜坡高位和非驻留斜坡低位产生正负线性调频信号㊂在非驻留斜坡高位模式中,斜坡方向引脚D R C T L正向转换时,启动正斜坡斜率,在达到上限值之前会始终以正斜率斜坡输出,达到上限值之后会立即跳转到下限值,如果工作参数不变,D R G会始终保持该限值输出㊂非驻留斜坡低位工作方式与高位类似,这里不做赘述㊂利用非驻留斜坡和P R O F I L模式,能够实现线性调频脉冲信号的发生㊂2软件设计采用V e r i l o g H D L硬件描述语言,并借助X i l-i n x公司I S E14.7开发软件完成了代码编写,软件框架按功能划分为3个部分,包括报文接收模块㊁报文处理模块以及波形发生模块,其结构如图3所示㊂图3软件基本结构图2.1报文接收模块频率源和外部控制模块之间采用L V D S进行时钟信号㊁触发信号的传输㊂本设计采用X i l i n x公司提供的原语将差分信号转换成单端信号,实现输入信号的缓冲㊂使用I B F G D S将差分时钟信号G C L K_P,G C L K_N转换成单端信号,再用B U F G实现时钟信号的全局缓冲,使它的时钟延迟和抖动最小;使用I B F D S将差分触发信号T R I转换成单端信号㊂整个频率源系统主时钟的频率为120MH z,为了确保系统的稳定性,需要对全局时钟进行约束,在I S E的U C F文件中添加时序约束语句:T I M E S P E CT S_C L K_P=P E R I O D C L K_P 120MH zH I G H50%㊂S P I模块用于向外部发送频率源状态信息,并接收单端S P I报文信号㊂本设计采用右移操作实现S P I数据的接收:首先定义一个256位的寄存器R x_D a t a_R e g[255ʒ0],当片选信号C S为低时,开始接收数据,时钟信号S C K的下降沿每来1次,将数据{MO S I,r x d_d a t a_r e g[255ʒ1]}整体右移1次,当C S为高时,将R x_D a t a_R e g赋值给R x_D a t a,更新一次接收到的报文数据,并将R x d_F l a g置高㊂2.2报文解析模块报文解析模块将报文信息解析,得到报文头㊁频711第2期曾超林等:基于A D9914的多参数可控频率源设计率源的频点信息F r e㊁工作模式信息M o d e和校验以及报文尾,和校验为所有字节相加并加1,如果和校验正确,则将报文信息发送给下级A D9914模块㊂2.3波形发生模块波形发生模块是整个软件设计的核心部分,它包括波形参数模块㊁相位参数模块㊁A D9914模块和数据匹配模块㊂其中,波形参数模块使用了F P G A 内部的查找表,它寄存了不同工作模式下D D S的各种调制参数,包括调频时间t F M㊁调频带宽B F M㊁数字斜坡下限值N D L I M㊁数字斜坡上限值N U L I M㊁数字斜坡频率步进s S T E P和时间步进s T I M E,参数值均根据M o d e样式来设置㊂为了保证线性调频的效果,这里按照最小数字斜坡时间步进调节,即s T I M E固定为1,其余数字斜坡参数计算公式如下:N U L I M=(F0+B F M/2)㊃1491308(2)N D L I M=(F0-B F M/2)㊃1491308(3)s S T E P=B F M㊃f s y s c l kt F M㊃24(4)式中:F0为中心频点;f s y s c l k为A D9914参考时钟频率㊂P h a s e_R o m模块存储了伪随机相位编码,这里使用E X C E L产生512位伪随机相位编码,调用I S E 里的B l o c k M e m o r y G e n e r a t o r I P核,将其设置成单端口只读存储器(R OM),并且设置R OM的深度和数据位宽与C o e文件对应,将C o e文件添加至此单端口R OM㊂A D9914模块根据输入的频点信息㊁工作模式㊁调频带宽㊁调频时间㊁重频等信息,配置A D9914的内部寄存器,使其输出对应的波形㊂A D9914模块包含了多波形发生器的加载,其中波形样式分为点频㊁正线性调频㊁负线性调频㊁相位编码4类,每类波形均对应1个线性序列机㊂根据线性序列机的思想,使用1个计数器不断计数,每个计数值都会对应1个时间,该时间符合操作信号的时间刻,并对该信号进行操作,从而完成A D9914内部寄存器的加载,下面将以正线性调频为例,介绍A D9914寄存器的配置流程㊂(1)地址0x0F:使能自动数模转换器(D A C)校准,触发内部校准程序,从而优化D A C内部时序的建立和保持时间,校准失败会影响功能和性能,因此校准时间需要满足一定条件:t c a l=531840f s (5)式中:f s为A D9914参考时钟频率㊂(2)地址0x01:对输出幅度调制时,需要置位外部O S K使能和O S K使能㊂(3)地址0x05:并行端口的频率㊁相位和幅度会通过不同的路径传达给D D S内核,导致不同的传播延迟,因此,本文调制多余1个参数时需要置位匹配延迟使能位,从而均衡并行端口至D D S内核的每个D D S参数㊂此外,还需置位S Y N C_C L K,它是并行端口的数据时钟,同时还作为F P G A的输入时钟㊂(4)地址0x07:使能数字斜坡非驻留高位㊂在数字斜坡非驻留高位操作期间,D R C T L引脚正向转换时,会启动正斜率斜坡,频率到达上限值时,D R G会自动掉到下限值㊂(5)地址0x11:设置数字斜坡下限值低16位㊂(6)地址0x13:设置数字斜坡下限值高16位㊂(7)地址0x15:设置数字斜坡上限值低16位㊂(8)地址0x16:设置数字斜坡上限值高16位㊂(9)地址0x19:设置数字斜坡频率步进低16位㊂(10)地址0x1B:设置数字斜坡频率步进高16位㊂(11)地址0x21:设置数字斜坡速率㊂其余波形样式寄存器加载方式与此方式类似,这里不做赘述㊂将功能引脚F0~F3配置为全0,通过并行编程实现对A D9914寄存器的加载,写入时序图如图4所示㊂其中A[7ʒ0]为寄存器地址,D[7ʒ0]为需要写入的数据,WR 为写使能,满足一定的时序关系之后,即可完成任意寄存器每一字节的写操作㊂此外,D a t a_D i r模块用于匹配设置32位并行端口,若i d为高电平,则将D a t a32[31ʒ0]直接赋值给D D S[31ʒ0],适用于并行数据端口模式和P R O F I L E调制模式㊂i d为低电平时,则D a t a32[31ʒ0]={P_d a t a[15ʒ0],A d d r[7ʒ0],5'd0,w r,2'b11},适用于数字斜坡调制模式,所以这里i d设置为低电平㊂所有的寄存器配置完成后,并行端口数据并不会发送给D D S内核,需要置位I O U P D A T E引脚,数据才会发送到D D S内核㊂当外部控制设备的同步触发脉冲T R I来临之后,将D R C T L引脚由0置为1,保持至少2个周期之后再置为0,并使能幅度811舰船电子对抗第44卷图4 并行编程写入时序图控制引脚O S K ,A D 9914开始输出,当满足调制时间之后,将O S K 管脚拉低,A D 9914停止输出,1次调制周期结束,系统等待下一个同步触发脉冲的到来㊂3 测试结果使用频谱仪和示波器对实物进行最终测试,测试过程及结果如图5~图8所示㊂图5是频率切换时间,切换时间小于250n s ㊂图6是150MH z 连续波,在100MH z 窄带内杂散抑制达到75d B c ㊂图7和图8分别是5MH z 带宽和20MH z 带宽的线性调频信号㊂图5频率切换时域图图6 150MH z连续波实测图图7 5MH z 带宽线性调频实测图图8 20MH z 带宽线性调频实测图4 结束语介绍了一种基于D D S 的多参数可调频率源,并对其工作原理进行分析,测试结果表明该频率源具有较低的杂散,并且能够实现单频㊁正负线性调频㊁脉冲调制等多波形输出㊂本组件采用D D S 技术,集成度高,性能优越,易于装配和调试,具有广阔的应用前景㊂参考文献[1] 赵腊,祁全,张俊.基于高速芯片9914的信号产生方法[J ].雷达与对抗,2015,39(4):2932.911第2期曾超林等:基于A D 9914的多参数可控频率源设计[2]胡茂海,蒋鸿宇,严俊,等.基于A D9910的多通道信号发生器[J].信息与电子工程,2012,10(1):7781.[3]刘韬.基于D D S的频率源设计与实现[J].电子科技,2013,26(1):5658.[4]张萧.微波D D S频率源技术研究[D].成都:电子科技大学,2013.[5]孟秉林,侯文,刘杏娟.D D S仿真模型的建立[J].山西电子技术,2013(4):5270.[6]任艳玲.基于A D9850的多功能信号源设计[J].电子科技,2015,28(6):179183.[7]陈翘.宽带频率源的研制[D].南京:东南大学,2015.[8] A n a l o g D e v i c e I n c.A D9910d a t a s h e e t[M].N o r w o o d:A n a l o g D e v i c e I n c,2012.[9]喻峰.基于F P G A的低相噪D D S的设计与实现[D].哈尔滨:哈尔滨工业大学,2007.[10]刘韬.基于D D S的频率源设计与实现[J].电子科技,2013,26(1):5658.(上接第103页)通过I O量与多种被控元件如接近开关㊁水平传感器等建立连接,通过C A N总线建立与伺服电机的连接从而接收伺服电机各项反馈量并向其下达控制指令,各被控元件及伺服电机结合传动结构件集成为雷达伺服系统,系统组成图如图6所示㊂图6系统组成图系统上电后,打开串口界面,搜索串口端口号,建立串口连接㊂通过数据采集,接收到伺服电机电压为380V,通过加载使能,给定相应速度,收集并绘制伺服系统某关节部分位置曲线,曲线显示其完成循环往复运动,与实际运动状态拟合㊂同时,调试系统采集到各被控元件的状态信息,并通过伺服调试系统界面的各点灯模块加以显示㊂经分析,本系统实时采集了被控元件的状态信息,并绘制了相应变量的状态曲线,通过参数调整和指令下达模块可以实时改变输出变量的状态从而实现控制被控元件的功能㊂系统简单明了,操作简易,适合伺服调试人员现场调试㊂系统调试界面如图7所示㊂通过实际应用可以发现,本系统信息显示和人工操作完全可以满足雷达伺服系统调试的需要㊂图7雷达伺服调试系统界面5结束语本文通过Q T平台设计了一款用于雷达伺服系统调试的系统,该系统包含了伺服系统常用的参数设定㊁通信方式和状态显示,极大简化了伺服调试人员调试过程㊂此外,该系统性能稳定且价格低廉,具有一定的发展前景㊂参考文献[1]汪洋,李垚,黄鲁.基于Q T和O p e n C V的无线视频监控系统[J].微型机与应用,2015,34(10):6769.[2]吴俊杰,谭勇.基于A R M l i n u x平台的Q t/e自定义键盘实现[J].中国水运,2011(2):7072. [3]杨柳,庞和明,姜琳颖.嵌入L i n u x及S Q L i t e数据库在智能监控中的应用研究[J].微计算机信息,2010,26(24):65-67.021舰船电子对抗第44卷。

基于FPGA Verilog RS232串口回环测试例程,附源程序仿真源码及测试图片

基于FPGA Verilog RS232串口回环测试例程,附源程序仿真源码及测试图片

FPGA Verilog RS232串口回环测试基于FPGA Verilog RS232串口回环测试例程,支持多byte数据传输,附源程序仿真源码及测试图片。

测试基于SSCOM/友善之臂上位机软件测试,测试结果如下图一图二所示。

图一SSCOM图二图三连续发送仿真截图图四连续接收仿真截图后附verilog源程序代码及testbech仿真例程,注释欠。

重点:多byte回环测试要点,上位机串口多位数据连续发送停止位和起始位之间无间隔,回环程序在接收和发送都需要具备在停止位后能立马跳转到下一个起始位的能力。

重点关注cnt_bit的处理方式。

附录1 顶层例化uart_txd uart_txd(.clk_50m(sys_clk_50m),.reset_n(sys_rst_n),.tx_data(rx_data),.baud_set(3'd4),.send_en(rx_done),.send_done(),.send_busy(send_busy),.uart_tx(uart_tx));uart_rxd uart_rxd(.clk_50m(sys_clk_50m),.reset_n(sys_rst_n),.rx_data(rx_data),.baud_set(3'd4),.rx_done(rx_done),.rx_busy(rx_busy),.uart_rx(uart_rx));附录2 串口发送源程序`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 09:45:23// Design Name:// Module Name: uart_txd// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies:// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_txd(clk_50m,reset_n,tx_data,baud_set,send_en,send_done,send_busy,uart_tx);input clk_50m;input reset_n;input[7:0] tx_data;input[2:0] baud_set;input send_en;output reg send_done;output reg send_busy;output reg uart_tx;reg[12:0] cnt;reg[12:0] baud_rate_cnt_max;reg[3:0] cnt_bit;reg[7:0] tx_data_r;localparam baud_rate_9600 =13'd5207;localparam baud_rate_19200 =13'd2603;localparam baud_rate_38400 =13'd1301;localparam baud_rate_57600 =13'd867;localparam baud_rate_115200 =13'd433;always@(posedge clk_50m or negedge reset_n)if(!reset_n)baud_rate_cnt_max <= baud_rate_115200;elsecase(baud_set)3'd0:baud_rate_cnt_max = baud_rate_9600;3'd1:baud_rate_cnt_max = baud_rate_19200;3'd2:baud_rate_cnt_max = baud_rate_38400;3'd3:baud_rate_cnt_max = baud_rate_57600;3'd4:baud_rate_cnt_max = baud_rate_115200;default:baud_rate_cnt_max = baud_rate_115200;endcasealways@(posedge clk_50m or negedge reset_n)if(!reset_n)tx_data_r <=8'd0;else if(send_en)tx_data_r <= tx_data;elsetx_data_r <= tx_data_r;always@(posedge clk_50m or negedge reset_n)if(!reset_n)send_busy <=1'b0;else if(send_en)send_busy <=1'b1;else if(cnt == baud_rate_cnt_max)beginif(cnt_bit ==4'd10)send_busy <=1'b0;elsesend_busy <= send_busy;endelsesend_busy <= send_busy;always@(posedge clk_50m or negedge reset_n)if(!reset_n)send_done <=1'b0;else if(cnt == baud_rate_cnt_max)beginif(cnt_bit ==4'd10)send_done <=1'b1;elsesend_done <=1'b0;endelsesend_done <=1'b0;always@(posedge clk_50m or negedge reset_n)if(!reset_n)cnt <=13'd0;else if(send_busy)beginif(cnt == baud_rate_cnt_max)cnt <=13'd0;elsecnt <= cnt +1'b1;endelsecnt <= cnt;/****************************************always@(posedge clk_50m or negedge reset_n)if(!reset_n)cnt_bit <= 4'd0;else if(send_en) //send_en needs to be 1 clock high pulse cnt_bit <= 4'd1;else if(cnt == baud_rate_cnt_max)beginif(cnt_bit == 4'd10)cnt_bit <= 4'd0;elsecnt_bit <= cnt_bit + 1'b1;endelsecnt_bit <= cnt_bit;******************************************/always@(posedge clk_50m or negedge reset_n)if(!reset_n)cnt_bit <=4'd0;else if(send_busy &&(cnt_bit ==4'd11))cnt_bit <=4'd1;else if(cnt ==1)cnt_bit <= cnt_bit +1'b1;elsecnt_bit <= cnt_bit;always@(posedge clk_50m or negedge reset_n)if(!reset_n)beginuart_tx <=1'b1;endelsecase(cnt_bit)4'd0:;4'd1: uart_tx <=1'b0;//start4'd2: uart_tx <= tx_data_r[0];//bit 04'd3: uart_tx <= tx_data_r[1];4'd4: uart_tx <= tx_data_r[2];4'd5: uart_tx <= tx_data_r[3];4'd6: uart_tx <= tx_data_r[4];4'd7: uart_tx <= tx_data_r[5];4'd8: uart_tx <= tx_data_r[6];4'd9: uart_tx <= tx_data_r[7];//bit 84'd10: uart_tx <=1'b1;//stopdefault:;endcaseendmodule附录3 串口发送testbench`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 11:38:04// Design Name:// Module Name: uart_txd_tb// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_txd_tb();reg clk_50m;reg reset_n;reg[7:0] tx_data;reg[2:0] baud_set;reg send_en;wire send_done;wire send_busy;wire uart_tx;parameter CLK_PERIOD =20;initial clk_50m =0;always#(CLK_PERIOD /2) clk_50m =~clk_50m;initial begintx_data =8'h55;baud_set =4;reset_n =0;send_en =0;#(CLK_PERIOD *100);reset_n =1;# CLK_PERIOD;send_en =1;#(CLK_PERIOD );send_en =0;#(CLK_PERIOD *4340);send_en =1;#(CLK_PERIOD );send_en =0;#(CLK_PERIOD *4340);#(CLK_PERIOD *100);$stop;enduart_txd uart_txd(.clk_50m(clk_50m),.reset_n(reset_n),.tx_data(tx_data),.baud_set(baud_set),.send_en(send_en),.send_done(send_done),.send_busy(send_busy),.uart_tx(uart_tx));endmodule附录4 串口接收源程序`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 15:30:30// Design Name:// Module Name: uart_rxd// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_rxd(clk_50m,reset_n,rx_data,baud_set,rx_done,rx_busy,uart_rx);input clk_50m;input reset_n;output reg[7:0] rx_data;input[2:0] baud_set;output reg rx_done;output reg rx_busy;input uart_rx;reg[12:0] cnt;reg[12:0] baud_rate_cnt_max;reg[3:0] cnt_bit;reg uart_rx_r1;reg uart_rx_r2;wire nedge;localparam baud_rate_9600 =13'd5207;localparam baud_rate_19200 =13'd2603;localparam baud_rate_38400 =13'd1301;localparam baud_rate_57600 =13'd867;localparam baud_rate_115200 =13'd433;always@(posedge clk_50m or negedge reset_n)if(!reset_n)baud_rate_cnt_max <= baud_rate_115200;elsecase(baud_set)3'd0:baud_rate_cnt_max = baud_rate_9600;3'd1:baud_rate_cnt_max = baud_rate_19200;3'd2:baud_rate_cnt_max = baud_rate_38400;3'd3:baud_rate_cnt_max = baud_rate_57600;3'd4:baud_rate_cnt_max = baud_rate_115200;default:baud_rate_cnt_max = baud_rate_115200;endcasealways@(posedge clk_50m or negedge reset_n)if(!reset_n)beginuart_rx_r1 <=8'd0;uart_rx_r2 <=8'd0;endelse beginuart_rx_r1 <= uart_rx;uart_rx_r2 <= uart_rx_r1;endassign nedge = uart_rx_r2 &(!uart_rx_r1);always@(posedge clk_50m or negedge reset_n) if(!reset_n)rx_busy <=1'b0;else if(nedge)rx_busy <=1'b1;else if(cnt == baud_rate_cnt_max)begin if(cnt_bit ==4'd10)rx_busy <=1'b0;elserx_busy <= rx_busy;endelserx_busy <= rx_busy;always@(posedge clk_50m or negedge reset_n) if(!reset_n)rx_done <=1'b0;else if(cnt == baud_rate_cnt_max)begin if(cnt_bit ==4'd10)rx_done <=1'b1;elserx_done <=1'b0;endelserx_done <=1'b0;always@(posedge clk_50m or negedge reset_n) if(!reset_n)cnt <=13'd0;else if(rx_busy)beginif(cnt == baud_rate_cnt_max)cnt <=13'd0;elsecnt <= cnt +1'b1;endelsecnt <= cnt;always@(posedge clk_50m or negedge reset_n) if(!reset_n)cnt_bit <=4'd1;else if(cnt == baud_rate_cnt_max )begin if(cnt_bit ==4'd10)cnt_bit <=4'd1;elsecnt_bit <= cnt_bit +1'b1;endelsecnt_bit <= cnt_bit;always@(posedge clk_50m or negedge reset_n)if(!reset_n)beginrx_data <=8'd0;endelse if(cnt == baud_rate_cnt_max /2)case(cnt_bit)4'd1:;//start4'd2: rx_data[0]<= uart_rx_r2;//bit 04'd3: rx_data[1]<= uart_rx_r2;4'd4: rx_data[2]<= uart_rx_r2;4'd5: rx_data[3]<= uart_rx_r2;4'd6: rx_data[4]<= uart_rx_r2;4'd7: rx_data[5]<= uart_rx_r2;4'd8: rx_data[6]<= uart_rx_r2;4'd9: rx_data[7]<= uart_rx_r2;//bit 74'd10:;//stopdefault:;endcaseelserx_data <= rx_data;endmodule附录5串口接收testbench`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 19:44:29// Design Name:// Module Name: uart_rxd_tb// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_rxd_tb();reg clk_50m;reg reset_n;wire[7:0] rx_data;wire rx_done;wire rx_busy;reg uart_rx;parameter CLK_PERIOD =20;initial clk_50m =0;always#(CLK_PERIOD /2) clk_50m =~clk_50m;initial beginreset_n =0;uart_rx =1;//idle#(CLK_PERIOD *100);reset_n =1;# CLK_PERIOD;uart_rx =0;//start#(CLK_PERIOD *434);uart_rx =1;//bit0#(CLK_PERIOD *434);uart_rx =0;//bit1#(CLK_PERIOD *434);uart_rx =1;//bit2#(CLK_PERIOD *434);uart_rx =0;//bit3#(CLK_PERIOD *434);uart_rx =1;//bit4#(CLK_PERIOD *434);uart_rx =0;//bit5#(CLK_PERIOD *434);uart_rx =1;//bit6#(CLK_PERIOD *434);uart_rx =0;//bit7#(CLK_PERIOD *434);uart_rx =1;//stop#(CLK_PERIOD *434);uart_rx =1;//idle#(CLK_PERIOD *434);#(CLK_PERIOD *434);#(CLK_PERIOD *434);uart_rx =0;//start #(CLK_PERIOD *434);uart_rx =0;//bit0#(CLK_PERIOD *434);uart_rx =1;//bit1#(CLK_PERIOD *434);uart_rx =0;//bit2#(CLK_PERIOD *434);uart_rx =1;//bit3#(CLK_PERIOD *434);uart_rx =0;//bit4#(CLK_PERIOD *434);uart_rx =1;//bit5#(CLK_PERIOD *434);uart_rx =0;//bit6#(CLK_PERIOD *434);uart_rx =1;//bit7#(CLK_PERIOD *434);uart_rx =1;//stop#(CLK_PERIOD *434);uart_rx =1;//idle#(CLK_PERIOD *434);#(CLK_PERIOD *434);#(CLK_PERIOD *434);$stop;enduart_rxd uart_rxd(.clk_50m(clk_50m),.reset_n(reset_n),.rx_data(rx_data),.baud_set(3'd4),.rx_done(rx_done),.rx_busy(rx_busy),.uart_rx(uart_rx));endmodule。

基于FPGA的串口通信设计与实现

基于FPGA的串口通信设计与实现

置和输人数据计算出响应
的奇偶校验位,它是通过
纯组合逻辑来实现的。
2.6总线选择模块
总线选择模块用于
选择奇偶校验器的输入是
数据发送总线还是数据接
收总线。
2.7计数器模块
计数器模块的功能
是记录串行数据发送或者
接收的数日,在计数到某
数值时通知UART内核模
块。 3 UART程序设计 UART完整的工作流程可以分为接收过程
关键词:FPGA:UART:RS232
引言 串行接口的应用非常广泛,为实现串口通 信功能一般使用专用串行接口芯片,但是这种 接口芯片存在体积较大、接口复杂以及成本较 高的缺点,使得硬件设计更加复杂,并且结构与 功能相对固定,无法根据设计的需要对其逻辑 控制进行灵活的修改。介绍了一种采用FPGA 实现串口通信的方法。 1串口通信协议 对一个设备的处理器来说,要接收和发送 串行通信的数据,需要一个器件将串行的数据 转换为并行的数据以便于处理器进行处理,这 种器件就是UART(Universal Asynchronous Re— ceiver/Transmitter)通用异步收发器。作为接iSl的 一部分,UART提供以下功能: 1.1将由计算机内部传送过来的并行数据 转换为输出的串行数据流; 1.2将计算机外部来的串行数据转换为字 节,供计算机内部使用并行数据的器件使用; 1.3在输出的串行数据流中加入奇偶校验 位,并对从外部接收的数据流进行奇偶校验: 1.4在输出数据流中加入启停标记,并从 接收数据流中删除启停标记。 2 UART模块设计 UART主要由UART内核、信号检测器、移 位寄存器、波特率发生器、计数器、总线选择器 和奇偶校验器7个模块组成。(见图1) 2.1 UART内核模块 UART内核模块是整个设计的核心。在数 据接收时,UART内核模块负责控制波特率发 生器和移位寄存器同步的接收并且保存 RS一232接收端口上的串行数据。在数据发送 时,UART内核模块首先产生完整的发送序列, 之后控制移位寄存器将序列加载到移位寄存器 的内部寄存器里,最后再控制波特率发生器驱 动移位寄存器将数据串行输出。 2_2信号检测模块 信号检测器用于对RS一232的输入信号进 行实时检测,一旦发现新的数据则立即通知 UART内核。需要注意的是,这里所说的 RS一232输入输出信号都指经过电平转换后的 逻辑信号,而不是RS一232总线上的电平信号。 2_3移位寄存器模块 移位寄存器的作用是存储输入或者输出 的数据。 2.4波特率发生器模块 由于RS一232传输必定是工作在某种波特 率下,比如9600,为了便于和RS一232总线进行 同步,需要产生符合RS一232传输波特率的时 钟。 2.5奇偶校验器模块 奇偶校验器的功能是根据奇偶校验的设

基于Verilog HDL设计的UART模块

基于Verilog HDL设计的UART模块

1 UART原理串行通信是指外部设备和计算机间使用一根数据线(另外需要地线,可能还需要控制线)进行数据传输的方式。

数据在一根数据线上一位一位传输,每一位数据都占据一个固定的时间长度。

与并行通信方式相比,串行通信方式的传输速度较慢,但这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,因此得到了广泛的应用。

基本的UART只需要发送和接收两条数据线就可以完成数据的全双工通信,其基本功能是在发送端将控制器通过总线传过来的并行数据,以设定的格式,设定的频率串行地传输出去,并同时在接收端将串行接收到的数据,转换成相应的并行数据发送出去。

UART的基本帧格式如图1所示。

其中,起始位总是逻辑O状态,停止位总是逻辑l状态,其持续时间可选为1位、1.5位或2位,其数据位可为5、6、7、8位,校验位可根据需要选择奇校验位,偶校验位或无校验位。

2 UART的设计现今复杂的数字系统的设计往往采用自顶向下的设计方案,利用层次化结构化的方法,将一个设计方案划分为若干模块,在不同层次的模块都可以进行仿真,可以很方便地查看某一层次的代码以改正仿真时发现错误。

在本设计中UART主要由波特率发生器、接收模块、发送模块3部分组成,并具有l位停止位和无校验位。

波特率发生器实现波特率的变换,利用外部时钟信号产生一个所需波特率16倍的波特率时钟,用来控制UART的接收与发送。

接收模块是用于接收串行信号,并将其转化为并行数据;而发送模块则将准备输出的并行数据按照UART的帧格式转化为串行数据输出。

图2为UART结构图。

2.1 波特率发生器波特率表示的是每秒钟传送的二进制数据的位数,即单位时间内传送的信息量。

在串行异步传送中,常用到的波特率为1 200、2 400、4 800、9 600、19 200等。

波特率发生器实际上是一个分频器,主要是产生和。

RS-232通信所采用的波特率同步的时钟。

由于串行数据帧与接收数据时钟是异步的,所以存UA RT的接收端在什么时刻将数据移入寄存器,怎样选择可靠的采样点是非常关键的。

verilog编写的uart程序

verilog编写的uart程序

// UART_FPGA.v 顶层模块,实现由ARM控制FPGA读取串口数据,经过ARM返回给FPGA串口发送出去;`timescale 1ns/1nsmodule UART_FPGA(//EMIF PINinput wire [10:0] EADDR_pin /* synthesis syn_noclockbuf = 1 */,inout wire [15:0] EDATA_pin ,input wire EnOE_pin /* synthesis syn_noclockbuf = 1 */,input wire EnWE_pin /* synthesis syn_noclockbuf = 1 */,input wire EnGCS1_pin /* synthesis syn_noclockbuf = 1 */,output wire EINT2_pin ,//LED_runoutput wire LED_run_pin ,//UARToutput wire UART_TXD0 ,input wire UART_RXD0 /* synthesis syn_noclockbuf = 1 */,//test signaloutput wire TXD_test,output wire RXD_test,output reg TXD_start,output wire EINT2_test,output wire TXD_over_test,output wire uart_send_WR,//FPGA SYSTEM PINinput wire nRESET_pin /* synthesis syn_noclockbuf = 1 */,input wire CLK_50M_pin);wire [15:0] write_data;//-------------------DSP ARM uart to EMIF---------------------- reg [7:0] ARM_DSP_data;wire [7:0] DSP_ARM_data;reg uart_send_WR_reg;//reg [7:0] T_data;//reg [1:0] TXD_start_cnt;wire [7:0] R_data;wire R_ready;reg [2:0] UART_INT_cnt;wire TXD_over;wire [1:0] baud_select;reg [12:0] baud_devide;//wire clkrec;parameter baud_9600 = 5208; //50M/9600 parameter baud_19200 = 2604;parameter baud_38400 = 1302;parameter baud_115200 = 434;assign TXD_test = UART_TXD0;assign RXD_test = UART_RXD0;assign EINT2_test = EINT2_pin;assign TXD_over_test=TXD_over;/*--------------Program start-------------------*//*----------baud select------------*/always @( negedge nRESET_pin or posedge CLK_50M_pin ) beginif( !nRESET_pin )beginbaud_devide <= 'h1FFF;endelsebegincase ( baud_select )'d0 : baud_devide <= baud_9600 ;'d1 : baud_devide <= baud_19200 ;'d2 : baud_devide <= baud_38400 ;'d3 : baud_devide <= baud_115200 ;endcaseendend/*----------INT generator------------*/always @( negedge nRESET_pin or posedge R_ready )beginif( !nRESET_pin )beginARM_DSP_data <= 8'd0;endelsebeginARM_DSP_data <= R_data;endendalways @( negedge nRESET_pin or negedge R_ready or posedge CLK_50M_pin ) beginif( !nRESET_pin )beginUART_INT_cnt <= 3'd5;endelse if( !R_ready )beginUART_INT_cnt <= 3'd0;endelse if( UART_INT_cnt < 3'd5 )beginUART_INT_cnt <= UART_INT_cnt + 1'b1;endassign EINT2_pin = ( UART_INT_cnt >= 3'd1 && UART_INT_cnt <= 3'd4 ) ? 1'b0 : 1'b1 ;/*---------------DSP to ARM data---------------*/always@(negedge nRESET_pin or posedge CLK_50M_pin) //当接收了一个数据后,把数据加1后发回PC机,注意串口一个一个数据发beginif( !nRESET_pin )beginuart_send_WR_reg <= 1'b0;TXD_start <= 1'b0;endelse if( uart_send_WR_reg != uart_send_WR )beginif( TXD_over )beginTXD_start <= 1'b1;uart_send_WR_reg <= uart_send_WR;endendelsebeginTXD_start <= 1'b0;endend//----------------EMIF read ,fpga TO ARM---------------------------EMIF_R EMIF_R_M(.EADDR_pin (EADDR_pin ),.EDA TA_pin (EDA TA_pin ),.EnOE_pin (EnOE_pin ),.EnGCS1_pin (EnGCS1_pin ),.write_data (write_data ),.ARM_DSP_data (ARM_DSP_data ),.nRESET_pin (nRESET_pin )// .CLK_50M_pin (CLK_50M_pin )//----------------EMIF write,ARM to fpga---------------------------EMIF_W EMIF_W_M(.EADDR_pin (EADDR_pin ),.EDA TA_pin (EDATA_pin ),.EnWE_pin (EnWE_pin ),.EnGCS1_pin (EnGCS1_pin ),//uart.DSP_ARM_data (DSP_ARM_data ),.uart_send_WR (uart_send_WR ),.write_data (write_data ),.baud_select (baud_select ),//LED run.LED_run_pin (LED_run_pin ),.nRESET_pin (nRESET_pin )// .CLK_50M_pin (CLK_50M_pin ) );UART_rec UART_rec_M (//input.RXD (UART_RXD0 ),.baud_devide (baud_devide ),//output.R_data (R_data ),.R_ready (R_ready ),//FPGA sys pin.nRESET_pin (nRESET_pin ),.CLK_50M_pin (CLK_50M_pin));UART_txd UART_txd_M (//input.TXD_start (TXD_start ),.T_data (DSP_ARM_data ),.baud_devide (baud_devide ),//output.TXD (UART_TXD0 ),.TXD_over (TXD_over ),//FPGA sys pin.nRESET_pin (nRESET_pin ),.CLK_50M_pin (CLK_50M_pin));Endmodule// UART_rec.v`timescale 1ns/1nsmodule UART_rec (//inputRXD,baud_devide,//outputR_data,R_ready,//FPGA sys pinnRESET_pin,CLK_50M_pin);input wire RXD;input wire [12:0] baud_devide;output reg [7:0] R_data;output reg R_ready;input wire nRESET_pin;input wire CLK_50M_pin;reg [1:0] RXD_sync;reg [2:0] RXD_cnt;reg RXD_bit;reg [3:0] rec_bit_cnt;//reg [8:0] baud_16_reg;reg [12:0] baud_cnt;reg [8:0] baud_16_cnt;wire baud_tick_16;wire baud_tick;wire [11:0] baud_devide_2;wire [8:0] baud_devide_16;/*----------Program start------------*/assign baud_devide_2 = baud_devide / 2;assign baud_devide_16 = baud_devide / 16;/*--------------baud 16 devided clk used in sample-----------*/ always @( negedge nRESET_pin or posedge CLK_50M_pin ) beginif( !nRESET_pin )beginbaud_16_cnt <= 'd0;endelsebeginif( baud_16_cnt < baud_devide_16 )beginbaud_16_cnt <= baud_16_cnt + 1'b1;endelsebeginbaud_16_cnt <= 'd0;endendendassign baud_tick_16 = ( baud_16_cnt == baud_devide_16 );//--------baud clk used in receiving data-------always @( negedge nRESET_pin or posedge CLK_50M_pin )beginif( !nRESET_pin )beginbaud_cnt <= 'd0;endelsebeginif( !R_ready )beginif( baud_cnt < baud_devide - 1'b1 )beginbaud_cnt <= baud_cnt + 1'b1;endelsebeginbaud_cnt <= 'd0;endendelsebeginbaud_cnt <= 'd0;endendendassign baud_tick = ( baud_cnt == baud_devide_2 );/*-----------jitter filter--------------*/always @( negedge nRESET_pin or posedge CLK_50M_pin )beginif( !nRESET_pin )beginRXD_sync <= 2'd0;endelsebeginRXD_sync <= {RXD_sync[0], RXD};endendalways @( negedge nRESET_pin or posedge baud_tick_16 ) beginif( !nRESET_pin )beginRXD_cnt <= 3'd7;endelsebeginif( RXD_sync[1] && RXD_cnt != 3'd7 )beginRXD_cnt <= RXD_cnt + 1;endelsebeginif( ~RXD_sync[1] && RXD_cnt != 3'd0 )beginRXD_cnt <= RXD_cnt - 1;endendendendalways @( negedge nRESET_pin or posedge baud_tick_16 ) beginif( !nRESET_pin )beginRXD_bit <= 1'b1;endelsebeginif( RXD_cnt == 3'd7)beginRXD_bit <= 1'b1;endelse if( RXD_cnt == 3'd0 )beginRXD_bit <= 1'b0;endendend/*---------------receive data cnt---------------*/always @( negedge nRESET_pin or posedge CLK_50M_pin ) beginif( !nRESET_pin )beginR_ready <= 1'b1;rec_bit_cnt <= 4'd0;endelsebeginif( R_ready )beginrec_bit_cnt <= 4'd0;if( !RXD_bit )beginR_ready <= 1'b0;endendelse if( baud_tick )beginif( rec_bit_cnt < 4'd9 )beginrec_bit_cnt <= rec_bit_cnt + 1'b1;R_ready <= 1'b0;endelsebeginrec_bit_cnt <= 4'd0;R_ready <= 1'b1;endendendendalways @( negedge nRESET_pin or posedge baud_tick ) beginif( !nRESET_pin )beginR_data <= 8'd0;endelse if( !R_ready )beginif( rec_bit_cnt == 0 )beginR_data <= 8'd0;endelsebeginif( rec_bit_cnt >= 4'd1 && rec_bit_cnt<= 4'd8 )R_data[rec_bit_cnt - 1'b1 ] <= RXD_bit;endendendendmodule// UART_TXD.v`timescale 1ns/1nsmodule UART_txd (//inputbaud_devide,TXD_start,T_data,//outputTXD,TXD_over,//FPGA sys pinnRESET_pin,CLK_50M_pin);input wire TXD_start;input wire [7:0] T_data;input wire [12:0] baud_devide;output reg TXD;output reg TXD_over;input wire nRESET_pin;input wire CLK_50M_pin;//regs & wireswire baud_tick;//reg baud_ctrl;reg [3:0] T_state;reg [7:0] T_data_reg;reg [12:0] baud_cnt;/*----------Program start---------------*//*-----------------Baud generator------------------------*/assign baud_tick = ( baud_cnt == baud_devide - 1'b1 );always @( negedge nRESET_pin or posedge CLK_50M_pin ) beginif( !nRESET_pin )beginbaud_cnt <= 'd0;endelse if( baud_cnt < baud_devide - 1'b1 )beginbaud_cnt <= baud_cnt + 1'b1;endelsebeginbaud_cnt <= 'd0;endend/*----------transmit state machine---------------*/always @( negedge nRESET_pin or posedge CLK_50M_pin ) beginif( !nRESET_pin )beginT_state <= 4'd0;endelsebegincase(T_state)4'd0: if(TXD_start) T_state <= 4'd1;4'd1: if(baud_tick) T_state <= 4'd2; // 开始位04'd2: if(baud_tick) T_state <= 4'd3; // bit 04'd3: if(baud_tick) T_state <= 4'd4; // bit 14'd4: if(baud_tick) T_state <= 4'd5; // bit 24'd5: if(baud_tick) T_state <= 4'd6; // bit 34'd6: if(baud_tick) T_state <= 4'd7; // bit 44'd7: if(baud_tick) T_state <= 4'd8; // bit 54'd8: if(baud_tick) T_state <= 4'd9; // bit 64'd9: if(baud_tick) T_state <= 4'd10; // bit 74'd10: if(baud_tick) T_state <= 4'd0; // 停止位1default: if(baud_tick) T_state <= 4'd0;endcaseendendalways @(negedge nRESET_pin or posedge baud_tick ) beginif( !nRESET_pin )beginTXD <= 1'b1;T_data_reg <= 8'd0;endelsebegincase(T_state)// 4'd0: TXD <= 1'b1;4'd1: beginTXD <= 1'b0;T_data_reg <= T_data;end4'd2: TXD <= T_data_reg[0];4'd3: TXD <= T_data_reg[1];4'd4: TXD <= T_data_reg[2];4'd5: TXD <= T_data_reg[3];4'd6: TXD <= T_data_reg[4];4'd7: TXD <= T_data_reg[5];4'd8: TXD <= T_data_reg[6];4'd9: TXD <= T_data_reg[7];4'd10: TXD <= 1'b1;default: TXD <= 1'b1;endcaseendend//assign TXD = TXD;always @( negedge nRESET_pin or posedge CLK_50M_pin ) beginif( !nRESET_pin )beginTXD_over <= 1'b0;endelsebeginif( T_state ==4'd0 )TXD_over <= 1'b1;elseTXD_over <= 1'b0;endendendmodule。

计算机网络实验RS232串口通信程序的编写

计算机网络实验RS232串口通信程序的编写

计算机网络实验RS232串口通信程序的编写RS232是一种常见的串行通信接口,用于在计算机和其他外部设备之间传输数据。

它广泛应用于各种设备和应用程序,如串口调试工具、点阵打印机等。

本文将介绍如何编写一个基本的RS232串口通信程序。

我们将使用C 语言和Linux操作系统来演示。

在开始编写程序之前,我们需要了解一些RS232串口的基本概念和通信协议。

RS232串口由发送线(TX)、接收线(RX)、控制线(如RTS、CTS、DTR和DSR)等组成。

通信时,发送方将数据从TX线发送到接收方的RX线,然后接收方通过RX线接收数据。

以下是一个简单的RS232串口通信程序示例:```c#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <termios.h>#include <unistd.h>int maiint fd = open("/dev/ttyS0", O_RDWR , O_NOCTTY); // 打开串口设备if (fd == -1)perror("打开串口失败");exit(1);}struct termios options;tcgetattr(fd, &options); // 获取当前串口设置//设置波特率为9600cfsetispeed(&options, B9600);cfsetospeed(&options, B9600);//设置数据位为8位,无奇偶校验,停止位为1位options.c_cflag &= ~PARENB;options.c_cflag &= ~CSTOPB;options.c_cflag &= ~CSIZE;options.c_cflag ,= CS8;//更新串口设置tcsetattr(fd, TCSANOW, &options);char buffer[255];while (1)ssize_t len = read(fd, buffer, sizeof(buffer)); // 从串口读取数据if (len == -1)perror("读取串口失败");exit(1);}printf("接收到数据:%.*s\n", len, buffer);ssize_t nwrite = write(fd, buffer, len); // 向串口写入数据if (nwrite == -1)perror("写入串口失败");exit(1);}}close(fd);return 0;```该程序首先打开串口设备`/dev/ttyS0`,如果打开失败则会输出错误信息并退出。

verilog RS232 串口通信 verilog

verilog RS232 串口通信 verilog
//=============================顶层模块=====================================
module uart_top(clk,rs232_rx,rs232_tx);
input clk; //时钟信号50M
input rs232_rx; //数据输入信号
bps_start,
clk_bps,
rs232_rx,
rx_data,
rx_int
);
input clk; //50MHz时钟
input rst_n; //低电平复位信号
input rs232_rx; //接收数据信号
);
uart_rx uart_rx(//数据接收模块
.clk(clk),
.rst_n(rst_n),
.bps_start(bps_start1),
.clk_bps(clk_bps1),
.rs232_rx(rs232_rx),
.rx_data(rx_data),
else
begin
if(int_cnt<250) int_cnt<=int_cnt+1'b1;
end
end
assign data_flg=(int_cnt==10)?1'b1:1'b0;
always @(posedge data_flg or negedge rst_n)
output rs232_tx; //数据输出信号
wire clk_bps1,clk_bps2;
wire bps_start1,bps_start2;
wire [7:0] rx_data;

nexys3开发板uart控制器设计实验原理

nexys3开发板uart控制器设计实验原理

nexys3开发板uart控制器设计实验原理Nexys3开发板是一款基于Xilinx Spartan-6 FPGA的高性能开发板,具有丰富的外设资源。

其中,UART(Universal Asynchronous Receiver Transmitter)控制器是一种用于实现串行通信的硬件设备,常用于与计算机以及其他外部设备之间进行数据传输。

本文将介绍Nexys3开发板UART控制器设计实验的原理。

UART控制器是一种用于实现串口通信的设备,通过将并行数据转换为串行数据,实现计算机与其他设备之间的通信。

在UART控制器的设计中,主要涉及到串行数据的发送和接收以及波特率的设置。

首先,串行数据发送。

UART通过将输入的并行数据进行排列,并通过将各个数据位的电平状态依次编码为高低电平,生成串行的数据流。

具体实现方法是,将每个数据位与开始位、数据位、停止位以及奇偶校验位拼接起来,形成一个数据帧,然后将数据帧按照波特率的速率依次发送。

在Nexys3开发板上,通过使用片上资源来实现数据位和相应控制位的读取和输出,通过GPIO来控制串行输出引脚的电平状态。

其次,串行数据接收。

UART通过监测接收引脚的电平状态,识别开始位、数据位、停止位以及奇偶校验位,然后对数据进行解码,恢复为原始的并行数据。

在Nexys3开发板上,通过读取接收引脚的电平状态,通过相应的逻辑电路进行译码和解码,然后将数据保存在缓冲区中,供后续的处理和使用。

最后,波特率的设置。

波特率是串口通信中非常重要的参数,它决定了数据传输的速率。

在Nexys3开发板上,可以通过修改FPGA中UART控制器的时钟频率来设置波特率。

通过调整时钟频率,可以改变数据传输的速率,使其与外部设备匹配。

在设计实验中,需要编写相应的Verilog代码来实现UART控制器。

首先,需要定义输入和输出的信号,包括接收引脚、发送引脚、时钟信号以及数据缓冲区等。

然后,需要编写发送和接收相关的逻辑电路,包括数据的排列和解析,以及时钟频率的计算和传输控制等。

ISE软件使用说明

ISE软件使用说明

说明这个说明主要介绍了使用开发板可能使用到的3个工具,主要以串口功能的实现作为例子,讲述了ISE, Plantform和EDK的使用方法以及操作的基本流程。

ISE的使用一.启动Xilinx ISE:开始Æ所有程序ÆXilinx ISE 7.1iÆProject Navigator二.新建/打开一个工程:如果已经有了工程,则在FileÆOpen Project弹出的对话框里面选择你的工程。

如果没有合适的工程就需要通过FileÆNew Project来新建一个工程。

具体操作步骤如下:分别在Project Name和Project Location里面填写您想要创建的工程的名称和路径。

在Top-Level Module Type的下拉菜单里面选择您的工程的顶层模块的类型。

本次串口通信的实验的顶层为原理图,所以选择Schematic。

然后点击下一步:在这个对话框的上半部分选择您使用的芯片的族(Spartan3),型号(xc3s400),封装(pq208)和速度(-4)。

下面选择您要使用编译和综合的软件,建议使用ISE自带的软件,一是使用简便,二是Xilinx公司对自己的FPGA了解程度比第三方要高很多,所以使用Xilinx公司自己的软件有的时候会获得意想不到的收获。

具体参数选择如图,然后单击下一步:在这个对话框里面新建工程里面的文件,这步也可以放到后面来实现,这里我们先选择下一步:这一步用来添加已经存在的文件,同样,我们在后面实现这步。

点击下一步:在最后这个对话框里面显示了我们即将建立的工程的详细信息,确认无误以后点击完成,ISE将为您创建一个名字为uart_test的工程:三.为刚创建的工程添加源文件:1.添加已经存在的源文件:选中屏幕右上的xc3s400-4pq208,单击ProjectÆAdd Source,在弹出的对话框里面选择您已经存在的程序文件(.v .vhd)。

verilog串口通信程序【精选文档】

verilog串口通信程序【精选文档】

FPGA实现RS-232串口收发的仿真过程(Quartus+Synplify+ModelSim)(2007-09-11 12:17:37)网上关于RS—232的异步收发介绍得很多,最近没事学着摸索用ModelSim来做时序仿真,就结合网上的参考资料和自己的琢磨,做了这个东西.针对我这个小程序结合FPGA的开发流程,主要走了以下几步:1。

文本程序输入(Verilog HDL)2。

功能仿真(ModelSim,查看逻辑功能是否正确,要写一个Test Bench)3。

综合(Synplify Pro,程序综合成网表)4. 布局布线(Quartus II,根据我选定的FPGA器件型号,将网表布到器件中,并估算出相应的时延)5。

时序仿真(ModelSim,根据时延做进一步仿真)这里贴出我的程序和各个详细步骤,能和各位正在学习的新手们一起分享。

0。

原理略一、文本程序输入(Verilog HDL)发送端:module trans(clk,rst,TxD_start,TxD_data,TxD,TxD_busy);input clk,rst,TxD_start;input[7:0]TxD_data; // 待发送的数据output TxD, // 输出端口发送的串口数据TxD_busy;reg TxD;reg [7:0] TxD_dataReg; // 寄存器发送模式,因为在串口发送过程中输入端不可能一直保持有效电平reg [3:0]state;parameter ClkFrequency = 25000000;// 时钟频率-25 MHzparameter Baud = 115200;// 串口波特率-115200// 波特率产生parameter BaudGeneratorAccWidth = 16;reg [BaudGeneratorAccWidth:0]BaudGeneratorAcc;wire [BaudGeneratorAccWidth:0] BaudGeneratorInc = ((Baud〈<(BaudGeneratorAccWidth—4))+(ClkFrequency>>5))/(ClkFrequency>〉4);wire BaudTick = BaudGeneratorAcc[BaudGeneratorAccWidth];wire TxD_busy;always @(posedge clk or negedge rst)if(~rst)BaudGeneratorAcc <= 0;else if(TxD_busy)BaudGeneratorAcc <= BaudGeneratorAcc[BaudGeneratorAccWidth-1:0]+ BaudGeneratorInc;// 发送端状态wire TxD_ready = (state==0);// 当state = 0时,处于准备空闲状态,TxD_ready = 1 assign TxD_busy = ~TxD_ready; // 空闲状态时TxD_busy = 0// 把待发送数据放入缓存寄存器TxD_dataRegalways @(posedge clk or negedge rst)if(~rst)TxD_dataReg <= 8’b00000000;else if(TxD_ready &TxD_start)TxD_dataReg <= TxD_data;// 发送状态机always @(posedge clk or negedge rst)if(~rst)beginstate 〈= 4’b0000;// 复位时,状态为0000,发送端一直发1电平TxD <= 1'b1;endelsecase(state)4’b0000: if(TxD_start) beginstate <= 4’b0100;// 接受到发送信号,进入发送状态end4’b0100: if(BaudTick) beginstate <= 4’b1000;// 发送开始位—0电平TxD <= 1'b0;end4'b1000: if(BaudTick)beginstate <= 4'b1001;// bit 0TxD <= TxD_dataReg[0];end4'b1001:if(BaudTick) beginstate <= 4’b1010; // bit 1TxD 〈= TxD_dataReg[1];end4’b1010:if(BaudTick) beginstate <= 4'b1011; // bit 2TxD <= TxD_dataReg[2];end4'b1011:if(BaudTick)beginstate <= 4'b1100; // bit 3TxD 〈= TxD_dataReg[3];end4'b1100: if(BaudTick) beginstate 〈= 4’b1101;// bit 4TxD <= TxD_dataReg[4];end4'b1101:if(BaudTick) beginstate 〈= 4’b1110;// bit 5TxD 〈= TxD_dataReg[5];end4'b1110:if(BaudTick) beginstate <= 4’b1111; // bit 6TxD <= TxD_dataReg[6];end4’b1111:if(BaudTick) beginstate 〈= 4’b0010;// bit 7TxD <= TxD_dataReg[7];end4'b0010: if(BaudTick) beginstate 〈= 4'b0011;// stop1TxD 〈= 1’b1;end4’b0011:if(BaudTick)beginstate 〈= 4’b0000;// stop2TxD 〈= 1'b1;enddefault: if(BaudTick)beginstate 〈= 4’b0000;TxD 〈= 1’b1;endendcaseendmodule接收端:module rcv(clk,rst,RxD,RxD_data,RxD_data_ready,);input clk,rst,RxD;output[7:0] RxD_data; // 接收数据寄存器output RxD_data_ready;// 接收完8位数据,RxD_data 值有效时,RxD_data_ready 输出读信号parameter ClkFrequency = 25000000;// 时钟频率-25MHzparameter Baud = 115200; // 波特率-115200reg[2:0]bit_spacing;reg RxD_delay;reg RxD_start;reg[3:0] state;reg[7:0]RxD_data;reg RxD_data_ready;// 波特率产生,使用8倍过采样parameter Baud8 = Baud*8;parameter Baud8GeneratorAccWidth = 16;wire [Baud8GeneratorAccWidth:0]Baud8GeneratorInc = ((Baud8〈<(Baud8GeneratorAccWidth—7))+(ClkFrequency>〉8))/(ClkFrequency>>7);reg [Baud8GeneratorAccWidth:0]Baud8GeneratorAcc;always @(posedge clk or negedge rst)if(~rst)Baud8GeneratorAcc 〈= 0;elseBaud8GeneratorAcc <= Baud8GeneratorAcc[Baud8GeneratorAccWidth—1:0] + Baud8GeneratorInc;// Baud8Tick 为波特率的8倍-115200*8 = 921600wire Baud8Tick = Baud8GeneratorAcc[Baud8GeneratorAccWidth];// next_bit 为波特率-115200always @(posedge clk or negedge rst)if(~rst||(state==0))bit_spacing 〈= 0;else if(Baud8Tick)bit_spacing <= bit_spacing + 1;wire next_bit = (bit_spacing==7);// 检测到RxD 有下跳沿时,RxD_start 置1,准备接收数据always@(posedge clk)if(Baud8Tick)beginRxD_delay 〈= RxD;RxD_start <= (Baud8Tick & RxD_delay & (~RxD));end// 状态机接收数据always@(posedge clk or negedge rst)if(~rst)state 〈= 4’b0000;else if(Baud8Tick)case(state)4'b0000:if(RxD_start)state <= 4’b1000;// 检测到下跳沿4’b1000: if(next_bit)state 〈= 4'b1001;// bit 04'b1001: if(next_bit) state <= 4'b1010;// bit 14’b1010:if(next_bit) state 〈= 4’b1011; // bit 24’b1011: if(next_bit) state <= 4'b1100;// bit 34’b1100: if(next_bit)state 〈= 4'b1101;// bit 44'b1101:if(next_bit)state <= 4’b1110; // bit 54'b1110: if(next_bit) state <= 4'b1111; // bit 64'b1111: if(next_bit) state 〈= 4'b0001; // bit 74'b0001: if(next_bit) state 〈= 4’b0000;// 停止位default: state <= 4'b0000;endcase// 保存接收数据到RxD_data 中always @(posedge clk or negedge rst)if(~rst)RxD_data 〈= 8’b00000000;else if(Baud8Tick &&next_bit && state[3])RxD_data <= {RxD,RxD_data[7:1]};// RxD_data_ready 置位信号always @(posedge clk or negedge rst)if(~rst)RxD_data_ready <= 0;elseRxD_data_ready <= (Baud8Tick && next_bit &&state==4'b0001); endmodule为了测试收发是否正常,写的Test Bench`timescale 1ns / 1nsmodule rs232_test;reg clk,rst,TxD_start;reg [7:0]TxD_data;wire[7:0] RxD_data;wire //RxD,TxD,TxD_busy,RxD_data_ready;trans trans(.clk(clk),。

fpga利用io口实现rs422通信的代码

fpga利用io口实现rs422通信的代码

fpga利用io口实现rs422通信的代码RS422通信是一种全双工、差分信号传输的串行通信协议。

相较于RS232通信协议,RS422通信协议传输距离更远、传输速度更快、噪声干扰更小,并且能够支持多个设备同时通信。

在本文中,我们将介绍如何利用FPGA的IO口实现RS422通信。

首先,我们需要为FPGA选择一个支持RS422协议的IO口。

以下是常用的几种IO口:1. 差分输出:FPGA通过两个相反的信号线向外输出差分信号。

3. 孤立输入:FPGA通过单一信号线接收差分信号,并通过内部电路将差分信号转换为单压缩信号。

在本文中,我们将选择差分输入的方式进行RS422通信。

接下来,我们需要配置FPGA的IO口。

一般来说,FPGA会提供相应的IP核用于配置IO口,我们可以通过IP核配置管理器进行配置。

以下是常见的IO口配置:1. 设置IO口的功能:将IO口设置为输入、输出或双向模式。

2. 设置IO口的电平:确定IO口的高电平和低电平的电压值。

3. 设置IO口的上下拉电阻:控制IO口的输入输出电阻。

4. 设置IO口的保护电路:为了保护IO口不受过电压或过电流的损坏,通常需要为IO 口配置保护电路。

接下来,我们可以开始编写FPGA的代码。

以下是实现RS422通信的代码:```verilogmodule RS422 (input clk, //时钟信号input rst, //复位信号input [7:0] rx, //接收端口output [7:0] tx, //发送端口output de, //差分输出使能output re, //差分输入使能output [1:0] ie //输入使能);//定义常量localparam BIT_CNT = 8; //一帧数据位数 localparam CNT_MAX = 16'h3FFF; //计数器最大值 localparam BAUD_RATE = 9600; //波特率//计数器reg [15:0] cnt;always @(posedge clk or posedge rst) beginif (rst) begincnt <= 0;end else beginif (cnt >= CNT_MAX) begincnt <= 0;end else begincnt <= cnt + 1;endendend//接收数据wire [BIT_CNT-1:0] rx_data;reg rx_flag;reg rx_err;reg rx_done;uart_rx #(BIT_CNT) uart_rx_inst (.rx(rx),.clk(clk),.rst(rst),.data(rx_data),.flag(rx_flag),.err(rx_err),.done(rx_done));assign tx = tx_data;//差分接收器使能信号assign re = 1;//输入使能assign ie[0] = tx_done;assign ie[1] = rx_done;endmodule```以上代码中,我们使用了一个基于计数器的时序生成器来产生波特率同步信号,用于控制发送和接收的时序。

基于FPGA的串口通信电路设计

基于FPGA的串口通信电路设计

基于FPGA的串口通信电路设计[摘要]串行通信接口是一种应用广泛的通信接口。

目前,大部分处理器都集成了支持rs-232接口的通用异步收发器,本文基于fpga开发板设计了一个串口数据采集和处理程序,介绍了用verilog hdl硬件描述语言来开发波特率发生器、接收模块和发送模块这三个模块,以及系统各个模块的具体设计方法和原理,用quartus ii软件进行仿真并给出结果,分别验证各个模块的正确性及用fpga实现串行通信的可行性。

[关键词]串行通信 rs-232 verilog hdl fpga中图分类号:tn 文献标识码:a 文章编号:1009-914x(2013)08-320-011.fpga概述fpga现场可编程逻辑门阵列是数字系统设计的主要硬件平台,其主要特点是完全由用户通过软件进行配置和编程,从而完成某种特定的功能,且可以反复擦写。

fpga具有运算速度快、根据需求在内部嵌入硬/软ip核,以及反复编程,擦写,使用的特点,被广泛应用于通信,数字信号处理,工业控制等领域。

2.rs232串口通信接口串口即串行数据接口主要用于网管控制或主业务数据的传输,支持数据的双向传输,速率9600-115200bps,即可以完成和pc的通信,也可以完成与带有标准串口的外设相连。

其中串口接口分为带插孔和带插针的两种,其中插针端称为dce,插孔端称为dte。

3.串口通信的verilog hdl实现本设计要求在fpga开发板上实现波特率为115200bps,停止位为1比特、1比特校验位的串口通信,并要求和pc机通过串口调试助手完成双向通信。

3.1波特率发生器模块的verilog hdl实现波特率发生器实际上是一个分频器,从给定的系统时钟频率得到要求的波特率。

一般来讲,为了提高系统的容错性处理,要求波特率发生器的输出时钟为实际串口数据波特率的n倍,n可以取值为8、16、32、64等。

在本设计中,系统的时钟为50mhz,取n为16,则分频系数为50000000/(16*115200)=27.127,取整为27。

uart的基本编程步骤

uart的基本编程步骤

uart的基本编程步骤UART(通用异步收发传输)是一种常见的串行通信协议,用于在微控制器和外部设备之间进行数据传输。

下面是UART的基本编程步骤:1. 初始化UART,首先,你需要在微控制器上初始化UART模块。

这通常涉及设置波特率(通信速率)、数据位、停止位和校验位等参数。

这些参数的设置取决于你的具体应用需求和外部设备的要求。

2. 配置引脚,UART通常使用两个引脚进行数据传输,一个用于发送(TX),一个用于接收(RX)。

你需要在微控制器上配置这些引脚,并确保它们与外部设备正确连接。

3. 发送数据,要发送数据,你需要将要发送的数据加载到UART发送缓冲区。

一旦数据被加载,UART模块将自动开始发送数据。

你需要确保发送的数据符合UART的规范,并且在发送数据之前,需要检查发送缓冲区是否为空,以避免数据丢失。

4. 接收数据,接收数据与发送类似,你需要设置接收缓冲区,并在接收到数据后从中读取数据。

同样,你需要检查接收缓冲区是否有新的数据可用,以避免数据丢失。

5. 中断处理(可选),在一些情况下,你可能需要使用中断来处理UART的发送和接收。

这可以帮助你及时响应数据的到来或发送完成等事件。

6. 错误处理,最后,你需要考虑如何处理可能出现的错误,比如数据丢失、校验错误等。

这可能涉及到错误标志的检查和相应的处理流程。

总的来说,UART的基本编程步骤包括初始化UART模块、配置引脚、发送数据、接收数据、中断处理(可选)和错误处理。

在实际编程中,你需要根据具体的微控制器型号和外部设备的通信协议要求来进行相应的设置和处理。

基于FPGA的ASIC设计

基于FPGA的ASIC设计

基于FPGA的ASIC设计—RS232接口功能一、设计说明为了配合课程设计,完成RS232通信功能,以Verilog为硬件描述语言在FPGA开发板上实现串行通信的接受和发送模块,通过本项目掌握基于FPGA的ASIC设计的流程方法。

1. RS232介绍RS232是一种异步串行通信接口,RS232只是一个物理层的标准,只规定了信号物理特性,链路层的协议是UART,RS232接口的逻辑设计就是这部分内容。

其设置包括三部分:波特率、奇偶校验、停止位。

所谓波特率,指单位时间内传送二进制数据的位数,以位/ 秒为单位,是衡量串行数据传输快慢的重要指标。

如果某串口的波特率为115 200,指的是该串口以115 200bits/s 的速率在传输数据。

奇偶校验:是用来验证数据的正确性。

奇偶校验是通过修改每一发送字节(也可以限制发送的字节)来工作的。

在偶校验中,因为奇偶校验位会被相应的置1或0(一般是最高位或最低位),所以数据会被改变以使得所有传送的数位(含字符的各数位和校验位)中“1”的个数为偶数;在奇校验中,所有传送的数位(含字符的各数位和校验位)中“1”的个数为奇数。

奇偶校验可以用于接受方检查传输是否发送生错误——如果某一字节中“1”的个数发生了错误,那么这个字节在传输中一定有错误发生。

如果奇偶校验是正确的,那么要么没有发生错误要么发生了偶数个的错误。

停止位:是在每个字节传输之后发送的,它用来帮助接受信号方硬件重同步。

2. RS232的特性使用9针的"DB-9"插头(它一共有9个引脚,最重要的3个引脚是:引脚2 RxD (接收数据). 引脚3: TxD (发送数据). 引脚5: GND (地)). 允许全双工的双向通讯,最大可支持的传输速率为10KBytes/sRS232通信线上的电平RS-323标准对逻辑电平的定义。

对于数据(信息码):逻辑“1”(传号)的电平低于-3V,逻辑“0”(空号)的电平高于+3V;对于控制信号;接通状态(ON)即信号有效的电平高于+3V,断开状态(OFF)即信号无效的电平低于-3V,也就是当传输电平的绝对值大于3V时,电路可以有效地检查出来,介于-3~+3V之间的电压无意义,低于-15V或高于+15V的电压也认为无意义,因此,实际工作时,应保证电平在±(3~15)V之间。

基于FPGA的UART通信接口电路设计

基于FPGA的UART通信接口电路设计

基于FPGA的UART通信接口电路设计张蕾【摘要】随着煤矿设备自动化程度的不断提高,对信号的传输也提出了越来越高的要求.本文设计了一种基于现场可编程门阵列(field programmable gate array,FPGA)的RS232接口电路.首先,分析了FPGA在设计通用串行收发器(universal asynchronous receiver and transmitter,UART)接口电路中的优势.该接口电路主要分为UART接收子模块、波特率发生器、先进先出(first in first out,FIFO)模块、UART发送子模块、通信校验模块等.然后,基于Xilinx公司的FPGA平台,使用Verilog HDL语言编写并实现了整个系统,给出了完整的电路结构框图及实验结果.实验结果验证了所设计RS232接口电路的有效性.【期刊名称】《山西焦煤科技》【年(卷),期】2011(035)008【总页数】3页(P18-20)【关键词】通用串行收发器(UART);可编程门阵列(FPGA);过采样;先进先出(FIFO)【作者】张蕾【作者单位】山西煤炭进出口集团有限公司,山西太原 030006【正文语种】中文【中图分类】TD65目前,我国的煤矿设备自动化程度不断提高,井下作业对信号传输的要求也愈趋严格。

本文研究的通用串行收发器(universal asynchronous receiver and transmitter,UART)可通过串行线传输并行数据,其本质功能是作为控制器和串行设备间的编码转换装置,在基于RS232、RS485等标准协议的通信系统中广泛应用[1-3],非常适合矿井通信系统。

常用的单片机、DSP控制器等一般都集成有专用的UART外设,极大地方便了基于RS232等协议的通信系统设计。

但这类预先固化好的系统也存在一定的不足,如工作模式不够灵活,数据位数固定、通信的波特率一般限制在几个固定的数值,可扩展性较小。

示波器UARTRS232422485解码实例

示波器UARTRS232422485解码实例
1
广州致远电子有限公司
电子测量仪器-示波器
图错误!文档中没有指定样式的文字。.2 波特率自定义
据通道信号数据的最小脉宽的倒数来估算通道信号的波特率。 结束位宽
结束位为一段数据的结束标志,可以设置为 1 位,1.5 位,2 位。默认为 1 位。 校验模式
校验位可有可无,用户可根据自己的具体需要设置。ZDS3000/4000 系列示波器校验模 式可选择:Even(偶校验)、Odd(奇校验)、Mark(填充 1)、Space(填充 0)、None(无校 验)。默认为 None(无校验)。
5、 用户按下【协议参数】软键,旋转旋钮 A 可选中参数,短按旋钮 A 可以对协议参数进 行设置,其中包括总线设置与触发设置,如图错误!文档中没有指定样式的文字。.1。
图错误!文档中没有指定样式的文字。.1 解码协议参数
(1) 总线设置 总线设置中包括对 7 个指标的设置,下面分别对其进行介绍。 通道使能
3
广州致远电子有限公司
电子测量仪器-示波器
6、 用户在设置好【协议参数】后,就可以按下【解码设置】软键,对协议进行解码,其中 包括对【阈值设置】、【显示方式】与【细节显示】;
7、 按下【事件表】软键,使其显示“ON”,用户可以通过查看事件表更清晰地了解 UART 协议信号。同时可以通过旋转旋钮 B 来查看各个事件,在停止状态下,短按旋钮 B 可 定位到选中的解码事件。如图错误!文档中没有指定样式的文字。.5。在停止状态下可 点击【事件导出】,具体可参考 16.2.2 报表生成。
在协议进行触发时,要注意设置合适的触发电平,在协议解码操作时,要注意设置合适 的解码阈值。
1.1.1UART 解码操作步骤
1、 将 UART 的 TXD 接到通道 1 中,点击【Auto Setup】一键捕获波形,让波形以最好的效 果显示在界面中;

基于FPGA的UART设计的Verilog实现程序

基于FPGA的UART设计的Verilog实现程序

module clkdiv (clk,clkout);input clk; //系统时钟output clkout; //采样时钟输出reg clkout;reg [24:0] cnt;//分频进程always @(posedge clk)beginif(cnt == 24'd162)beginclkout <= 1'b1;cnt <= cnt + 24'd1;endelse if(cnt == 24'd324)beginclkout <= 1'b0;cnt <= 24'd0;endelsebegincnt <= cnt + 24'd1;endendendmodule/*******************发送模块********************************/ module urattx(clk,datain,wrsig,idle,tx);input clk; //UART时钟input [7:0] datain; //需要发送的数据input wrsig; //发送命令,上升沿有效output idle; //线路状态指示,高为线路忙,地为线路空闲output tx; //发送数据信号reg idle,tx;reg send;reg wrsigbuf,wrsigrise;reg presult;reg [7:0] cnt; //计数器parameter paritymode = 1'b0;//检测发送命令是否有效always @(posedge clk)beginwrsigbuf <= wrsig;wrsigrise <=(~wrsigbuf)&wrsig;endalways @(posedge clk)beginif(wrsigrise && (~idle)) //当发送命令有效且线路为空闲时,启动新的数据发送进程beginsend <=1'b1;endelse if(cnt == 8'd176) //一帧资料发送结束beginsend <=1'b0;endendalways @(posedge clk)beginif(send <=1'b1)begincase(cnt)8'd0: //产生起始位begintx <= 1'b0;idle <= 1'b1;cnt <= cnt + 8'd1;end8'd16:begintx <= datain[0]; //发送数据0位presult <= datain[0]^paritymode;idle <= 1'b1;cnt <= cnt + 8'd1;end8'd32:begintx <= datain[1]; //发送数据1位presult <= datain[1]^presult;idle <= 1'b1;cnt <= cnt + 8'd1;end8'd48:begintx <= datain[2]; //2presult <= datain[2]^presult;idle <= 1'b1;cnt <= cnt + 8'd1;end8'd64:begintx <= datain[3]; //3presult <= datain[3]^presult;idle <= 1'b1;cnt <= cnt + 8'd1;end8'd80:begintx <= datain[4]; //4presult <= datain[4]^presult;idle <= 1'b1;cnt <= cnt + 8'd1;end8'd96:begintx <= datain[5]; //5presult <= datain[5]^presult;idle <= 1'b1;cnt <= cnt + 8'd1;end8'd112:begintx <= datain[6]; //6presult <= datain[6]^presult;idle <= 1'b1;cnt <= cnt + 8'd1;end8'd128:begintx <= datain[7]; //7presult <= datain[7]^presult;idle <= 1'b1;cnt <= cnt + 8'd1;end8'd144:begintx <= presult; //发送奇偶校验位presult <= datain[0]^paritymode;idle <= 1'b1;cnt <= cnt + 8'd1;end8'd160:begintx <=1'b1; //发送停止位idle <=1'b1;cnt <=cnt +8'd1;end8'd176:begintx <=1'b1;idle <=1'b0; //一帧资料发送结束cnt <= cnt + 8'd1;enddefault:begincnt<=cnt +8'd1;endendcaseendelsebegintx <= 1'b1;cnt <= 8'd0;idle <=1'b0;endendendmodule。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

module my_uart_top(clk,rst_n,rs232_rx,rs232_tx);input clk; lk(clk), st_n(rst_n),.bps_start(bps_start1),.clk_bps(clk_bps1),);my_uart_rx my_uart_rx(.clk(clk), st_n(rst_n),.rs232_rx(rs232_rx),.rx_data(rx_data),.rx_int(rx_int),.clk_bps(clk_bps1),%.bps_start(bps_start1));lk(clk), st_n(rst_n),.bps_start(bps_start2),.clk_bps(clk_bps2));`my_uart_tx my_uart_tx(.clk(clk), st_n(rst_n),.rx_data(rx_data),.rx_int(rx_int),.rs232_tx(rs232_tx),.clk_bps(clk_bps2),.bps_start(bps_start2));.endmodulemodule my_uart_rx(clk,rst_n,rs232_rx,rx_data,rx_int,…clk_bps,bps_start);input clk; // 50MHz主时钟input rst_n; //低电平复位信号input rs232_rx; // RS232接收数据信号input clk_bps; // clk_bps的高电平为接收或者发送数据位的中间采样点output bps_start; //接收到数据后,波特率时钟启动信号置位`output[7:0] rx_data; //接收数据寄存器,保存直至下一个数据来到output rx_int; //接收数据中断信号,接收到数据期间始终为高电平//----------------------------------------------------------------reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3; //接收数据寄存器,滤波用wire neg_rs232_rx; //表示数据线接收到下降沿always @ (posedge clk or negedge rst_n) begin{if(!rst_n) beginrs232_rx0 <= 1'b0;rs232_rx1 <= 1'b0;rs232_rx2 <= 1'b0;rs232_rx3 <= 1'b0;endelse beginrs232_rx0 <= rs232_rx;:rs232_rx1 <= rs232_rx0;rs232_rx2 <= rs232_rx1;rs232_rx3 <= rs232_rx2;endend//下面的下降沿检测可以滤掉<20ns-40ns的毛刺(包括高脉冲和低脉冲毛刺),//这里就是用资源换稳定(前提是我们对时间要求不是那么苛刻,因为输入信号打了好几拍)//(当然我们的有效低脉冲信号肯定是远远大于40ns的),assign neg_rs232_rx = rs232_rx3 & rs232_rx2 & ~rs232_rx1 & ~rs232_rx0; //接收到下降沿后neg_rs232_rx置高一个时钟周期//----------------------------------------------------------------reg bps_start_r;reg[3:0] num; //移位次数reg rx_int; //接收数据中断信号,接收到数据期间始终为高电平always @ (posedge clk or negedge rst_n)#if(!rst_n) beginbps_start_r <= 1'bz;rx_int <= 1'b0;endelse if(neg_rs232_rx) begin //接收到串口接收线rs232_rx的下降沿标志信号bps_start_r <= 1'b1; //启动串口准备数据接收rx_int <= 1'b1; //接收数据中断信号使能end—else if(num==4'd12) begin //接收完有用数据信息bps_start_r <= 1'b0; //数据接收完毕,释放波特率启动信号rx_int <= 1'b0; //接收数据中断信号关闭endassign bps_start = bps_start_r;//----------------------------------------------------------------~reg[7:0] rx_data_r; //串口接收数据寄存器,保存直至下一个数据来到//----------------------------------------------------------------reg[7:0] rx_temp_data; //当前接收数据寄存器always @ (posedge clk or negedge rst_n)if(!rst_n) beginrx_temp_data <= 8'd0;…num <= 4'd0;rx_data_r <= 8'd0;endelse if(rx_int) begin //接收数据处理if(clk_bps) begin //读取并保存数据,接收数据为一个起始位,8bit数据,1或2个结束位num <= num+1'b1;case (num)4'd1: rx_temp_data[0] <= rs232_rx; //锁存第0bit》4'd2: rx_temp_data[1] <= rs232_rx; //锁存第1bit4'd3: rx_temp_data[2] <= rs232_rx; //锁存第2bit4'd4: rx_temp_data[3] <= rs232_rx; //锁存第3bit4'd5: rx_temp_data[4] <= rs232_rx; //锁存第4bit4'd6: rx_temp_data[5] <= rs232_rx; //锁存第5bit4'd7: rx_temp_data[6] <= rs232_rx; //锁存第6bit4'd8: rx_temp_data[7] <= rs232_rx; //锁存第7bitdefault: ;*endcaseendelse if(num == 4'd12) begin //我们的标准接收模式下只有1+8+1(2)=11bit的有效数据num <= 4'd0; //接收到STOP位后结束,num清零rx_data_r <= rx_temp_data; //把数据锁存到数据寄存器rx_data中endend,assign rx_data = rx_data_r;endmodulemodule speed_select(clk,rst_n,-bps_start,clk_bps);input clk; // 50MHz主时钟input rst_n; //低电平复位信号input bps_start; //接收到数据后,波特率时钟启动信号置位output clk_bps; // clk_bps的高电平为接收或者发送数据位的中间采样点】/*parameter bps9600 = 5207, //波特率为9600bpsbps19200 = 2603, //波特率为19200bpsbps38400 = 1301, //波特率为38400bpsbps57600 = 867, //波特率为57600bpsbps115200 = 433; //波特率为115200bpsparameter bps9600_2 = 2603,~bps19200_2 = 1301,bps38400_2 = 650,bps57600_2 = 433,bps115200_2 = 216;*///以下波特率分频计数值可参照上面的参数进行更改`define BPS_PARA 5207 //波特率为9600时的分频计数值}`define BPS_PARA_2 2603 //波特率为9600时的分频计数值的一半,用于数据采样reg[12:0] cnt; //分频计数reg clk_bps_r; //波特率时钟寄存器//----------------------------------------------------------reg[2:0] uart_ctrl; // uart波特率选择寄存器//----------------------------------------------------------[always @ (posedge clk or negedge rst_n)if(!rst_n) cnt <= 13'd0;else if((cnt == `BPS_PARA) || !bps_start) cnt <= 13'd0; //波特率计数清零else cnt <= cnt+1'b1; //波特率时钟计数启动always @ (posedge clk or negedge rst_n)if(!rst_n) clk_bps_r <= 1'b0;:else if(cnt == `BPS_PARA_2) clk_bps_r <= 1'b1; // clk_bps_r高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点else clk_bps_r <= 1'b0;assign clk_bps = clk_bps_r;endmodule)module my_uart_tx(clk,rst_n,rx_data,rx_int,rs232_tx,clk_bps,bps_start);input clk; // 50MHz主时钟input rst_n; //低电平复位信号?input clk_bps; // clk_bps_r高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点input[7:0] rx_data; //接收数据寄存器input rx_int; //接收数据中断信号,接收到数据期间始终为高电平,在该模块中利用它的下降沿来启动串口发送数据output rs232_tx; // RS232发送数据信号output bps_start; //接收或者要发送数据,波特率时钟启动信号置位//---------------------------------------------------------reg rx_int0,rx_int1,rx_int2; //rx_int信号寄存器,捕捉下降沿滤波用#wire neg_rx_int; // rx_int下降沿标志位always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginrx_int0 <= 1'b0;rx_int1 <= 1'b0;rx_int2 <= 1'b0;end}else beginrx_int0 <= rx_int;rx_int1 <= rx_int0;rx_int2 <= rx_int1;endendassign neg_rx_int = ~rx_int1 & rx_int2; //捕捉到下降沿后,neg_rx_int拉高保持一个主时钟周期》//---------------------------------------------------------reg[7:0] tx_data; //待发送数据的寄存器//---------------------------------------------------------reg bps_start_r;reg tx_en; //发送数据使能信号,高有效reg[3:0] num;|always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginbps_start_r <= 1'bz;tx_en <= 1'b0;tx_data <= 8'd0;endelse if(neg_rx_int) begin //接收数据完毕,准备把接收到的数据发回去bps_start_r <= 1'b1;}tx_data <= rx_data; //把接收到的数据存入发送数据寄存器tx_en <= 1'b1; //进入发送数据状态中endelse if(num==4'd11) begin //数据发送完成,复位bps_start_r <= 1'b0;tx_en <= 1'b0;endend;assign bps_start = bps_start_r;//---------------------------------------------------------reg rs232_tx_r;always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginnum <= 4'd0;rs232_tx_r <= 1'b1;endelse if(tx_en) beginif(clk_bps) beginnum <= num+1'b1;case (num)4'd0: rs232_tx_r <= 1'b0; //发送起始位4'd1: rs232_tx_r <= tx_data[0]; //发送bit04'd2: rs232_tx_r <= tx_data[1]; //发送bit14'd3: rs232_tx_r <= tx_data[2]; //发送bit24'd4: rs232_tx_r <= tx_data[3]; //发送bit34'd5: rs232_tx_r <= tx_data[4]; //发送bit44'd6: rs232_tx_r <= tx_data[5]; //发送bit54'd7: rs232_tx_r <= tx_data[6]; //发送bit64'd8: rs232_tx_r <= tx_data[7]; //发送bit74'd9: rs232_tx_r <= 1'b1; //发送结束位default: rs232_tx_r <= 1'b1;endcaseendelse if(num==4'd11) num <= 4'd0; //复位endendassign rs232_tx = rs232_tx_r; endmodule。

相关文档
最新文档