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	

코드는 완전한 코드가 아니고 시리얼 포트 부분만 가로채서 사용하고 있으니 꼭 사용하셔야 할 경우 실제 상황에 맞게 변경해 주시기 바랍니다.

Supongo que te gusta

Origin blog.csdn.net/hhcgn/article/details/131684328
Recomendado
Clasificación