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

XiaomaGee發表於2017-09-29

實驗現象:

核心程式碼:

int main(void)
{
    int i,n;
    char buffer[20];
    char spi_buffer[20];
    
  HAL_Init();
  system_clock.initialize();

    led.initialize();
  usart1.initialize(115200);
    spi.initialize();
    

    usart1.printf("Hello! I am iCore1S!\r\n");      
    while(1)
        {
        if(usart1.receive_ok_flag)
            {                                           
                usart1.receive_ok_flag = 0;
                for(i = 0;i < 20;i++)
                {
                    buffer[i] = tolower(usart1.receive_buffer[i]);
                }
            n = strlen(buffer);
        
            if(memcmp(buffer,"ledr",strlen("ledr")) == 0)
                {
                   
                    LED_RED_ON;
                    LED_GREEN_OFF;
                    LED_BLUE_OFF;
                }
            if(memcmp(buffer,"ledg",strlen("ledg")) == 0)
                {
                    
                    LED_RED_OFF;
                    LED_GREEN_ON;
                    LED_BLUE_OFF;
                }    
            if(memcmp(buffer,"ledb",strlen("ledb")) == 0)
                {
                   
                    LED_RED_OFF;
                    LED_GREEN_OFF;
                    LED_BLUE_ON;
                }    
            buffer[4]=13;
            n=strlen(buffer);
            spi.write_nbyte(n,buffer);       
            for(i=0;i<5;i++)
            {
                spi_buffer[i] = spi.write_byte(0x00);
            }
            
            
            usart1.printf("%s\n",spi_buffer);
        }
    }
}
    module SPI(
                    input CLK_12M,
                    input spi_clk,
                    input spi_mosi,
                    input spi_cs,
                    output spi_miso,
                    
                    output FPGA_LEDR,
                    output FPGA_LEDG,
                    output FPGA_LEDB
                    );
                    
//-------------------------rst_n---------------------------//
    /*復位訊號*/
    reg [5:0]rst_cnt = 6'd0;
    reg rst_n = 1'd0;
    
    always @(posedge CLK_12M)                        
        if(rst_cnt == 6'd50)
            begin
                rst_n <= 1'd1;
                rst_cnt <= rst_cnt;
            end
        else rst_cnt <= rst_cnt + 1'd1;    
        
//-------------------------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_12M or negedge rst_n)
        if(!rst_n)
            begin
                led <= 3'b111;
            end
        else if (data == ledr)
                led <= 3'b011;                   //紅燈亮
        else if (data == ledg)
                led <= 3'b101;                            //綠燈亮
        else if (data == ledb)
                led <= 3'b110;                            //藍燈亮
                
    assign {FPGA_LEDR,FPGA_LEDG,FPGA_LEDB} = led;

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

實驗方法及指導書:

連結:http://pan.baidu.com/s/1jImpPRo 密碼:c4s0

相關文章