FPGA sends 32-bit data to MCU at 9600 baud rate, and then MCU parses the data and displays it on the display screen
Generation of baud rate: 9600bps means that 9600 bits are sent every second, that is, the time of one bit is 1/9600. The FPGA board is equipped with a 50m crystal oscillator, so the time of one bit is 1/9600/1/50m
In the case of no check bit, each frame data is 10 bits, the first starting bit is 02-9 bits of data (the low bit is in front, the high bit is in back), and the tenth ending bit is 1
FPGA program idea: first, FPGA counts and generates a BPS every other period of time_ CLK, that is, the baud rate drive clock, the transmission state machine is divided into seven states
Idle: TX is the start flag of transmission_ 1: Send the high eight bits of 32 data, in which the low bit is in the front and the high bit is in the back Stop: stop flag bit_ 1: it is specially used for delay. There is no delay state at the beginning
In this case, the FPGA sends data to the MCU too quickly, which takes up the interrupt resources of the MCU very much. Therefore, a delay module stop is added. The function is to wait 100ms after each data sending, and then send the second data
SCM will have time to do other things.
MCU program idea: first, in the interrupt function, the data sent by FPGA is stored in an array for processing. The detect uart() function is used to analyze the array. First, the start flag’t ‘in the array is detected. If it is not detected
If the flag bit ‘x’ is terminated, shift the intermediate data and restore the previous 32-bit wide data. Since there is bit error during data transmission, a three-level cache is added to the display to reduce the possibility of error.
module uart_tx( //global clock input clk, input rst_n, //uart interface output reg uart_tx, //user interface input [31:0] pinlv, input pinlv_value);parameter BPS_9600 = 5208;//parameter BPS_9600 = 10;//count for bps_clkreg [14:0] cnt_bps_clk;always @(posedge clk or negedge rst_n)begin if(!rst_n) cnt_bps_clk <= 1'b0;="" else="" if(pinlv_value="=" 0)="" cnt_bps_clk="">=><= 1'b0;="" else="" if(cnt_bps_clk="=" bps_9600="" -="" 1)="" cnt_bps_clk="">=><= 1'b0;="" else="" cnt_bps_clk="">=><= cnt_bps_clk="" +="" 1;="" end="" reg="" [31:0]="" cnt_bps_stop;="" wire="" stop_done;="" always="" @(posedge="" clk="" or="" negedge="" rst_n)="" begin="" if(!rst_n)="" cnt_bps_stop="">=><= 0;="" else="" if(state="=" stop)="" cnt_bps_stop="">=><= 0;="" else="" if(cnt_bps_stop=""> 50_000_00) cnt_bps_stop <= 0;="" else="" cnt_bps_stop="">=><= cnt_bps_stop="" +="" 1;="" end="" assign="" stop_done="(cnt_bps_stop" =="49_000_00)?" 1="" :="" 0;="" clk="" for="" bps="" reg="" bps_clk;="" always="" @(posedge="" clk="" or="" negedge="" rst_n)="" begin="" if(!rst_n)="" bps_clk="">=><= 1'b0;="" else="" if(cnt_bps_clk="=" 1)="" bps_clk="">=><= 1'b1;="" else="" bps_clk="">=><= 1'b0;="" end="" cnt="" for="" bps="" reg="" [14:0]="" bps_cnt;="" always="" @(posedge="" clk="" or="" negedge="" rst_n)="" begin="" if(!rst_n)="" bps_cnt="">=><= 1'b0;="" else="" if(bps_cnt="=" 10)="" bps_cnt="">=><= 0;="" else="" if(bps_clk)="" bps_cnt="">=><= bps_cnt="" +="" 1'b1;="" else="" bps_cnt="">=><= bps_cnt;="" end="" tx="" state="" localparam="" idle="4'd0;" localparam="" tx_1="4'd1;" localparam="" tx_2="4'd2;" localparam="" tx_3="4'd3;" localparam="" tx_4="4'd4;" localparam="" stop="4'd5;" localparam="" stop_1="4'd6;" cnt="" state="" reg="" [3:0]="" state;="" always="" @(posedge="" clk="" or="" negedge="" rst_n)="" begin="" if(!rst_n)="" state="">=><= idle;="" else="" if(state="=" stop_1="" &&="" stop_done)="" state="">=><= idle;="" else="" if(bps_cnt="=" 10="" &&="" (state="" !="STOP_1))" state="">=><= state="" +="" 1;="" end="" state="" always="" @(posedge="" clk="" )="" begin="" if(bps_clk)="" begin="" case(state)="" idle="" :="" 't'="" di="" --="" gao="" begin="" case(bps_cnt)="" 4'd0="" :="" uart_tx="">=><= 0;="" begin="" 4'd1="" :="" uart_tx="">=><= 0;//data="" 4'd2="" :="" uart_tx="">=><= 0;="" 4'd3="" :="" uart_tx="">=><= 1;="" 4'd4="" :="" uart_tx="">=><= 0;="" 4'd5="" :="" uart_tx="">=><= 1;="" 4'd6="" :="" uart_tx="">=><= 1;="" 4'd7="" :="" uart_tx="">=><= 1;="" 4'd8="" :="" uart_tx="">=><= 0;="" 4'd9="" :="" uart_tx="">=><= 1;="" stop="" default="" :="" uart_tx="">=><= 1;="" endcase="" end="" tx_1="" :="" tx_1byte="" begin="" case(bps_cnt)="" 4'd0="" :="" uart_tx="">=><= 0;="" begin="" 4'd1="" :="" uart_tx="">=><= pinlv[24];//data="" 4'd2="" :="" uart_tx="">=><= pinlv[25];="" 4'd3="" :="" uart_tx="">=><= pinlv[26];="" 4'd4="" :="" uart_tx="">=><= pinlv[27];="" 4'd5="" :="" uart_tx="">=><= pinlv[28];="" 4'd6="" :="" uart_tx="">=><= pinlv[29];="" 4'd7="" :="" uart_tx="">=><= pinlv[30];="" 4'd8="" :="" uart_tx="">=><= pinlv[31];="" 4'd9="" :="" uart_tx="">=><= 1;="" stop="" default="" :="" uart_tx="">=><= 1;="" endcase="" end="" tx_2="" :="" tx_1byte="" begin="" case(bps_cnt)="" 4'd0="" :="" uart_tx="">=><= 0;="" begin="" 4'd1="" :="" uart_tx="">=><= pinlv[16];//data="" 4'd2="" :="" uart_tx="">=><= pinlv[17];="" 4'd3="" :="" uart_tx="">=><= pinlv[18];="" 4'd4="" :="" uart_tx="">=><= pinlv[19];="" 4'd5="" :="" uart_tx="">=><= pinlv[20];="" 4'd6="" :="" uart_tx="">=><= pinlv[21];="" 4'd7="" :="" uart_tx="">=><= pinlv[22];="" 4'd8="" :="" uart_tx="">=><= pinlv[23];="" 4'd9="" :="" uart_tx="">=><= 1;="" stop="" default="" :="" uart_tx="">=><= 1;="" endcase="" end="" tx_3="" :="" tx_1byte="" begin="" case(bps_cnt)="" 4'd0="" :="" uart_tx="">=><= 0;="" begin="" 4'd1="" :="" uart_tx="">=><= pinlv[8];//data="" 4'd2="" :="" uart_tx="">=><= pinlv[9];="" 4'd3="" :="" uart_tx="">=><= pinlv[10];="" 4'd4="" :="" uart_tx="">=><= pinlv[11];="" 4'd5="" :="" uart_tx="">=><= pinlv[12];="" 4'd6="" :="" uart_tx="">=><= pinlv[13];="" 4'd7="" :="" uart_tx="">=><= pinlv[14];="" 4'd8="" :="" uart_tx="">=><= pinlv[15];="" 4'd9="" :="" uart_tx="">=><= 1;="" stop="" default="" :="" uart_tx="">=><= 1;="" endcase="" end="" tx_4="" :="" tx_1byte="" begin="" case(bps_cnt)="" 4'd0="" :="" uart_tx="">=><= 0;="" begin="" 4'd1="" :="" uart_tx="">=><= pinlv[0];//data="" 4'd2="" :="" uart_tx="">=><= pinlv[1];="" 4'd3="" :="" uart_tx="">=><= pinlv[2];="" 4'd4="" :="" uart_tx="">=><= pinlv[3];="" 4'd5="" :="" uart_tx="">=><= pinlv[4];="" 4'd6="" :="" uart_tx="">=><= pinlv[5];="" 4'd7="" :="" uart_tx="">=><= pinlv[6];="" 4'd8="" :="" uart_tx="">=><= pinlv[7];="" 4'd9="" :="" uart_tx="">=><= 1;="" stop="" default="" :="" uart_tx="">=><= 1;="" endcase="" end="" stop="" :="" 'x'="" di="" --="" gao="" begin="" case(bps_cnt)="" 4'd0="" :="" uart_tx="">=><= 0;="" begin="" 4'd1="" :="" uart_tx="">=><= 0;//data="" 4'd2="" :="" uart_tx="">=><= 0;="" 4'd3="" :="" uart_tx="">=><= 0;="" 4'd4="" :="" uart_tx="">=><= 1;="" 4'd5="" :="" uart_tx="">=><= 1;="" 4'd6="" :="" uart_tx="">=><= 1;="" 4'd7="" :="" uart_tx="">=><= 1;="" 4'd8="" :="" uart_tx="">=><= 0;="" 4'd9="" :="" uart_tx="">=><= 1;="" stop="" default="" :="" uart_tx="">=><= 1;="" endcase="" end="" stop_1="" :="" begin="" uart_tx="">=><= 1;="" end="" default="" :="" uart_tx="">=><= 1;="" endcase="" end="" else="" uart_tx="">=><= uart_tx;="" end="">=>=>
/***************User defined parameters *******************************/\define main_ FOSC 11059200l //define main clock\define baudrate1 9600 //define the baudrate. If BRT is used as baudrate generator, the baudrate rate is the same as that of serial port 2 //12t mode: 600~115200 for 22.1184MHz, 300~57600 for 11.0592Mhz \define baudrate2 19200 //define the baudrate2, //12T mode: 600~115200 for 22.1184MHZ, 300~57600 for 11.0592MHZ#define BUF_ Lenth 20 / / define the serial port receive buffer length /*******************************************************/\includesfr AUXR1 = 0xA2; sfr AUXR = 0x8E; sfr S2CON = 0x9A; // 12c5a60s2 dual serial port series SFR s2buf = 0x9b// 12c5a60s2 dual serial port series SFR IE2 = 0xaf// STC12C5A60S2 series SFR BRT = 0x9c; unsigned char uart1_ wr; // Write pointer unsigned char uart1_ rd; // Read pointer unsigned char XDATA rx1_ Buffer[BUF_LENTH]; bit B_ TI; unsigned char uart2_ wr; // Write pointer unsigned char UART2_ rd; // Read pointer unsigned char XDATA rx2_ Buffer[BUF_LENTH]; bit B_ TI2; long temp1 = 0; long temp2 = 0; long temp_ buf1 = 0; long temp_ buf2 = 0; long temp_ buf3 = 0; long temp_ buf = 0; long ce = 9999;/****************** The compiler generates automatically. Please do not modify ********************************************/\define T1_ TimerReload (256 - MAIN_Fosc / 192 / Baudrate1) //Calculate the timer1 reload value at 12T mode#define BRT_ Reload (256 - MAIN_Fosc / 12 / 16 / Baudrate2) //Calculate BRT reload value#define TimeOut1 (28800 / (unsigned long)Baudrate1 + 2)#define TimeOut2 (28800 / (unsigned long)Baudrate2 + 2)#define TI2 (S2CON & 0x02) != 0#define RI2 (S2CON & 0x01) != 0#define CLR_ TI2() S2CON &= ~0x02#define CLR_ Ri2() s2con &= ~0x01/*****************************************************/***************************************_ init(void); void UART1_ TxByte(unsigned char dat); void PrintString1(unsigned char code *puts); void delay(char x){ char i = 0; char t= 0; for(i = 0;i<110;i++) {="" for(t="0;t">110;i++)>< x;t++);="" }="" }="" void="" detect_ uart()="" {="" char="" i="0;" char="" flag="0;" temp1="0;" for(i="0;i"><= uart1_wr="" ;="" i++)="" {="" uart1_txbyte(rx1_buffer[i]);="" if(flag)="" {="" if(rx1_buffer[i]="" !='x' )="" {="" temp1="temp1">=>< 8="" ;="" temp1="temp1" +="" rx1_buffer[i];="" uart1_txbyte(rx1_buffer[i]);="" }="" else="" temp2="temp1;" }= "" if(rx1_buffer[i]="=" 't')="" {="" flag="1;" }= "" }="" }="" void="" ceshi()="" {="" ce="0;" ce="ce">< 8="" ;= "" ce="ce" +="" 0xff;= "" ce="ce">< 8="" ;= "" ce="ce" +="" 0x0c;= "" ce="ce">< 8="" ;= "" ce="ce" +="" 0xcc;= "" ce="ce">< 8="" ;= "" ce="ce" +="" 0xcc;= "" ce="9999;" }= "" void="" display()="" {="" char="" flag="0;" temp_ buf3="temp_buf2;" temp_ buf2="temp_buf1;" temp_ buf1="temp2;" if(temp_buf3="=" temp2)="" {="" temp_buf="temp2;" }= "" else="" {="" temp_buf="temp_buf;" }= "" uart1_ txbyte('s'); uart1_ txbyte('="" '); uart1_ txbyte('="" '); uart1_ txbyte('="" '); uart1_ txbyte('="" ');= "" if(temp_buf/100000000="=" 0)="" bai="" m="" {="" uart1_txbyte('="" ');="" }="" else="" {="" uart1_txbyte(temp_buf/100000000="" +="" 0x30);="" flag="1;" }= "" if(temp_buf/10000000%10="=" 0="" )="" shi="" m="" {="" if(!flag)="" {="" uart1_txbyte('="" ');="" }="" else="" {="" uart1_txbyte(0x30);="" }="" }="" else="" {="" uart1_txbyte(temp_buf/10000000%10="" +="" 0x30);="" flag="1;" }= "" if(temp_buf/1000000%10="=" 0="" )="" m="" {="" if(!flag)="" {="" uart1_txbyte('="" ');="" }="" else="" {="" uart1_txbyte(0x30);="" }="" }="" else="" {="" uart1_txbyte(temp_buf/1000000%10="" +="" 0x30);="" flag="1;" }= "" if(temp_buf/100000%10="=" 0="" )="" bai="" k="" {="" if(!flag)="" {="" uart1_txbyte('="" ');="" }="" else="" {="" uart1_txbyte(0x30);="" }="" }="" else="" {="" uart1_txbyte(temp_buf/100000%10="" +="" 0x30);="" flag="1;" }= "" if(temp_buf/10000%10="=" 0="" )="" shi="" k="" {="" if(!flag)="" {="" uart1_txbyte('="" ');="" }="" else="" {="" uart1_txbyte(0x30);="" }="" }="" else="" {="" uart1_txbyte(temp_buf/10000%10="" +="" 0x30);="" flag="1;" }= "" if(temp_buf/1000%10="=" 0="" )="" k="" {="" if(!flag)="" {="" uart1_txbyte('="" ');="" }="" else="" {="" uart1_txbyte(0x30);="" }="" }="" else="" {="" uart1_txbyte(temp_buf/1000%10="" +="" 0x30);="" flag="1;" }= "" if(temp_buf/100%10="=" 0="" )="" bai="" {="" if(!flag)="" {="" uart1_txbyte('="" ');="" }="" else="" {="" uart1_txbyte(0x30);="" }="" }="" else="" {="" uart1_txbyte(temp_buf/100%10="" +="" 0x30);="" flag="1;" }= "" if(temp_buf/10%10="=" 0="" )="" shi="" {="" if(!flag)="" {="" uart1_txbyte('="" ');="" }="" else="" {="" uart1_txbyte(0x30);="" }="" }="" else="" {="" uart1_txbyte(temp_buf/10%10="" +="" 0x30);="" flag="1;" }= "" if(temp_buf%10="=" 0="" )="" ge="" {="" if(!flag)="" {="" uart1_txbyte('="" ');="" }="" else="" {="" uart1_txbyte(0x30);="" }="" }="" else="" {="" uart1_txbyte(temp_buf%10="" +="" 0x30);="" flag="1;" }= "" }="" void="" main(void)="" {="" char="" i="0;" uart1_ rd="0;" uart1_ wr="0;" uart2_ rd="0;" uart2_ wr="0;" auxr="" |="0x01;" Serial port 1 uses an independent baud rate generator, = "" baud rate is the same as serial port 2 = "" auxr1= "" | = "" > <4); Switch UART2 from P1 port to = "rxd2--p1.2 to p4.2=" "txd2---p1.3 to p4.3=" "uart1_ init();= "" printstring1 ("serial port 1 test program")= "" while(1)="" {="" display();="" detect_uart();="" }="" }="" void="" uart1_ txbyte(unsigned="" char="" dat)="" {="" b_ti="0;" sbuf="dat;" while(!b_ti);= "" b_ ti="0;" delay(10);= ""}= "" void= "" printstring1 (unsigned= "" char= "" code= "" *puts) = "" send a string = "" {= "" for= "" (; = "" *puts= ""! = "0;" puts++)="" uart1_ txbyte(*puts);= "" encountered stop character 0 end = ""}= "" void= "" uart1_ init(void)="" {="" pcon="" |="0x80;" uart0="" double="" rate="" enable="" scon="0x50;" uart0="" set="" as="" 10bit="" ,="" uart0="" rx="" enable="" tmod="" &="">4);>< 6); timer1="" set="" as="" timer,="" 12t="" tmod="(TMOD" &="" ~0x30)="" |="" 0x20;= "" timer1="" set="" as="" 8="" bits="" auto="" relaod="" th1="T1_TimerReload;" load="" the="" timer="" tr1="1;" es="1;" ea="1;" }= "" *********************************************/="" void="" uart0_ rcv="" (void)="" interrupt="" 4="" {="" if(ri)="" {="" ri="0;" rx1_ buffer[uart1_wr]="SBUF;" if(++uart1_wr="">= BUF_LENTH) uart1_ wr = 0; } if(TI) { TI = 0; B_TI = 1; }} 6);>
Original title: serial port communication between MCU and FPGA
Source of the article: [wechat official account: FPGA home] welcome to add your attention! Please indicate the source when reprinting the article.