您的位置 首页 芯片行情

FPGA与MCU的程序思路

FPGA以9600的波特率向单片机发送32位数据,然后单片机对数据进行解析,显示在显示屏上面\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

FPGA以9600的波特率向单片机发送32位数据,然后单片机对数据进行解析,显示在显示屏上面

波特率的产生 :9600bps是指每秒钟发送9600个bit,即1bit的时间为1/9600,fpga板子自带50M晶振,那么一bit的时间时1/9600/1/50M

在没有检验位的情况下,每一帧数据是10位 第一位起始位 0 2-9位 数据(低位在前,高位在后),第十位 终止位 1

FPGA程序思路 :首先由fpga计数,每隔一段时间产生一个bps_clk,也就是波特率的驱动时钟,发送状态机共分为7个状态

IDLE :发送起始标志为 TX_1 :发送32数据的高八位,其中低位在前,高位在后 …… STOP :终止标志位 STOP_1 : 是专门用来延时的,刚开始没有延时状态

的情况下,FPGA向单片机发送数据过快,非常占用单片机的中断资源,所以加了一个延时模块 stop ,作用是:每发完一次数据等待100ms然后再发第二次数据,这样的

单片机就有时间干别的事情了。

MCU程序思路 :首先在中断函数里面将FPGA发送过来的数据存到一个数组里面来处理,detect-uart()函数是用来分析数组的,首先检测数组里面的起始标志 ‘t’,如果没有检测到

终止标志位‘x’的话,对中间数据进行移位处理,还原以前的32位宽的数据,由于在数据传送时有误码的情况,所以在display中加了三级缓存,来减少出错的可能性。

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;endreg        [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  50_000_00)        cnt_bps_stop <= 0;    else        cnt_bps_stop <= cnt_bps_stop + 1;endassign    stop_done = (cnt_bps_stop == 49_000_00)? 1 : 0;//clk for bpsreg                    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 bpsreg        [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 statelocalparam    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 statereg        [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// statealways @(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;endendmodule

/*************** 用户定义参数 *****************************/#define MAIN_Fosc        11059200L    //define main clock#define Baudrate1        9600        //define the baudrate, 如果使用BRT做波特率发生器,则波特率跟串口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        //定义串口接收缓冲长度/**********************************************************/#include    sfr AUXR1 = 0xA2;sfr    AUXR = 0x8E;sfr S2CON = 0x9A;    //12C5A60S2双串口系列sfr S2BUF = 0x9B;    //12C5A60S2双串口系列sfr IE2   = 0xAF;    //STC12C5A60S2系列sfr BRT   = 0x9C;unsigned char     uart1_wr;        //写指针unsigned char     uart1_rd;        //读指针unsigned char     xdata RX1_Buffer[BUF_LENTH];bit        B_TI;unsigned char     uart2_wr;        //写指针unsigned char     uart2_rd;        //读指针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;/****************** 编译器自动生成,用户请勿修改 ************************************/#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/**********************************************************//******************** 本地函数声明 ***************/void    uart1_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 < 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;        //串口1使用独立波特率发生器, 波特率跟串口2一样    AUXR1 |= (1<<4);    //将UART2从P1口切换到 RXD2--P1.2切换到P4.2   TXD2---P1.3切换到P4.3        uart1_init();    PrintString1(\"串口1测试程序\");        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)        //发送一串字符串{    for (; *puts != 0;    puts++)  UART1_TxByte(*puts);     //遇到停止符0结束}void    uart1_init(void){    PCON |= 0x80;        //UART0 Double Rate Enable    SCON = 0x50;        //UART0 set as 10bit , UART0 RX enable    TMOD &= ~(1<= BUF_LENTH)    uart1_wr = 0;    }    if(TI)    {        TI = 0;        B_TI = 1;    }}

原文标题:MCU与FPGA串口通信

文章出处:【微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

审核编辑:彭菁

免责声明:文章内容不代表本站立场,本站不对其内容的真实性、完整性、准确性给予任何担保、暗示和承诺,仅供读者参考,文章版权归原作者所有。如本文内容影响到您的合法权益(内容、图片等),请及时联系本站,我们会及时删除处理。

作者: admin

为您推荐

如何使用GPU编程优化模型/代码

  使用 Python 和 NumPy 库开发的 HIM 模型在 hackathon 开始时没有并行或 GPU 计算。在活动期间, THINKLAB 团队使用 CuPy 为了使他们的代码在 GPU 上并行运行,然后重点将用户定义的 CUDA 内核应用于参数。结果是 672 倍加速,计算时间从 2 周缩短到大约 30 分钟。\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

NVIDIA驱动程序支持OpenCL和Vulkan进行互操作

  OpenCL 和 Vulkan 之间的互操作在移动和桌面平台上都有很强的需求。 NVIDIA 与 Khronos OpenCL 工作组密切合作,发布了一套临时跨供应商的 KHR 扩展。这些扩展使应用程序能够在 OpenCL 和 Vulkan 等 API 之间高效地共享数据,与使用隐式资源的前一代互操作 API 相比,灵活性显著提高。\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

准备去元宇宙过第二人生?小心别被骗了

准备去元宇宙过第二人生?小心别被骗了   电子发烧友网报道(文/黄山明)随着元宇宙在近期的大火,相信大家对于这一技术已不陌生。但元宇宙因为其特性,也需要建立合适的网络安全防护措施,来应对这项技术带来的独特挑战。并且在元宇宙想要得以持续,需要用去中心化的平权式共享机制与共治机制来作为保障,既要做大“蛋糕”,也要分好“蛋糕”。但问题在于,去中心化的元宇宙,在安全问题上也将面临更大的挑战。     先简单解释一下元\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

代工巨头再次换帅,中芯国际高管频频离职,业绩喜人之下原因为何?

电子发烧友网(文/黄山明)3月17日,中芯国际发出公告,公司代理董事长高永岗博士,获委任为中芯国际董事长,自2022年3月17日生效。而在半年前辞去中芯国际董事长职位的“芯片泰斗”周子学最终以身体原因为由,辞去了执行董事一职。   对于这一次的交接,有业内人士称这是一次完美的交接,对中芯国际乃至中国半导体产业都有着重要的影响。不过另一方面,自周子学辞任中芯国际董事长之后,其股价便一路走低,从半年前的21.1港元降至如今的\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

电子测量仪器企业普源精电上市!年营收超3亿,募资7.6亿加速自研芯片项目

电子发烧友网报道(文/莫婷婷)4月8日,普源精电在科创板上市,发行价格60.88元/股,公开发行股份约3032.74万股,占公司发行后总股本的比例为25%。该股上市当日开盘即破发,截至今日收盘,普源精电报39.78元,跌幅34.66%,总市值48.26亿元。   图源:东方财富   在上市之前,普源精电在招股书的风险因素中提到,“公司无法保证未来几年内实现盈利,公司上市后亦可能面临退市的风险”。2020年、2021年上半年,普源精电分别亏损2716.6万元、2036.48万元,连\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

返回顶部