【iCore1S 双核心板_FPGA】例程十六:基于SPI的ARM与FPGA通信实验
实验现象:
核心代码:
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