Verilog实现串口收发

主要逻辑参考stm32篇的GPIO模拟串口,接收主要是捕获开始信号,然后定时采样获取8位数据位(未考虑停止位和校验位)

使用robei eda仿真结果(发送的仿真信号,然后再将接收的信号输出)

Verilog实现串口收发_第1张图片

 

接收:

	
    reg[15:0] uart_clk_count=0;
	reg[15:0] uart_trig_count=0;
	reg[15:0] uart_period=3472;//(1/9600)*33.333Mhz=3472
	reg[15:0] uart_period_tx=3472;
	reg rx_p=0;//接收端口
	reg tx_p=1;//发送端口
	reg[7:0] dataa_out=0;//8'b10101001;
	reg[7:0] datab_out=0;
	reg rx_flag=0;
	reg tx_flag=0;
	reg send_flag=1;
	reg[23:0] send_num="abc";//发送

always @(posedge CLK)
begin
    rx_p=RX;//RX为外部引脚
	if(rx_flag==0&&tx_flag==0&&send_flag==0&&rx_p==0)begin//判断是否应该监听接收数据
		rx_flag=1;//接收标志
		tx_p=1;//发送无数据为高电平(结束位)
		uart_clk_count=0;
		uart_trig_count=0;
		dataa_out=0;
	end
	
	uart_clk_count=1+uart_clk_count;
	
	if(uart_clk_count>(uart_period*uart_trig_count+uart_period+uart_period/4)&&rx_flag==1&&tx_flag==0&&send_flag==0)begin//间隔104us(9600)//recieve
		//tx_p=0;
		if(uart_trig_count<8)dataa_out=dataa_out|(rx_p<

发送:

	if(send_num!=0&&rx_flag==0&&tx_flag==0&&send_flag==0&&uart_clk_count>uart_period*3) send_flag=1;
	//当不处于接收状态且发送数据不为0且间隔时间大于3个bit位没接收数据就启动发送

	if(send_flag==1)begin//启动发送
		tx_flag=1;
		uart_clk_count=0;
		send_flag=0;
		uart_trig_count=0;
	end

	//if(uart_clk_count(uart_period_tx*uart_trig_count+uart_period_tx)) begin//发送数据
			if(uart_trig_count<8)begin//8位数据
				tx_p=(send_num>>uart_trig_count)&1;//先发送低位
				uart_trig_count=1+uart_trig_count;
			end
			else if(uart_trig_count<12) begin //停止位
				tx_p=1;
				uart_trig_count=1+uart_trig_count;

				if(uart_trig_count==12)begin//如果缓冲区还有数据就继续发送,没有就结束
					send_num=send_num>>8;
					if(send_num==0) tx_flag=0;
					else send_flag=1;
				end
			end
		end
		if(tx_flag==0) tx_p=1;
	end	

代码不是完整代码,仅仅把串口部分截取出来,如需使用请根据实际情况进行更改

你可能感兴趣的:(FPGA,fpga开发)