MCU与FPGA串口通信

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_clk
reg        [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

endmodule
/*************** 用户定义参数 *****************************/

#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    <reg51.h>

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<<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;
    }
}
时间: 2024-11-10 18:53:34

MCU与FPGA串口通信的相关文章

关于单片机串口通信的问题

最近在调板子的时候又遇到了单片机MCU检测不到的问题,之前百度了一堆驱动问题,已经可以正常烧写程序,但是昨天又写不了了,连单片机都检测不到,将驱动器的RxD与TxD短接,使用串口助手自己给自己发送数字,是可以接收到的,证明仿真器没有问题,交换驱动器与单片机的RxD与TxD,从顺接改为交叉连接,还是不行.后来在一哥们的指导下解决了该问题.然后发 现一个小小的串口通信其实门道很多,特别是对于对单片机不熟悉的初级选手是个不小的挑战,所以今天跟小伙伴们聊聊我的感受. 我的问题概而论之就是对于CH340驱

[VISA]实现PC与外设串口通信功能

简述 串口通信是使用非常广泛的通信协议之一,一般都是指的RS232,一般PC都会支持串口的,对于速度要求不是特别高的,用串口来通信相对比较简单,而且成本也很低. 关于RS232 RS232常见的9针串口接口,其电平其实是-15V和15V的,-15V貌似表示数据1,而15V表示数据0.而一般单片机的UART接口是使用的TTL电平,0表示低电平,1表示高电平.因此单片机的UART和PC的RS232之间需要有一个转换,有许多成熟的IC可以使用.RS232的通信协议也相对简单. 关于VISA LabVI

RS232串口通信

RS232串口经常使用在PC机与FPGA通信中,用于两者之间的数据传输,因为UART协议简单.易实现,故经常使用. DB9接口只需要使用3根线,RXD(2).TXD(3)和GND(5),如下图所示.而用FPGA实现控制器时只需要利用RXD和TXD两根线即可完成串口通信. UART的异步通信协议如下所示: 1. 首先接受双方提前定义好通信的速度和格式等信息: 2. 如果是空闲状态,发送器一直将数据线拉高: 3. 开始通信时,发送器将数据线拉低,从而接收器能知道数据字节即将过来: 4. 数据位通常是

51单片机串口通信(字符串接收和发送)

1 #include<reg52.h> 2 3 //------------------串口通信协议-----------------// 4 /* 5 客户端数据包格式解释(长度恒为15): 6 例如:A01_fmq_01Off___# 7 A--------数据包的开始标记(可以为A到Z,意味着数据包可以有26种) 8 01-----设备代号 9 fmq_01Off___--------指令(长度恒为10),指令的前4个人字符是指令头部,指令的后6个字符是指令尾部 10 #--------

51单片机之串口通信(三)

51单片机之串口通信(三) 已有 47 次阅读2015-12-29 00:21 |个人分类:51单片机| 单片机, 通信 用串口实现发送和接收同时可操作: 电脑显示结果如图: 源程序: /*项目名称:串口发送接收实验项目内容:串口发送接收同时进行,计算机发送数据给单片机控制P0口,从而控制LED灯的亮灭,单片机发送数据到计算机,计算机显示出来时间:2015年12月23日项目负责人:YUAN*/#include <reg52.h>typedef unsigned char uChar8;type

(转载)用vs2010开发基于VC++的MFC 串口通信一*****两台电脑同一个串口号之间的通信

此文章以visual C++数据採集与串口通信測控应用实战为參考教程 此文章适合VC++串口通信入门 一.页面布局及加入控件 1, 安装好vs2010如图 2, 新建一个基于VC++的MFC项目comm 注意:点击ok,然后next,这时候要将application type改成dialog base.接着next到最后一个对话框是将generated dasses改成CcommDlg,然后finish 4, 将新生成的项目的对话框默认dialog edit删去,如图 5,在对话框中加入两个st

嵌入式Linux裸机开发(七)——UART串口通信

嵌入式Linux裸机开发(七)--UART串口通信 一.UART串口通信简介 通用异步收发器简称UART,即UNIVERSAL ASYNCHRONOUS RECEIVER AND TRANSMITTER, 它用来传输串行数据.发送数据时, CPU 将并行数据写入UART,UAR按照一定的格式在一根电线上串 行发出:接收数据时, UART检测另一根电线的信号,将串行收集在缓冲区中, CPU 即可读取 UART 获得这些数据. 在 S5PV210中, UART提供了 4 对独立的异步串口I/O端口,

51单片机之串口通信(一)

一.基础知识 1.串行通信和并行通信:目前用的比较多的是串行通信.串行通信优点是连接简单,传输距离远:缺点是传输速度慢. 2.串行通信:分为同步通信和异步通信:异步通信是指发送和接收设备利用各自的时钟控制数据的发送和接收. 3.串行通信的传输方向:单工,半双工,全双工. 4.波特率:每秒钟传输2进制代码的位数,如1个字节为10位,每秒传输240个字节,则波特率为10*240=2400bps,单位是bps: 5.RS-232C:25个管脚,我们用到的是PGND(保护接地).TXD(发送数据),RX

转:Qt编写串口通信程序全程图文讲解

转载:http://blog.csdn.net/yafeilinux/article/details/4717706  作者:yafeilinux (说明:我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自己改动.) 在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourceforge.net/projects/qextser