Verilog实现串口收发

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

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

 

接收:

	
    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<<uart_trig_count);//数据,先接收到低位
		uart_trig_count=uart_trig_count+1;//接收到的bit数
		if(uart_trig_count==10) begin//结束接收
		send_num=(send_num<<8)|dataa_out;//合成8位数据
		uart_clk_count=0;//接收完一个字节
		rx_flag=0;
		if(dataa_out==97) run_flag=0;//判断接收到的数据
		else if(dataa_out==98) run_flag=1;//runb
		else if(dataa_out==117) run_flag=2;//gou
		else if(dataa_out==108) run_flag=3;//leftl
		else if(dataa_out==114) run_flag=4;//rightr
		turn_cont=0;
		end
		
		//tx_p=1;
	end
end
assign TX=tx_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*3) tx_flag=0;

	if(tx_flag==1)begin//send
		if(uart_clk_count<uart_period_tx)//启动信号
			tx_p=0;
		else 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	

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山间朝暮-CanEve

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值