uart_receive.v源码及测试代码

合集下载

uart串口发送和接受的程序的实现原理

uart串口发送和接受的程序的实现原理

UART串行端口传输和接收程序工作像繁忙的邮政办公室为你的数据!它遵循UART(UART)通用同步接收器、传输器(Transmitter)协议,其中数据以特定baud速率的节奏舞蹈比特发送,开始和停止比
特引导方向。

当您想要将数据发送到世界时,程序首先会设置带有正
确baud率和其他配置的UART模块,然后它会欢快地将您的数据丢
入传输缓冲器。

从那里,UART硬件接管,刷刷你的数据并发送出来在TX针,遵循所有的规则和设置你已经规定。

这就像一个精心编程的表演,与你的数据占据中心阶段!
基本上,UART模块总是在检查RX针上的任何线程数据。

一旦它检
测到一个起始位,它开始根据指定的baud速率抓取其余位。

在获得
包括开始和停止位数在内的整个数据包后,它会保存接收缓冲中的所
有数据。

程序可以从接收缓冲器中获取数据来查看里面有什么。

处理任何潜在的错误,如框架错误或等值错误,在接收过程中可能出现,
也是非常重要的。

UART串行端口传输和接收程序的实施遵循UART协议的原则和政策,促进设备之间的数据交换。

程序精心配置了UART模块,其中包含关于baud率,数据比特,stop比特,以及等价的具体参数,并认真遵
守了规定的准则。

随后,要传输的数据被有效存储并写入UART传输缓冲器。

接收后,从接收缓冲中勤勉地检索数据,确保UART模块准确处理并存储了iing数据。

通过坚持规定的UART协议和有条不紊地
配置UART模块,程序按照既定的政策和指令,有效建立了设备间连续免疫的可靠和安全的通道。

hal_uart_receive_it 用法

hal_uart_receive_it 用法

hal_uart_receive_it 用法`HAL_UART_Receive_IT` 是一个函数,用于启动 UART 接收中断模式。

它的详细精确用法如下:1. 在 `main` 函数或其他适当的位置,初始化 UART 和相应的 GPIO 引脚。

c/* 初始化 UART 和 GPIO 引脚 */void UART_Init(void){/* 初始化 UART 配置结构体 */UART_HandleTypeDef huart;huart.Instance = USARTx; // USARTx 是你要使用的UART 实例huart.Init.BaudRate = 9600; // 设置波特率huart.Init.WordLength = UART_WORDLENGTH_8B; // 设置数据位长度huart.Init.StopBits = UART_STOPBITS_1; // 设置停止位huart.Init.Parity = UART_PARITY_NONE; // 设置奇偶校验huart.Init.Mode = UART_MODE_TX_RX; // 设置 UART 模式huart.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 设置硬件流控制huart.Init.OverSampling = UART_OVERSAMPLING_16; // 设置采样率/* 初始化 UART */HAL_UART_Init(&huart);/* 初始化 GPIO 引脚 */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = GPIO_PIN_2; //USARTx_RX_Pin 是接收引脚GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 设置引脚为复用功能GPIO_InitStruct.Pull = GPIO_PULLUP; // 设置上拉电阻GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 设置引脚速度GPIO_InitStruct.Alternate = GPIO_AF7_USARTx; // 设置引脚复用功能为 USARTxHAL_GPIO_Init(GPIOx, &GPIO_InitStruct); // GPIOx 是引脚所在的 GPIO 端口}2. 在 `main` 函数或其他适当的位置,启动 UART 接收中断模式。

嵌入式中 uart发送和接受数据的编程方法,以及接受中断编程

嵌入式中 uart发送和接受数据的编程方法,以及接受中断编程

嵌入式中 uart发送和接受数据的编程方法,以及接受中断
编程
一、UART发送和接收数据编程方法
发送:
1.配置UART的参数,包括波特率,字长,停止位,校验位等;
2.设置中断使能标志位:
a)发送数据时,设置发送中断使能标志位;
b)接收数据时,设置接收中断使能标志位;
3.发送数据:将要发送的数据写入发送缓冲区;
4.查询发送状态:查询发送缓冲区内数据已发送完毕;
5.处理中断:当发送缓冲区数据发送完毕,会产生发送中断,根据中断处理函数,编写中断处理函数,清除发送中断标志,完成发送数据。

接收:
1.配置UART的参数,包括波特率,字长,停止位,校验位等;
2.设置中断使能标志位:
a)发送数据时,设置发送中断使能标志位;
b)接收数据时,设置接收中断使能标志位;
3.查询接收状态:查询接收缓冲区内数据接收状态;
4.读取数据:从接收缓冲区中读取接收到的数据;
5.处理中断:当接收数据完毕,会产生接收中断,根据中断处理函数,编写中断处理函数,清除接收中断标志,完成接收数据的
读取。

二、UART接收中断编程
1.首先,需要将UART的接收中断使能标志位设置为1;
2.然后,需要在main函数中,设置对应的中断向量,指定接收中断要执行的中断服务程序;
3.在中断服务程序中,可以访问UART接收缓冲区,从中读取接收到的数据;
4.最后,在中断服务程序中,清除接收中断标志,以便重新接收下一个中断信号。

micropython uart 读取格式

micropython uart 读取格式

Micropython是一种精简的Python解释器,专门用于微控制器和嵌入式系统。

它提供了一种方便的方式来编写和运行Python代码,并且可以轻松地与传感器、执行器和其他外部设备进行通信。

在Micropython中,UART(Universal AsynchronousReceiver/Transmitter)是一种常用的串行通信接口,用于将微控制器与其他设备连接起来。

在本文中,我们将探讨如何使用Micropython来读取和处理UART接收到的数据。

1. 确定串口配置在使用Micropython读取UART数据之前,首先需要确定串口的配置参数。

这些参数包括波特率、数据位、停止位和校验位等。

在Micropython中,可以通过调用`machine.UART`类来设置串口的配置,例如:```pythonuart = machine.UART(1, baudrate=9600, bits=8, parity=None, stop=1)```在这个例子中,我们创建了一个名为`uart`的串口对象,将其连接到第一个UART接口,并将波特率设置为9600,数据位设置为8位,停止位设置为1位,校验位设置为None。

2. 读取串口数据一旦串口被配置好,就可以开始读取接收到的数据了。

在Micropython中,可以使用`uart.read()`方法来从串口中读取指定长度的数据,例如:```pythondata = uart.read(10)```在这个例子中,我们从串口中读取了10个字节的数据,并将其赋值给名为`data`的变量。

需要注意的是,如果串口暂时没有接收到足够的数据,`uart.read()`方法会一直阻塞直至接收到指定长度的数据或者超时。

3. 处理串口数据一旦从串口中读取到数据,就可以对其进行进一步的处理了。

根据接收到的数据格式的不同,处理方法也会有所不同。

一种常见的情况是接收到的数据是ASCII格式的字符串,可以直接对其进行解析和处理,例如:```pythondata_str = data.decode('utf-8')```在这个例子中,我们将接收到的字节数据解码为UTF-8格式的字符串,并将其赋值给名为`data_str`的变量。

hal_uart_receive用法

hal_uart_receive用法

hal_uart_receive用法1.简介在使用H AL(硬件抽象层)进行嵌入式开发时,我们经常需要与外部设备进行UA RT通信。

在这种情况下,我们可以使用H AL库提供的`h al_u ar t_re ce ive`函数来接收U AR T数据。

本文将介绍`h al_u ar t_re ce ive`函数的用法,帮助你快速上手并正确使用该函数。

2.函数定义`h al_u ar t_re ce ive`函数用于接收UA RT数据,其函数定义如下:```ci n th al_u ar t_re cei v e(ua rt_h an dl e_t*ha nd le,v oi d*dat a,s iz e _t si ze,u in t32_tti m eo ut);```参数说明:-`ha nd le`:UA RT句柄,用于指定要接收数据的UA RT端口。

-`da ta`:接收数据的缓冲区指针。

-`si ze`:接收数据的字节数。

-`ti me ou t`:接收超时时间,单位为毫秒。

返回值:-成功接收数据的字节数。

-如果出现错误,则返回负值。

3.使用示例下面是一个使用`hal_ua rt_r ec ei ve`函数的示例:```c#i nc lu de"h al_u art.h"#d ef in eU AR T_PO RTU A RT_P OR T_1v o id ua rt_r ec ei ve_e xa mp le(v oi d){u a rt_h an dl e_tu art_ha nd le;u i nt8_tb uf fe r[10];i n tr et;//初始化U AR Th a l_ua rt_i ni t(UAR T_P OR T,&u ar t_han d le);//接收数据r e t=ha l_ua rt_r ece i ve(&ua rt_h an dle,bu ff er,s iz eo f(b u ff er) ,1000);i f(r et>0){//成功接收到数据,处理数据f o r(in ti=0;i<r et;i++){//处理接收到的数据//...}}e ls ei f(re t==0){//超时,未接收到数据//...}e ls e{//发生错误//...}}```以上示例代码展示了如何初始化U AR T句柄并使用`h al_u ar t_re ce ive`函数接收UA RT数据。

uart实验报告

uart实验报告

uart实验报告
《UART实验报告》
实验目的:通过实验学习串行通信的基本原理,掌握UART通信协议的工作原理和使用方法。

实验设备:单片机开发板、串口调试助手、电脑。

实验原理:UART(Universal Asynchronous Receiver/Transmitter)是一种通用的异步串行通信协议,用于在计算机和外部设备之间进行数据传输。

UART通信协议包括数据位、停止位、奇偶校验位等参数,通过这些参数的设置可以实现不同的通信速率和数据传输方式。

实验步骤:
1. 连接单片机开发板和电脑,打开串口调试助手。

2. 在单片机开发板上编写UART通信程序,设置通信参数。

3. 将单片机开发板通过串口连接到电脑,打开串口调试助手。

4. 在串口调试助手上发送数据,观察单片机开发板接收到的数据。

5. 在单片机开发板上发送数据,观察串口调试助手接收到的数据。

实验结果:
经过实验,我们成功地实现了通过UART通信协议在单片机开发板和电脑之间进行数据传输。

在串口调试助手上发送的数据能够被单片机开发板正确接收,并且在单片机开发板上发送的数据也能够被串口调试助手正确接收。

通过调整通信参数,我们还验证了不同通信速率和数据传输方式对通信效果的影响。

实验总结:
通过本次实验,我们深入了解了UART通信协议的工作原理和使用方法,掌握
了串行通信的基本原理。

在今后的学习和工作中,我们将能够更加熟练地应用UART通信协议进行数据传输,为实际工程应用打下了坚实的基础。

通俗的UART讲解和源码

通俗的UART讲解和源码通⽤异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UATR,是⼀种异步收发传输器。

将数据由串⾏通信与并⾏通信间做传输转换,作为并⾏输⼊称为串⾏输出的芯⽚。

UART是⼀种通⽤串⾏数据总线,⽤于异步通信。

该总线双向通信,可以实现全双⼯传输和接收。

数据传送速率⽤波特率来表⽰,即每秒钟传送的⼆进制位数。

例如数据传送速率为120字符/秒,⽽每⼀个字符为10位(1个起始位,7个数据位,1个校验位,1个结束位),则其传送的波特率为10×120=1200字符/秒=1200波特。

起始位:先发出⼀个逻辑”0”信号,表⽰传输字符的开始。

数据位:可以是5~8位逻辑”0”或”1”。

如ASCII码(7位),扩展BCD码(8位)。

⼩端传输校验位:数据位加上这⼀位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验)停⽌位:它是⼀个字符数据的结束标志。

可以是1位、1.5位、2位的⾼电平。

空闲位:处于逻辑“1”状态,表⽰当前线路上没有资料传送。

注:异步通信是按字符传输的,接收设备在收到起始信号之后只要在⼀个字符的传输时间内能和发送设备保持同步就能正确接收。

下⼀个字符起始位的到来⼜使同步重新校准(依靠检测起始位来实现发送与接收⽅的时钟⾃同步的)。

1、UART通信协议UART作为异步串⼝通信协议的⼀种,⼯作原理是将传输数据的每⼀个字符⼀位⼀位地传输。

其中每⼀位(bit)的意义如下:起始位:先发出⼀个逻辑“0”的信号,表⽰传输字符开始。

数据位:紧接着起始位之后。

数据位的个数可以是4、5、6、7、8等,构成⼀个字符。

通常采⽤ASCII码。

从最低位开始传送,靠时钟定位。

奇偶校验位:数据位加上这⼀位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以次来校验数据传送的正确性。

停⽌位:它是⼀个字符数据的结束标志。

可以是1位、1.5位、2位的⾼电平。

UART串口代码

UART串⼝代码uart_cfg=XUartPs_LookupConfig(uart_id);XUartPs_CfgInitialize(&uart,uart_cfg,uart_cfg->BaseAddress);XUartPs_SetBaudRate(&uart,baud_rate); 设置波特率XUartPs_SetHandler(&uart,(XUartPs_Handler)uart1handler,&uart); UART有多种中断,触发对应的中断intrmask=XUARTPS_IXR_TOUT;XUartPs_SetInterruptMask(&uart,intrmask);XUartPs_SetOperMode(&uart,normal_mode);XUartPs_SetRecvTimeout(&uart,8); 间隔4*8共32个bit的时间内没有接收到数据触发XUartPs_Recv(&uart,recvbuf,32);// 读出32个数据到 recbufvoid XUartPs_SetFifoThreshold(XUartPs *InstancePtr, u8 TriggerLevel) 设置阈值,FIFO内数据达到阈值触发(产⽣事件)/** main.c** Created on: 2022年2⽉23⽇* Author: lht*/#include "stdio.h"#include "xparameters.h"#include "xscugic.h"#include "xuartps.h"#include "xil_exception.h"#include "xil_printf.h"#include <stdlib.h>#define uart_id XPAR_PS7_UART_1_DEVICE_ID#define baud_rate XUARTPS_DFT_BAUDRATE#define normal_mode XUARTPS_OPER_MODE_NORMAL#define gic_id XPAR_PS7_SCUGIC_0_DEVICE_ID#define uart1_intr XPAR_PS7_UART_1_INTR#define BUFFER_SIZE 1024unsigned char recvbuf[1024];u32 RecvCnt;u32 codecnt;//static u16 recvbuf_and[512];static u8 RecvBuffer[BUFFER_SIZE];u16 *recvbuf_and=NULL;u16 data_len;u8 sum_check;u8 xor_check;int right=0;/*typedef struct st_type //柔性数组{int j;u16 recvbuf_and[];}type_a; */u32 TotalRecvCnt;u8 *RecvBufferPtr;XUartPs uart;XUartPs_Config *uart_cfg;XScuGic scugic;XScuGic_Config * gic_cfg;void init_uart();void init_intr();void uart1handler(void *CallBackRef, u32 Event,u32 EventData);int main(){printf("hi\n\r");init_intr();init_uart();while(1){//int i=0;//for(i=0;i<codecnt;i++){// xil_printf("i:%x\r\n",recvbuf_and[i]);//}}return0;}void init_uart(){// XUartPs uart;// XUartPs_Config *uart_cfg;u32 intrmask=0;//RecvBufferPtr=RecvBuffer;uart_cfg=XUartPs_LookupConfig(uart_id);XUartPs_CfgInitialize(&uart,uart_cfg,uart_cfg->BaseAddress);XUartPs_SetBaudRate(&uart,baud_rate);XUartPs_SetHandler(&uart,(XUartPs_Handler)uart1handler,&uart); intrmask=XUARTPS_IXR_TOUT|XUARTPS_IXR_RXOVR;XUartPs_SetInterruptMask(&uart,intrmask);XUartPs_SetOperMode(&uart,normal_mode);XUartPs_SetFifoThreshold(&uart,32);XUartPs_SetRecvTimeout(&uart,8);//XUartPs_Recv(&uart,recvbuf,64);//}void init_intr(){// XScuGic scugic;// XScuGic_Config * gic_cfg;gic_cfg=XScuGic_LookupConfig(gic_id);XScuGic_CfgInitialize(&scugic,gic_cfg,gic_cfg->CpuBaseAddress);Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&scugic); Xil_ExceptionEnable();XScuGic_Connect(&scugic,uart1_intr,(Xil_ExceptionHandler)XUartPs_InterruptHandler,&uart);XScuGic_Enable(&scugic,uart1_intr);}void uart1handler(void *CallBackRef, u32 Event,u32 EventData){//u32 recvcnt;if(Event==XUARTPS_EVENT_RECV_DATA){/* 清除中断标志 */XUartPs_WriteReg(uart_cfg->BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR) ;XUartPs_Recv(&uart, RecvBuffer, 500) ; //设置为最⼤,这样有多少就会接收多少//RecvCnt += EventData ;//RecvBufferPtr += EventData;xil_printf("1\r\n");}else if(Event==XUARTPS_EVENT_RECV_TOUT){int i;int j;int right=0;recvbuf_and = (u16 *) malloc(codecnt * sizeof(u16));/* 清除中断标志 */XUartPs_WriteReg(uart_cfg->BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_TOUT) ;XUartPs_Recv(&uart, RecvBuffer, 500) ;//RecvCnt += EventData ;if((RecvBuffer[0]==0x12) && (RecvBuffer[1]==0x34)){data_len=(((RecvBuffer[2])&0x00ff)<<8|(RecvBuffer[3]&0x00ff));for(j=2;j<(data_len+6);j++){sum_check+=RecvBuffer[j];xor_check^=RecvBuffer[j];//printf("RecvBuffer[j]=%d\n\r",RecvBuffer[j]);//printf("j=%d\n\r",j);}/*printf("RecvBuffer[1]=%d\n\r",RecvBuffer[1]);printf("RecvBuffer[2]=%d\n\r",RecvBuffer[2]);printf("RecvBuffer[3]=%d\n\r",RecvBuffer[3]);printf("DATA_LEN=%d\n\r",data_len);printf("SUM_CHECK=%d\n\r",sum_check);printf("XOR_CHECK=%d\n\r",xor_check);printf("RecvBuffer[4+data_len]=%d\n\r",RecvBuffer[4+data_len]);printf("RecvBuffer[5+data_len]=%d\n\r",RecvBuffer[5+data_len]);printf("RecvBuffer[6+data_len]=%d\n\r",RecvBuffer[6+data_len]);printf("RecvBuffer[7+data_len]=%d\n\r",RecvBuffer[7+data_len]);*/if((sum_check==RecvBuffer[4+data_len]) && (xor_check==RecvBuffer[5+data_len])){right=1;printf("right=%d\n\r",right);right=0;if((RecvBuffer[6+data_len]==0x43) && (RecvBuffer[7+data_len]==0x21) ){codecnt=data_len/2;for(i=2;i<codecnt+2;i++){recvbuf_and[i-2]=(((RecvBuffer[2*i])&0x00ff)<<8|(RecvBuffer[2*i+1]&0x00ff));printf("recvbuf_and[i]=%d\n\r",recvbuf_and[i-2]);printf("i=%d\n\r",i-2);}}else{printf("codecnt=%d\n\r",codecnt);}}else{printf("right=%d\n\r",right);}}else {for(i=0;i<BUFFER_SIZE;i++){RecvBuffer[i]=0;}}xil_printf("2:%d\r\n",RecvCnt);xil_printf("2:%d\r\n",data_len);sum_check=0;xor_check=0;RecvCnt=0;data_len=0;//recvcnt=EventData;// if(recvcnt==8 && recvbuf[0]==0x55 && recvbuf[1]==0x55){ // printf("recved frame1\n\r");//}}}。

hal_uart_receive_it 用法

hal_uart_receive_it用法=====================hal_uart_receive_it是一个常用的函数,它用于从UART (UniversalAsynchronousReceiver/Transmitter)接收数据。

UART是一种串行通信协议,用于在两个设备之间进行异步通信。

在使用HAL (HardwareAbstractionLayer)库进行嵌入式系统开发时,hal_uart_receive_it函数是一种常用的接收数据的方法。

一、函数简介-------hal_uart_receive_it是HAL库中的一个函数,它接收来自UART 的数据,并将接收到的数据存储在一个指定的缓冲区中。

这个函数是异步的,这意味着它在接收到数据后会立即返回,而不会等待接收完成。

这种设计模式适用于一些实时性要求较高的应用场景。

二、函数参数------*`HAL_UART*uart`:UART设备的指针,指向要接收数据的UART 设备的数据结构。

*`uint8_t*buffer`:指向接收数据的缓冲区的指针。

这个缓冲区用于存储接收到的数据。

*`uint16_tlength`:要接收的数据长度,以字节为单位。

*`uint16_ttimeout`:超时时间,以微秒为单位。

如果在指定的时间内没有接收到足够的数据,函数将返回超时错误。

三、函数使用示例---------下面是一个使用hal_uart_receive_it函数的示例代码:```c#include"hal_uart.h"intmain(){HAL_UART*uart=hal_uart_open("UARTx",115200);if(uart==NULL){//打开UART设备失败,处理错误}uint8_tbuffer[100];//假设要接收的数据长度为100字节uint16_tlength=sizeof(buffer);//设置要接收的数据长度为缓冲区大小uint16_ttimeout=5000;//设置超时时间为5秒if(hal_uart_receive_it(uart,buffer,length,timeout)==HAL_O K){//接收成功,处理接收到的数据}else{//接收失败,处理错误}hal_uart_close(uart);//关闭UART设备return0;}```在上面的示例中,首先打开了一个UART设备,并指定了要接收数据的波特率等参数。

51单片机串口通讯UART头文件的源代码

bit bdata sendfull; //发送缓冲区满标志
bit bdata sendactive; //发送有效标志
/*串行中断服务程序*/
static void com_isr(void) interrupt 4 using 1
{
//----------接收数据---------------
char c;
if(RI) //接收中断置位
{
c=SBUF;//读字符
RI=0;//清接收中端标志
if(istart+ILEN!=iend)
inbuf[iend++&(ILEN-1)]=c; //缓冲区接收数据
}
//------------发送数据------
if(TI)
{
TI=0; //清发送中断标志
if(ostart!=oend)
char idata outbuf[OLEN]; //发送缓冲区存储数组
#define ILEN 8//串行接收缓冲区大小
unsigned char istart; //接受缓冲区起始索引
unsigned char iend; //接收缓冲区结束索引
char idata inbuf[ILEN]; //接收缓冲区存储数组
putbuf(0x0D); //对新行在LF前发送CR
}
while(sendfull);
putbuf(c);
return(c);
}
//替换标准库函数_getkey程序
//getchar和gets函数使用_getkey
char _getkey(void)
{
char c;
while(iend==istart) //判断接收缓冲区起始索引是否等于接收区结束索引
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

顶层文件uart_receive.v ,实现串口接收功能,里面例化四个子文件,分别是detect.v, baud.v, rx_receive.v, odd_even_detect.v,各个模块功能如下:Detect.v功能简介:实现串行输入数据(i_rxdata)电平检测(在i_rxdata由高电平向低电平转换时产生检测脉冲o_h2l),为后面检测起始位做准备(此文件可综合) 综合软件:quartus ii 11.0代码如下://===========================//Author : wsc//Time : 2013/12/02//File Name : detect.v//==========================module detect (i_clk,i_rst_n,i_rxdata,o_h2l);input i_clk;input i_rst_n;input i_rxdata;output o_h2l;parameter YES=1'b1;parameter NO=1'b0;reg h2l_r1;reg h2l_r2;always @ (posedge i_clk or negedge i_rst_n)if(!i_rst_n)beginh2l_r1<=YES;h2l_r2<=YES;endelsebeginh2l_r1<=i_rxdata;h2l_r2<=h2l_r1;endwire o_h2l;assign o_h2l=h2l_r2&&(!h2l_r1); /*在i_rxdata由高电平向低电平换时产生检测脉冲o_h2*/endmoduleBaud.v 模块简介:根据波特率,产生传输1bit所需的固定时间周期,并在合适的时间输出采样脉冲(此文件可综合)综合软件:quartus ii 11.0代码如下://===========================//Author : wsc//Time : 2013/12/02//File Name : baud.v//==========================module baud (i_clk,i_rst_n,i_baud_en,o_baud_clk);input i_clk;input i_rst_n;input i_baud_en;output o_baud_clk;parameter baud_count_data2=16'd1000; /*待定,可根据实际baud,来确定计数长度*/parameter baud_count_data=16'd500; /*待定,可根据实际baud,确定采样时间*///-------------------------------------------reg [15:0] baud_count; //定义16位计数器always @ (posedge i_clk,negedge i_rst_n)if(!i_rst_n)baud_count<=16'd0;else if(baud_count==baud_count_data2)baud_count<=16'd0;else if(i_baud_en)baud_count<=baud_count+16'd1;elsebaud_count<=16'd0;//-------------------------------------------wire o_baud_clk;assign o_baud_clk=(baud_count==baud_count_data)?1'b1:1'b0; /*采样脉冲输*/ endmodulerx_receive.v 功能简介:此模块主要有一个状态机组成,采集串口输入数据(i_rxdata),并储存数据位与校验位到ov_rx_data_r寄存器,然后输出(此文件可综合)综合软件:quartus ii 11.0代码://===========================//Author : wsc//Time : 2013/12/02//File Name : rx_receive.v//==========================module rx_receive (i_clk,i_rst_n,i_h2l,i_en,i_rxdata,i_baud_clk,iv_oe, /*odd_even*/o_baud_en,o_rx_done,ov_oe,ov_rx_data_r);input i_clk;input i_rst_n;input i_h2l;input i_en;input i_rxdata;input i_baud_clk;input [1:0] iv_oe;output o_baud_en;output o_rx_done;output [1:0] ov_oe;output [8:0] ov_rx_data_r;parameter YES=1'b1;parameter NO=1'b0;reg o_baud_en;reg o_rx_done;reg [1:0] oe_r;reg [3:0] i; /*state*/reg [8:0] rx_data;reg [8:0] ov_rx_data_r;reg [1:0] ov_oe;always @ (posedge i_clk,negedge i_rst_n)if(!i_rst_n)begino_baud_en<=NO;o_rx_done<=NO;i<=4'd0;oe_r<=2'd0;rx_data<=9'd0;ov_rx_data_r<=9'd0;ov_oe<=2'd0;endelse if(i_en)case(i)4'd0: if(i_h2l==YES) /*下降沿,由Detect.提供v*/begini<=i+4'd1;o_baud_en<=YES;end4'd1: if(i_baud_clk==YES) /*start_bit*/i<=i+4'd1;4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8,4'd9: /*data_bit*/if(i_baud_clk==YES)begini<=i+4'd1;rx_data[i-4'd2]<=i_rxdata;oe_r<=iv_oe;end4'd10: /*根据奇偶校验输入使能进行输出设置,00无校验,01,11奇校验,10偶校验*/if(iv_oe==2'b00)i<=4'd12;else if(iv_oe==2'b10) /*odd*/i<=4'd11;else /*even*/i<=4'd11;4'd11:if(i_baud_clk==YES) /*odd_evev_bit*/begini<=i+4'd1;rx_data[8]<=i_rxdata;end4'd12: if(i_baud_clk==YES) /*end_bit*/i<=i+4'd1;4'd13: begin /*输出done信号,为奇偶校验做准备*/o_baud_en<=NO;o_rx_done<=YES;i<=i+4'd1;ov_oe<=oe_r;ov_rx_data_r<=rx_data; /*储存数据到ov_rx_data_r*/end4'd14: begino_baud_en<=NO;o_rx_done<=NO;i<=4'd0;enddefault :begino_baud_en<=NO;o_rx_done<=NO;i<=4'd0;oe_r<=2'd0;rx_data<=9'd0;endendcaseendmoduleodd_even_detect.v 简介:奇偶校验检测模块,对收到的数据进行奇偶校验,奇偶校验出错输出为8’d0,否则原数据输出(此文件可综合)综合软件:quartus ii 11.0代码://===========================//Author : wsc//Time : 2013/12/02//File Name : odd_even_detect.v//==========================module odd_even_detect (i_clk,i_rst_n,i_rx_receive_done,iv_rx_receive_oe,iv_rx_receive_data,o_oe_done,ov_rxdata);input i_clk;input i_rst_n;input i_rx_receive_done;input [1:0] iv_rx_receive_oe;input [8:0] iv_rx_receive_data;output o_oe_done;output [7:0] ov_rxdata;reg o_oe_done;reg [7:0] ov_rxdata;reg [2:0] i;always @ (posedge i_clk,negedge i_rst_n)if(!i_rst_n)begino_oe_done<=1'b0;ov_rxdata<=8'd0;i<=3'd0;endelsecase(i)3'd0: i f(i_rx_receive_done==1'b1)i<=i+3'd1;3'd1:case (iv_rx_receive_oe)2'b00: begin /*无校验,原数据输出*/ov_rxdata<=iv_rx_receive_data[7:0];i<=i+3'd1;end2'b10: if(^iv_rx_receive_data==1'b0) /*odd校验,iv_rx_receive_data缩位异或为0,则正确,原数据输出,产生done信号,否则输出为0,不产生done信号*/beginov_rxdata<=iv_rx_receive_data[7:0];i<=i+3'd1;endelsebeginov_rxdata<=8'd0;i<=3'd3;end2'b01,2'b11: /*even校验,iv_rx_receive_data缩位异或为1,则正确,原数据输出,产生done信号,否则输出为0,不产生done信号*/if(^iv_rx_receive_data==1'b1)beginov_rxdata<=iv_rx_receive_data[7:0];i<=i+3'd1;endelsebeginov_rxdata<=8'd0;i<=3'd3;enddefault :ov_rxdata<=8'd0;endcase3'd2:begino_oe_done<=1'b1;i<=i+3'd1;end3'd3:begino_oe_done<=1'b0;i<=3'd0;enddefault :i<=3'd0;endcaseendmodule顶层文件uart_receive.v:顶层文件,实现串口接收功能,串行数据输入,并行输出(此文件可综合)综合软件:quartus ii 11.0代码://===========================//Author : wsc//Time : 2013/12/02//File Name : uart_receive.v//==========================module uart_receive (i_clk,i_rst_n,i_en,iv_oe, /*odd_even*/i_rxdata,o_done,ov_data);input i_clk;input i_rst_n;input i_en;input [1:0] iv_oe;input i_rxdata;output o_done;output [7:0] ov_data;wire o_h2l;detect u1 (.i_clk(i_clk),.i_rst_n(i_rst_n),.i_rxdata(i_rxdata),.o_h2l(o_h2l));wire i_baud_en,o_baud_clk;baud u2(.i_clk(i_clk),.i_rst_n(i_rst_n),.i_baud_en(i_baud_en),.o_baud_clk(o_baud_clk));wire o_rx_done;wire [1:0] ov_oe;wire [8:0] ov_rx_data_r;rx_receive u3(.i_clk(i_clk),.i_rst_n(i_rst_n),.i_h2l(o_h2l),.i_en(i_en),.i_rxdata(i_rxdata),.i_baud_clk(o_baud_clk),.iv_oe(iv_oe), /*odd_even*/.o_baud_en(i_baud_en),.o_rx_done(o_rx_done),.ov_oe(ov_oe),.ov_rx_data_r(ov_rx_data_r));odd_even_detect u4(.i_clk(i_clk),.i_rst_n(i_rst_n),.i_rx_receive_done(o_rx_done),.iv_rx_receive_oe(ov_oe),.iv_rx_receive_data(ov_rx_data_r),.o_oe_done(o_done),.ov_rxdata(ov_data));endmodule测试文件uart_receive_tb.v简介:对uart_receive.v做简单测试,以确保uart_receive.v逻辑功能设计无误(此文件不可综合)仿真软件:modelsim 6.5代码://===========================//Author : wsc//Time : 2013/12/03//File Name : uart_receive_tb.v//==========================`timescale 1ns/1nsmodule uart_receive_tb ;reg i_clk;reg i_rst_n;reg i_en;reg [1:0] iv_oe;reg i_rxdata;wire o_done;wire [7:0] ov_data;initialbegini_clk<=1'b0;i_rst_n<=1'b1;i_en<=1'b0;#23 i_rst_n<=1'b0;#45 i_rst_n<=1'b1;endalways #10 i_clk<=!i_clk;/*以上实现功能为产生时钟周期为20ns的时钟信号i_clk,及复位信号i_rst_n(低电平有效)*/initial /*产生i_rxdata数据,(由于波特率未定,暂时假设传输一位需要时间为20000ns)*/ beginiv_oe<=2'b00;i_rxdata<=1'b1;#200 i_en<=1'b1;iv_oe<=2'b00; /*无校验位*/i_rxdata<=1'b0;#20000 i_rxdata<=1'b0; /*传输数据为0011 1010*/#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_en<=1'b0;#200 ;//--------------------------i_en<=1'b1;iv_oe<=2'b01; /*奇校验,传输数据为1100 1000*/i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_en<=1'b0;#200 ;//------------------------i_en<=1'b1;iv_oe<=2'b10; /*偶校验,传输数据为1100 1000*/i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b1;#20000 i_en<=1'b0;#200 ;//-----------------------i_en<=1'b1;iv_oe<=2'b11; /*奇校验,传输数据为1100 1010*/i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b1;#20000 i_en<=1'b0;#200 ;//-----------------------i_en<=1'b1;iv_oe<=2'b10; /*偶校验,传输数据为1100 1000,校验位为0,此帧传输出错*/i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_rxdata<=1'b0;#20000 i_rxdata<=1'b1;#20000 i_en<=1'b0;#200 ;//-----------------------#1000 $stop;enduart_receive u1(.i_clk(i_clk),.i_rst_n(i_rst_n),.i_en(i_en),.iv_oe(iv_oe), /*odd_even*/.i_rxdata(i_rxdata),.o_done(o_done),.ov_data(ov_data));endmodule。

相关文档
最新文档