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.

Reviewed by: Pengjing

Leave a Reply

Your email address will not be published. Required fields are marked *