• 【iCore4 双核心板_FPGA】例程十二:基于UART的ARM与FPGA通信实验


    实验现象:

    1、先烧写ARM程序,然后烧写FPGA程序。

    2、打开串口精灵,会接收到字符GINGKO。

    3、通过串口精灵发送命令可以控制ARM·LED和FPGA·LED。

    核心代码:

    int main(void)
    {
    
      /* USER CODE BEGIN 1 */
        int i;
        char buffer[20];
        char buffer1[20];
        
      /* USER CODE END 1 */
    
      /* MCU Configuration----------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_USART6_UART_Init();
      MX_UART4_Init();
    
      /* USER CODE BEGIN 2 */
        uart4.initialize(115200);
        usart6.initialize(115200);
        usart6.printf("Hello,I am iCore4!
    ");
        LED_GREEN_ON;
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
      /* USER CODE END WHILE */
    
      /* USER CODE BEGIN 3 */
            if(usart6.receive_ok_flag == 1){
                usart6.receive_ok_flag = 0;
                for(i = 0;i < 20;i ++){
                    buffer[i] = tolower(usart6.receive_buffer[i]);
                }
                //±È½Ï½ÓÊÕÐÅÏ¢
                if(memcmp(buffer,"ledr",strlen("ledr")) == 0){                //ARMºìµÆÁÁ       
                    LED_RED_ON;
                    LED_GREEN_OFF;
                    LED_BLUE_OFF;
                    uart4.printf("LEDR
    ");                                    //´®¿Ú2Êä³ö
                }
                if(memcmp(buffer,"ledg",strlen("ledg")) == 0){               //ARMÂ̵ÆÁÁ 
                    LED_GREEN_ON;
                    LED_RED_OFF;
                    LED_BLUE_OFF;
                    uart4.printf("LEDG
    ");                                    //´®¿Ú2Êä³ö
                }    
                if(memcmp(buffer,"ledb",strlen("ledb")) == 0){               //ARMÀ¶µÆÁÁ
                    LED_BLUE_ON;
                    LED_GREEN_OFF;
                    LED_RED_OFF;
                    uart4.printf("LEDB
    ");                                    //´®¿Ú2Êä³ö        
                }        
            }
            if (uart4.receive_ok_flag){                                    //´®¿Ú2½ÓÊÕÍê³É
                    uart4.receive_ok_flag = 0;
                    for(i = 0;i < 20;i++){
                    buffer1[i] = uart4.receive_buffer[i];
                }
                    usart6.printf(buffer1);                                      //´®¿Ú4Êä³ö
            }        
        }
      /* USER CODE END 3 */
    
    }
    module txd_rxd(
        input rst_n,
        input uart_clk,
        input rx,
        output tx,
        output led_red,
        output led_green,
        output led_blue
    );
    //---------------------------parameter--------------------------//
    parameter ledr = 40'b01001100_01000101_01000100_01010010_00001010,
                 ledg = 40'b01001100_01000101_01000100_01000111_00001010,
                 ledb = 40'b01001100_01000101_01000100_01000010_00001010;
    
    //---------------------------------rx---------------------------//
    /* 接收模块 */
    reg[3:0]j;
    reg[7:0]data_in;
    reg [39:0]receive_data,data_inr;
    
    always@(posedge uart_clk or negedge rst_n)
        if(!rst_n)
            begin
                j <= 4'd0;
                data_in <= 8'd0;
                data_inr <= 40'd0;
                receive_data <= 40'd0;
            end
        else case(j)
                4'd0:                                                    //判断起始标志
                    begin
                        if(!rx)           
                            begin
                                data_in <= 8'd0;
                                j <= j + 1'd1;
                            end
                        else j <= j;
                    end
                4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8:                //接收数据
                    begin
                        j <= j + 1'd1;
                        data_in <= {rx,data_in[7:1]};
                    end
                4'd9:                                                   //接收校验位
                    begin
                        receive_data <= {receive_data[31:0],data_in};
                        j <= j + 1'd1;
                    end
                4'd10:                                                             //接收停止位
                    begin
                        j <= 1'd0;
                        if(receive_data[7:0] == 8'b00001010)
                            begin
                                data_inr <= receive_data;
                            end
                    end
                default: j <= 4'd0;
        endcase    
    
    //---------------------------------led---------------------------//
    /*对比接收数据 */
    reg [2:0]led;        
    
    always@(posedge uart_clk or negedge rst_n)
        if(!rst_n)
            begin
                led <= 3'b101;
            end
        else if (data_inr == ledr)                  
                led <= 3'b011;
        else if (data_inr == ledg)
                led <= 3'b101;
        else if (data_inr == ledb)
                led <= 3'b110;    
        
    assign {led_red,led_green,led_blue} = led;
    
    //---------------------------------tx---------------------------//
    
    /*发送模块,定时发送GINGKO*/
    reg tx_r;                                                                                  //串行发送数据的寄存器,空闲状态默认为1
    reg[16:0]i;
    reg[7:0]data_out;
    reg[3:0]cnt;
    reg[63:0]GINGKO;
    
    always @(posedge uart_clk or negedge rst_n)
        if (!rst_n)
            begin
                i <= 17'd0;
                tx_r <= 1'd1;                                                                 //空闲状态为1
                cnt <= 4'd0;
                data_out <= 8'd0;
                GINGKO <= {8'd71,8'd73,8'd78,8'd71,8'd75,8'd79,8'd13,8'd10};
            end
        else                                                                                      //开始发送DATA
            case(i)
                17'd0: begin                                                                 //先发送起始位0
                            i <= i + 1'd1;
                            {data_out,GINGKO[63:8]} <= GINGKO;
                            tx_r <= 1'd0;                                                    
                        end
                17'd1,14'd2,14'd3,14'd4,14'd5,14'd6,14'd7,14'd8:                 //tx_r
                        begin
                            i <= i + 1'd1;
                            {data_out[6:0],tx_r} <= data_out;                          //串口发送时,低位在先
                        end                                
                17'd9: begin                                                                 //1位奇偶校验位和1位停止位
                            i <= i + 1'd1;
                            tx_r <= 1'd1;                                      
                        end
                17'd10: begin                                                                 //1位停止位
                            if(cnt == 4'd7)
                                begin
                                    i <= i + 1'd1;
                                    cnt <= 4'd0;
                                end
                            else 
                                begin
                                    i <= 14'd0;
                                    cnt <= cnt + 1'd1;
                                end
                        end
                17'd115200: begin                                                            //定时约为1s                
                                i <= 14'd0;
                                GINGKO <= {8'd71,8'd73,8'd78,8'd71,8'd75,8'd79,8'd13,8'd10};
                        end
                default: i <= i + 1'd1;                                                  //i为其他无效数值时,直接转到退出TXD模块状态
            endcase
    
    assign tx = tx_r;    
    
    endmodule

    源代码下载链接:

    链接:http://pan.baidu.com/s/1nv836RZ 密码:iky7

    iCore4链接:

  • 相关阅读:
    【Java学习笔记之二十一】抽象类在Java继承中的用法小结
    【Java学习笔记之二十】final关键字在Java继承中的用法小结
    【Java学习笔记之十九】super在Java继承中的用法小结
    【Java学习笔记之十八】Javadoc注释的用法
    【Java学习笔记之十七】Java中普通代码块,构造代码块,静态代码块区别及代码示例分析
    hdu 5310(贪心)
    poj3268 最短路
    poj1797 最短路
    poj2253 最短路
    poj2387 最短路
  • 原文地址:https://www.cnblogs.com/xiaomagee/p/7518919.html
Copyright © 2020-2023  润新知