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