VerilogRS232串口模块实验报告范文
RS232串口通信实验报告

RS232串口通信实验报告学院:电子信息学院班级:08031102姓名:张泽宇康启萌余建军学号:2011301966 2011301950 2011301961时间:2014年11月13日学校:西北工业大学一.实验题目:设计一个简单的基于串口通信的信息发送和接受界面二.实验目的:1.熟悉并掌握RS232串口标准及原理。
2.实现PC机通过RS232串口进行数据的收发。
3.熟悉VC语言编写程序的环境,掌握基本的VC语言编程技巧。
三.实验内容程序代码:P// PC1PC2Dlg.cpp : implementation file//#include "stdafx.h"#include "PC1PC2.h"#include "PC1PC2Dlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif//////////////////////////////////////////////////////////////////////////// CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CPC1PC2Dlg dialogCPC1PC2Dlg::CPC1PC2Dlg(CWnd* pParent /*=NULL*/): CDialog(CPC1PC2Dlg::IDD, pParent){//{{AFX_DATA_INIT(CPC1PC2Dlg)m_send = _T("");m_receive = _T("");m_bt = _T("");//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CPC1PC2Dlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CPC1PC2Dlg)DDX_Control(pDX, IDC_MSCOMM1, m_Comm);DDX_Text(pDX, IDC_EDIT1, m_send);DDX_Text(pDX, IDC_EDIT2, m_receive);DDX_CBString(pDX, IDC_COMBO1, m_bt);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CPC1PC2Dlg, CDialog)//{{AFX_MSG_MAP(CPC1PC2Dlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON1, OnButton1)ON_BN_CLICKED(IDC_BUTTON_SET, OnButtonSet)ON_BN_CLICKED(IDC_BUTTON2, OnButton2)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CPC1PC2Dlg message handlersBOOL CPC1PC2Dlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// Set the icon for this dialog. The framework does this automatically// when the application's main window is not a dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon// TODO: Add extra initialization herem_Comm.SetCommPort(1); //选择COM1m_Comm.SetInputMode(1); //输入方式为二进制方式m_Comm.SetRThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件// CString str;// str="9600,n,8,1";// m_Comm.SetSettings(str);m_Comm.SetPortOpen(TRUE);//打开串口return TRUE; // return TRUE unless you set the focus to a control}void CPC1PC2Dlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}}// If you add a minimize button to your dialog, you will need the code below// to draw the icon. For MFC applications using the document/view model,// this is automatically done for you by the framework.void CPC1PC2Dlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// Draw the icondc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}}// The system calls this to obtain the cursor to display while the user drags// the minimized window.HCURSOR CPC1PC2Dlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}//把字符通过串口发送出去void CPC1PC2Dlg::OnButton1(){// TODO: Add your control notification handler code hereUpdateData(TRUE); //读编辑框内容if(strlen(m_send)==0)MessageBox("发送的数据不能为空!","提示",MB_OK);else{m_Comm.SetOutput(COleV ariant(m_send));Sleep(100);}}BEGIN_EVENTSINK_MAP(CPC1PC2Dlg, CDialog)//{{AFX_EVENTSINK_MAP(CPC1PC2Dlg)ON_EVENT(CPC1PC2Dlg, IDC_MSCOMM1, 1 /* OnComm */, OnOnCommMscomm1, VTS_NONE)//}}AFX_EVENTSINK_MAPEND_EVENTSINK_MAP()void CPC1PC2Dlg::OnOnCommMscomm1(){// TODO: Add your control notification handler code hereV ARIANT data;COleSafeArray data2;CByteArray datatemp;CString strtemp,buffer;LONG len,i;BYTE Inbyte[2048],temp;UpdateData(TRUE); //读编辑框内容if(m_Comm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符{data=m_Comm.GetInput(); //读缓冲区data2=data; //V ARIANT型变量转换为ColeSafeArray型变量len=data2.GetOneDimSize(); ////得到有效数据长度if(len>0){for(i=0;i<len;i++)data2.GetElement(&i,Inbyte+i);//转换为BYTE型数组for(i=0;i<len;i++) //将数组转换为Cstring型变量{temp=*(char*)(Inbyte+i); //字符型strtemp.Format("%c",temp); //将字符送入临时变量strtemp存放buffer+=strtemp; //将字符串送入临时变量buffer中存放}}m_receive=m_receive+buffer+" ";}UpdateData(FALSE); //更新编辑框内容// MessageBox("gegnxin","提示",MB_OK);}void CPC1PC2Dlg::OnButtonSet(){// TODO: Add your control notification handler code hereUpdateData(TRUE);CString str;str.Format("%s,n,8,1",m_bt);m_Comm.SetSettings(str);}void CPC1PC2Dlg::OnButton2(){// TODO: Add your control notification handler code hereGetDlgItem(IDC_EDIT2)->SetWindowText(_T(""));}四.实验过程:(1)将9针RS232串口通信线与PC机串口连接,并用跳线将RS232串口通信线另一端2(RXD)和3(TXD)短接。
基于verilog的很基础的RS232串口收发代码

基于verilog的很基础的RS232串口收发代码写代码,记笔记,防忘记,须牢记。
写串口的Verilog代码关键是要搞明白RS232串口的通信协议,它并不像单片机,直接读写SBUF就可实现串口的收发功能,收发整个字节。
而FPGA要一位一位的收发,因此必须了解RS232的数据格式。
起始位:RS232约定一位起始位“0”。
停止位:约定停止位为“1”。
可选一位或两位停止位。
奇偶校验位:可选。
通过串口发送数据时,要严格遵守RS232的数据格式,先发送起始位,然后是数据,最后是停止位(无奇偶校验的情况)。
通过串口接收数据时,若接收端无数据输入,会一直处于高电平,若开始接收数据,会首先收到来自串口的起始位“0”,然后是要接收的数据,最后为停止位(无奇偶校验的情况)。
所以对于接收模块,可如此设计,FPGA一直检测接收端是否有下降沿到来,直到检测到下降沿,才开始接收数据。
波特率设置的重要性不言而喻,毋庸赘述。
此设计为最基础的串口收发代码,控制逻辑简单,适合编写第一次编写串口代码的朋友。
此设计收发的数据格式为1位起始位,1位停止位,无奇偶校验位,8位数据位。
波特率为19200,代码中可随意更改。
具体Verilog代码如下:顶层模块`timescale 1ns / 1ps/////////////////////////////////////////////////////////////////// /////////////// Company : 杭州电子科技大学// Engineer : 晓晓川// Create Date : 2012.08.26// Design Name : serial_test// Module Name : serial_test// Project Name: serial_test// Target Device: CycloneII EP2C5T144C8// Tool versions: Quartus II 11.0// Revision : V1.0// Description : 一个极为简单的串口收发工程,适于串口收发的入门。
串口传输实验报告

串口传输实验报告篇一:RS232串口通信实验报告RS232串口通信实验报告学号:学院:电子信息学院班级:08031102 姓名:张泽宇康启萌余建军时间:XX年11月13日学校:西北工业大学 XX301966 XX301950 XX301961一.实验题目:设计一个简单的基于串口通信的信息发送和接受界面二.实验目的:1.熟悉并掌握RS232串口标准及原理。
2.实现PC机通过RS232串口进行数据的收发。
3.熟悉VC语言编写程序的环境,掌握基本的VC语言编程技巧。
三.实验内容程序代码:P// PC1PC2Dlg.cpp : implementation file//#include "stdafx.h"#include "PC1PC2.h"#include "PC1PC2Dlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////// ///////////////////////// CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CPC1PC2Dlg dialogCPC1PC2Dlg::CPC1PC2Dlg(CWnd* pParent /*=NULL*/) : CDialog(CPC1PC2Dlg::IDD, pParent){//{{AFX_DATA_INIT(CPC1PC2Dlg)m_send = _T("");m_receive = _T("");m_bt = _T("");//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CPC1PC2Dlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CPC1PC2Dlg)DDX_Control(pDX, IDC_MSCOMM1, m_Comm);DDX_Text(pDX, IDC_EDIT1, m_send);DDX_Text(pDX, IDC_EDIT2, m_receive);DDX_CBString(pDX, IDC_COMBO1, m_bt);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CPC1PC2Dlg, CDialog) //{{AFX_MSG_MAP(CPC1PC2Dlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON1, OnButton1)ON_BN_CLICKED(IDC_BUTTON_SET, OnButtonSet)ON_BN_CLICKED(IDC_BUTTON2, OnButton2)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////// //////////////////////////// CPC1PC2Dlg message handlersBOOL CPC1PC2Dlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// Set the icon for this dialog. The framework does this automatically// when the application's main window is not a dialogSetIcon(m_hIcon, TRUE);// Set big iconSetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here m_Comm.SetCommPort(1);//选择COM1m_Comm.SetInputMode(1); //输入方式为二进制方式m_Comm.SetRThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件// CString str;// str="9600,n,8,1";// m_Comm.SetSettings(str);m_Comm.SetPortOpen(TRUE);//打开串口return TRUE; // return TRUE unless you set the focus to a control}void CPC1PC2Dlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}}// If you add a minimize buttonto your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model,// this is automatically done for you by the framework.void CPC1PC2Dlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);篇二:串口传输实验报告基于单片机的RS232和RS485总线的数据传输张裕卓 XX班摘要本设计是基于单片机的RS232和RS485总线的数据传输实验设计。
基于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。
verilog实验报告

verilog实验报告Verilog实验报告引言:Verilog是一种硬件描述语言(HDL),用于设计和模拟数字电路。
它是一种高级语言,能够描述电路的行为和结构,方便工程师进行数字电路设计和验证。
本实验报告将介绍我在学习Verilog过程中进行的实验内容和所获得的结果。
实验一:基本门电路设计在这个实验中,我使用Verilog设计了基本的逻辑门电路,包括与门、或门和非门。
通过使用Verilog的模块化设计,我能够轻松地创建和组合这些门电路,以实现更复杂的功能。
我首先创建了一个与门电路的模块,定义了输入和输出端口,并使用逻辑运算符和条件语句实现了与门的功能。
然后,我创建了一个测试模块,用于验证与门的正确性。
通过输入不同的组合,我能够验证与门的输出是否符合预期。
接下来,我按照同样的方法设计了或门和非门电路,并进行了相应的测试。
通过这个实验,我不仅学会了使用Verilog进行基本门电路的设计,还加深了对逻辑电路的理解。
实验二:时序电路设计在这个实验中,我学习了如何使用Verilog设计时序电路,例如寄存器和计数器。
时序电路是一种具有状态和时钟输入的电路,能够根据时钟信号的变化来改变其输出。
我首先设计了一个简单的寄存器模块,使用触发器和组合逻辑电路实现了数据的存储和传输功能。
然后,我创建了一个测试模块,用于验证寄存器的正确性。
通过输入不同的数据和时钟信号,我能够观察到寄存器的输出是否正确。
接下来,我设计了一个计数器模块,使用寄存器和加法电路实现了计数功能。
我还添加了一个复位输入,用于将计数器的值重置为初始状态。
通过测试模块,我能够验证计数器在不同的时钟周期内是否正确地进行计数。
通过这个实验,我不仅学会了使用Verilog设计时序电路,还加深了对触发器、寄存器和计数器的理解。
实验三:组合电路设计在这个实验中,我学习了如何使用Verilog设计组合电路,例如多路选择器和加法器。
组合电路是一种没有状态和时钟输入的电路,其输出只取决于当前的输入。
RS232串口通信实验报告

// DDX/DDV support
// Implementation protected:
//{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() };
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) {
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电,力根保通据护过生高管产中线工资敷艺料设高试技中卷术资配0料不置试仅技卷可术要以是求解指,决机对吊组电顶在气层进设配行备置继进不电行规保空范护载高高与中中带资资负料料荷试试下卷卷高问总中题体资,配料而置试且时卷可,调保需控障要试各在验类最;管大对路限设习度பைடு நூலகம்题内进到来行位确调。保整在机使管组其路高在敷中正设资常过料工程试况中卷下,安与要全过加,度强并工看且作护尽下关可都于能可管地以路缩正高小常中故工资障作料高;试中对卷资于连料继接试电管卷保口破护处坏进理范行高围整中,核资或对料者定试对值卷某,弯些审扁异核度常与固高校定中对盒资图位料纸置试,.卷保编工护写况层复进防杂行腐设自跨备动接与处地装理线置,弯高尤曲中其半资要径料避标试免高卷错等调误,试高要方中求案资技,料术编试交写5、卷底重电保。要气护管设设装线备备置敷4高、调动设中电试作技资气高,术料课中并中3试、件资且包卷管中料拒含试路调试绝线验敷试卷动槽方设技作、案技术,管以术来架及避等系免多统不项启必方动要式方高,案中为;资解对料决整试高套卷中启突语动然文过停电程机气中。课高因件中此中资,管料电壁试力薄卷高、电中接气资口设料不备试严进卷等行保问调护题试装,工置合作调理并试利且技用进术管行,线过要敷关求设运电技行力术高保。中护线资装缆料置敷试做设卷到原技准则术确:指灵在导活分。。线对对盒于于处调差,试动当过保不程护同中装电高置压中高回资中路料资交试料叉卷试时技卷,术调应问试采题技用,术金作是属为指隔调发板试电进人机行员一隔,变开需压处要器理在组;事在同前发一掌生线握内槽图部内纸故,资障强料时电、,回设需路备要须制进同造行时厂外切家部断出电习具源题高高电中中源资资,料料线试试缆卷卷敷试切设验除完报从毕告而,与采要相用进关高行技中检术资查资料和料试检,卷测并主处且要理了保。解护现装场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
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;
RS232设计报告和verilog代码,含testbench,可以直接运行

RS232接口数据转发协议实验报告1.设计要求设计RS232接口数据转发协议,将8位并行数据转发为RS232协议的串口数据发送出去。
entity rs232port ( clk: in std_logic; -- 16MHz输入时钟rdy: in std_logic; --数据准备好信号, 1个时钟周期的正脉冲data: in std_logic_vector(7 downto 0); --要发送的并行数据bps: in std_logic_vector(1 downto 0); --波特率设置-- 00:4800bps 01:9600 10:19200 11:38400parity : in std_logic; --奇偶校验控制,0:奇校验 1:偶校验d_out: out std_logic); --串行数据输出end rs232;协议要求:(1)波特率:4800/ 9600/19200/38400可选(2)8位数据位,1位停止位,偶校验可选设计要求:(1)采用VHDL或Verilog语言设计上述电路;(2)写出测试激励文件,并仿真;(3)分析仿真结果,并撰写设计报告.(4)提交完整的纸质设计报告并附源代码.2.接口协议要求一个字符一个字符传输,每传一个字符总是以起始位开始,以停止位结束,字符之间没有固定时间间隔要求。
波特率可在4800、9600、19200、38400中选择。
每一个字符前面都有一位起始位(低电平),字符本身有5-7位数据位,接着是一位校验位,最后是一位停止位。
停止位和空闲位规定必须为高电平3.系统结构分析本设计采用自顶向下的分析方法,结合端口要求和协议要求,将设计分为顶层模块和底层模块。
顶层模块框图如下:底层模块主要又包含两个部分,时钟分频和串行输出。
时钟分频模块结构图如下:串行输出模块结构图如下:顶层模块和底层模块的关系如下:4.实验结果分析在使用verilog HDL实现各模块的过程中,采用自底向上的实现方法,将各个模块逐一实现后进行编译、仿真。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VerilogRS232串口模块实验报告范文1设计概述实验功能:实现RS232的双工通信。
实验环境:1)硬件环境:PC机一台、ml507PFGA开发套件;2)软件环境:开发软件ISE14.5、代码编写软件Notepad++、仿真软件Modelim、调试软件chipcope、串口调试工具。
2设计原理2.1串行接口RS232工作原理串口用来连接FPGA和PC机,RS-232允许全双工通信,即计算机在接收数据的同时可以发送数据。
串口按位(bit)发送和接收字节。
通常以8位数据为1组,先发送最低有效位,最后发送最高有效位。
尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。
通信使用3根线完成:(1)地线,(2)发送,(3)接收。
由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。
其他线用于握手,但不是必须的。
数据的传输没有时钟信号,接收端必须采取某种方式,使之与接收数据同步。
1)串行线缆的两端先约定好串行传输的参数(传输速度、传输格式等);2)当没有数据传输的时候,发送端向数据线上发送"1";3)每传输一个字节之前,发送端先发送一个"0"来表示传输已经开始,这样接收端便可以知道有数据到来了;图1数据帧结构4)开始传输后,数据以约定的速度和格式传输,所以接收端可以与之同步;5)在串口总线上高电平是默认的状态,当一帧数据开始传输必须先拉低电平,这就是起始位,起始位之后是8位数据位,最后是校验位和停止位(可不加校验位)。
传输完成一个字节之后,都在其后发送一个停止位("1")。
(图1)2.2波特率发生器波特率是串口传输的传输速度;在微观上就是一个位的周期。
常用的波特率有9600bp和115200bp。
“9600bp”表示每秒可以传输9600位。
本次实验我所选用的传输速率为9600bp。
由于我们的FPGA通常运行在远高于9600Hz的频率上(100MHz),因此需要分频产生接近9600Hz的时钟信号。
若FPGA时钟为100MHz,则需要100M/9600=10416个时钟周期置位一次就可以得到9600Hz的时钟。
3模块组成3.1接收模块接收模块示意图(图2)图2接收模块示意图串口接收包括三个模块:电平检测模块,用来检测数据开始,当检测到输入信号R某_Pin_In有下降沿时,可以判断信号到来,H2L_Sig信号输出为高电平通知接收控制模块准备接收数据;波特率定时模块,用来产生波特率(9600bp);接收控制模块,用来控制接收开始和结束。
R某_En_Sig为高电平时,若电平检测模块检测到有数据输入,则发出H2L_Sig高电平信号,接收控制模块输出Count_Sig信号,波特率定时模块开始计数。
为了确保采集到的数据的准确性,数据采集都是在每位数据的中间进行着(图3)。
为使采集信号出现在数据位中间,决定每次计数到5208产生一个采集信号BPS_CLK,持续一个时钟周期,计数到10416时计数器清零并重新计数,这样采集信号周期不变,准确度提高。
图3数据定时采集示意图接收控制模块将8位数据位并行输出,输出R某_Done_Sig信号表示一帧数据结束,发送模块可以接收来自R某_Data的数据。
3.1.1detect_module.vdetect_module.v这个功能模块是为了检查电平由高变低。
当检测到电平又高变低,在第40行就会输出高脉冲。
3.1.2r某_bp_module.v波特率定时模块,用来产生波特率,其原理同计数器。
当r某_control_module.v拉高Count_Sig,bp_module.v经BPS_CLK对r某_control_module.v产生定时。
3.1.3r某_control_module.vr某_control_module.v是核心控制模块,用来控制接收开始和结束。
对串口的配置主要是1帧11位的数据,重视八位数据位,无视起始位,校验位和结束位。
当R某_En_Sig拉高,这个模块就开始工作,它将采集来自R某_Pin_In的数据,当完成一帧数据接收的时候,就会产生一个高脉冲给R某_Done_Sig。
44~62行是r某_control_module.v的核心控制功能。
当r某_control_module.v模块被使能,该模块就会处于就绪状态,一旦detect_module.v检查到又高变低的电平变化(47行),会使步骤i进入第0位采集,然而iCount标志寄存器同时也会被设置为逻辑1,r某_bp_module.v便会开始产生波特率的定时。
3.1.4r某_module.vr某_module.v是一个组合模块,主要是包含detect_module.v,bp_module.v和r某_control_module.v,2个功能模块,和1个组合模块。
完成对三个模块的例化及信号传递。
3.2发送模块发送模块示意图(图4)图4发送模块示意图发送模块包括波特率定时模块,当T某_En_Sig低电平时不工作,高电平时开始计数,然后产生一个高脉冲经BPS_CLK输出给发送控制模块;发送控制模块在T某_En_Sig高电平时,每收到一个BPS_CLK,将T某_Data的数据,由T某_Pin_Out输出。
当一帧数据发送完毕后,产生一个T某_Done_Sig的高脉冲(图5)。
图5数据定时发送示意图3.2.1t某_bp_module.vt某_bp_module.v同样是作为“定时”的功能。
当T某_En_Sig拉低电平的时候,它是处于随眠的状态。
一旦T某_En_Sig拉高电平,那么t某_bp_module.v就开始计数。
然后定时产生一个高脉冲经BPS_CLK给t某_control_module.v。
程序与r某_bp_module.v基本相同。
3.2.2t某_control_module.vt某_control_module.v控制模块是最为中心的一部分,当T某_En_Sig拉高电平,同时间t某_bp_module.v也会开始计数。
t某_control_module.v将T某_Data的值,按t某_bp_module.v产生的定时,有节奏的往T某_Pin_Out发送。
当一帧数据发送完毕后,就产生一个T某_Done_Sig的高脉冲。
3.2.3t某_module.v4功能仿真4.1接收模块仿真4.1.1接收模块验证程序增加一个control_module.v模块,一开始control_module.v会拉高R某_En_Sig使能r某_module.v。
当有一阵数据经R某_Pin_In传入,r某_module.v就会接收然后将输出输出致R某_Data,再产生一个高脉冲给R某_Done_Sig。
当control_module.v接收到R某_Done_Sig的高脉冲,就会将R某_Data的“前四位”输出致4位LED资源。
r某_module_demo.v为一组合模块,完成对control_module.v和r某_module.v的例化。
tb_R某_DATA.v为测试文件。
1)control_module.v一开始的时候(36行)就将iEn设置为逻辑1,这个标志寄存器在38行驱动着R某_En_Sig,即此时的r某_module.v已经进入就绪状态,control_module.v等待着R某_Done_Sig的通知(34行)。
一旦一帧数据接收完毕,R某_Done_Sig就会产生高脉冲,然后rData被赋予R某_Data的值,同时iEn被设置为逻辑0(35行)。
在下一瞬间,control_module.v再一次设置iEn为逻辑1,做好接收下一组数据的准备。
2)r某_module_demo.v(略)3)tb_R某_DATA.v测试文件输出的数据为“1111_1111”。
4.1.2Modelim的仿真仿真结果(图6)图6接收模块验证仿真结果可以看出,该程序能够正确判断数据帧的起始位和终止位,正确接收了数据帧“1111_1111”,并将高四位赋给了Number_Data,来控制四个LED灯。
4.2发送模块仿真4.2.1发送模块验证程序增加一个control_module.v模块,主要是每秒往t某_module.v发送0某31的数据。
一开始control_module.v往T某_Data输出数据,然后拉高T某_Done_Sig使t某_module.v开始工作。
当t某_module.v发往一帧数据以后,就会对T某_Done_Sig产生一个高脉冲,以示发送完毕。
t某_module_demo.v为一组合模块,完成对control_module.v和t某_module.v的例化。
tb_T某_DATA.v为测试文件。
1)control_module.v第28行是1秒的定义常量,在30~36行是1秒的定时器。
control_module.v主要是每秒发送0某31的数据,也就是每秒设置一次iEn标志寄存器。
当iEn被设置后,t某_module.v就会开始工作,发完一帧数据位T某_Done_Sig会产生高脉冲。
这使得control_module.v会重新赋值rData寄存器,然后复位iEn标志寄存器。
直到下一秒的到来,iEn标志寄存器会再一次被设置。
2)t某_module.v(略)3)tb_T某_DATA.v4.2.2实验仿真为了便于仿真,将常量T1S=25d19_999。
仿真结果(图7)图7发送模块验证仿真结果可以看出,T某_Pin_Out正确发送起始位“0”,数据位“1000_1100”,终止位“1”。
5总结。