Verilog implements serial port sending and receiving

The main logic refers to the GPIO analog serial port in the stm32 article. The reception is mainly to capture the start signal, and then sample regularly to obtain 8 data bits (stop bits and check bits are not considered)

Use robei eda simulation results (send the simulation signal, and then output the received signal)

 

take over:

	
    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;

send:

	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	

The code is not a complete code, only the serial port part is intercepted. If you need to use it, please make changes according to the actual situation.

Guess you like

Origin blog.csdn.net/hhcgn/article/details/131684328
Recommended