【iCore4 雙核心板_FPGA】例程十三:基於SPI的ARM與FPGA通訊實驗

XiaomaGee發表於2017-09-26

實驗現象:

1、先燒寫ARM程式,然後燒寫FPGA程式。

2、開啟串列埠精靈,通過串列埠精靈給ARM傳送資料從而給FPGA傳送資料 ,會接收到字元HELLO。

3、通過串列埠精靈傳送命令可以控制ARM·LED和FPGA·LED。

命令格式
LEDR\CR\LF ARM·LED、FPGA·LED亮
LEDG\CR\LF ARM·LED、FPGA·LED亮
LEDB\CR\LF ARM·LED、FPGA·LED亮

核心程式碼:

int main(void)
{

  /* USER CODE BEGIN 1 */
    int i;
    char buffer[20];
    char spi_buffer[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_SPI4_Init();
  MX_USART6_UART_Init();

  /* USER CODE BEGIN 2 */
    usart6.initialize(115200);
    usart6.printf("Hello,I am iCore4!\r\n");
    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){
                LED_RED_ON;
                LED_GREEN_OFF;
                LED_BLUE_OFF;
            }
            if(memcmp(buffer,"ledg",strlen("ledg")) == 0){
                LED_GREEN_ON;
                LED_RED_OFF;
                LED_BLUE_OFF;
            }    
            if(memcmp(buffer,"ledb",strlen("ledb")) == 0){
                LED_BLUE_ON;
                LED_GREEN_OFF;
                LED_RED_OFF;
            }        
            spi4.write(strlen(buffer),(unsigned char *)buffer);
            for (i = 0;i < 100; i++);
            
            SPI4_CS_OFF;
            for(i = 0; i < 5; i++){                                               //SPI½ÓÊÕÊý¾Ý
                spi_buffer[i] = spi4.send_data(0x00);
            }
            SPI4_CS_ON;
                
            usart6.printf(spi_buffer);                
        }
  }
  /* USER CODE END 3 */

}
module spi_ctrl(
    input clk_25m,
    input rst_n,
    input spi_clk,
    input spi_mosi,
    input spi_cs,
    output spi_miso,
    output led_red,
    output led_green,
    output led_blue
);
//--------------------------parameter--------------------------//
parameter ledr = {8'd108,8'd101,8'd100,8'd114},
             ledg = {8'd108,8'd101,8'd100,8'd103},
             ledb = {8'd108,8'd101,8'd100,8'd98},
             hello = {8'd104,8'd101,8'd108,8'd108,8'd111};
             
//--------------------------spi_mosi---------------------------//             
reg[3:0]i;
reg[7:0]data_in;
reg [39:0]temp_data,data;

always@(posedge spi_clk or negedge rst_n)
    if(!rst_n)
        begin
            i <= 4'd0;
            temp_data <= 40'd0;
            data <= 40'd0;
            data_in <= 8'd0;
        end
    else case(i)   //從高位開始接收資料,每8個spi_clk時鐘接收一個Byte
        4'd0:
            begin
                i <= i + 1'd1;
                data_in <= {data_in[6:0],spi_mosi};
                temp_data <= {temp_data[31:0],data_in};
                if(data_in == 8'd13)
                    begin
                        data <= temp_data;
                    end
                else 
                    begin
                        data <= data;
                    end
            end
        4'd1,4'd2,4'd3,4'd4,4'd5,4'd6:
            begin
                i <= i + 1'd1;
                data_in <= {data_in[6:0],spi_mosi};
            end
        4'd7:begin
                i <= 4'd0;
                data_in <= {data_in[6:0],spi_mosi};
            end
        default: i <= 4'd0;
    endcase

//--------------------------data----------------------------//
/*對比接收資料*/
reg [2:0]led;    

always@(posedge clk_25m or negedge rst_n)
    if(!rst_n)
        begin
            led <= 3'b101;
        end
    else if (data == ledr)
            led <= 3'b011;                   //紅燈亮
    else if (data == ledg)
            led <= 3'b101;                            //綠燈亮
    else if (data == ledb)
            led <= 3'b110;                            //藍燈亮
            
assign {led_red,led_green,led_blue} = led;

//--------------------------delay----------------------------//
    reg spi_clk_r;
    always@(posedge clk_25m or negedge rst_n)
        if(!rst_n)
            begin
                spi_clk_r <= 1'd1;
            end
        else 
            spi_clk_r <= spi_clk; 

//--------------------------spi_miso----------------------------//
/*傳送模組*/
reg [39:0]data_out;
reg [5:0]j;
reg spi_out;
always@(negedge spi_clk_r or negedge rst_n)
    if(!rst_n)
        begin
            data_out <= hello;
            spi_out <= 1'd0;
            j <= 6'd0;
        end
    else case(j)  //連續40個spi_clk_r時鐘傳送“hello”字串
        6'd0:
            begin
                {spi_out,data_out[39:1]} <= data_out;
                j <= j + 1'd1;
            end
        6'd39:
            begin
                {spi_out,data_out[39:1]} <= data_out;
                data_out <= hello;
                j <= 6'd0;
            end
        default:
            begin
                {spi_out,data_out[39:1]} <= data_out;
                j <= j + 1'd1;
            end
    endcase

assign spi_miso = spi_out;
//--------------------------endmodule----------------------------//


endmodule

原始碼下載連結:

連結:http://pan.baidu.com/s/1kUDbJoz 密碼:du7e

iCore4連結:

相關文章