博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【iCore4 双核心板_FPGA】例程十四:基于I2C的ARM与FPGA通信实验
阅读量:7121 次
发布时间:2019-06-28

本文共 8801 字,大约阅读时间需要 29 分钟。

实验现象:

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

2、打开串口精灵,通过串口精灵给ARM发送数据从而给FPGA发送数据 ,会接收到字符GINGKO。

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 i2c_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_USART6_UART_Init();  /* USER CODE BEGIN 2 */    i2c.initialize();    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;                i2c.write_nbyte(0x03,0X8F,buffer,strlen(buffer));   //i2c×ÜÏß·¢ËÍÊý¾Ý            }            if(memcmp(buffer,"ledg",strlen("ledg")) == 0){                LED_RED_OFF;                LED_GREEN_ON;                LED_BLUE_OFF;                i2c.write_nbyte(0x03,0X8F,buffer,strlen(buffer));            }            if(memcmp(buffer,"ledb",strlen("ledb")) == 0){                LED_RED_OFF;                LED_GREEN_OFF;                LED_BLUE_ON;                i2c.write_nbyte(0x03,0X8F,buffer,strlen(buffer));            }                    for(i = 0; i < 1000; i ++);            i2c.read_nbyte(0x02,0x0F,i2c_buffer,0x06);            //i2c×ÜÏß½ÓÊÕÊý¾Ý            usart6.printf(i2c_buffer);                    }  }  /* USER CODE END 3 */}
module i2c_ctrl(    input clk_25m,    input rst_n,    input scl,    inout sda,    output led_red,    output led_green,    output led_blue    );//---------------------------parameter--------------------------//parameter ledr = {
8'd108,8'd101,8'd100,8'd114,8'd13}, ledg = {
8'd108,8'd101,8'd100,8'd103,8'd13}, ledb = {
8'd108,8'd101,8'd100,8'd98,8'd13}, GINGKO = {
8'd71,8'd73,8'd78,8'd71,8'd75,8'd79}, wide = 6'd40;//-----------------------------address--------------------------// reg[4:0]m;reg[7:0]device_address,word_address; //接收地址先传输高位always@(posedge scl or negedge rst_n) if(!rst_n) begin m <= 5'd0; device_address <= 8'd0; word_address <= 8'd0; tx_en <= 1'd0; tx_en <= 1'd0; end else case(m) 5'd0,5'd1,5'd2,5'd3,5'd4,5'd5,5'd6,5'd7: //接收设备地址 begin if(!rx_en || !tx_en) begin m <= m + 1'd1; device_address <= {device_address[6:0],sda}; end else m <= 5'd0; end 5'd8: begin if(device_address == 8'd3 || device_address == 8'd2) begin m <= 5'd9; device_address <= 8'd0; end else if(rx_ack || tx_ack) begin m <= 5'd18; device_address <= 8'd0; end else begin m <= 5'd0; end end 5'd9,5'd10,5'd11,5'd12,5'd13,5'd14,5'd15,5'd16: //接收寄存器地址,以寄存器地址区分读写操作 begin m <= m + 1'd1; word_address <= {word_address[6:0],sda}; end 5'd17: begin if(word_address == 8'h8f) //使能接收数据 begin rx_en <= 1'd1; word_address <= 8'd0; end else if(word_address == 8'h0f) //使能发送数据 begin tx_en <= 1'd1; word_address <= 8'd0; end else if(rx_ack) begin rx_en <= 1'd0; m <= 5'd0; end else if(tx_ack) begin tx_en <= 1'd0; m <= 5'd18; end else m <= 5'd17; end 5'd18:begin m <= 5'd0; end endcase //-------------------------------rx---------------------------// /*接收数据*/reg[63:0]data_in;reg[63:0]data;reg[4:0]i;reg tx_en,rx_en;reg rx_ack;always@(posedge scl or negedge rst_n) if(!rst_n) begin i <= 5'd0; data <= 64'd0; data_in <= 64'd0; rx_ack <= 1'd0; end else if(rx_en) begin case(i) 5'd0,5'd1,5'd2,5'd3,5'd4,5'd5,5'd6,5'd7: //移位完成数据接收 begin i <= i + 1'd1; rx_ack <= 1'd0; data_in <= {data_in[62:0],sda}; end 5'd8: begin if(data_in[7:0] == 8'h0d) begin i <= 5'd9; rx_ack <= 1'd1; data <= data_in; end else begin i <= 5'd0; end end 5'd9:begin rx_ack <= 1'd0; i <= 5'd0; end default:i <= 5'd0; endcase end //-----------------------------data-------------------------// /*比较接收数据*/reg [2:0]led; always@(posedge clk_25m or negedge rst_n) if(!rst_n) begin led <= 3'b101; end else if (data[wide-1:0] == ledr) led <= 3'b011; else if (data[wide-1:0] == ledg) led <= 3'b101; else if (data[wide-1:0] == ledb) led <= 3'b110; assign {led_red,led_green,led_blue} = led; //----------------------------tx--------------------------// //发送数据 先传输高位reg[47:0]data_out;reg[3:0]j;reg send_data;reg tx_ack;reg[2:0]tx_cnt;always@(negedge scl or negedge rst_n) if(!rst_n) begin j <= 4'd0; send_data <= 1'd1; tx_ack <= 1'd0; tx_cnt <= 3'd0; data_out <= GINGKO; end else case(j) 4'd0,4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7: //移位输出数据 begin if(tx_en) begin j <= j + 1'd1; {send_data,data_out[47:1]} <= data_out; tx_ack <= 1'd0; end end 4'd8:begin if(tx_cnt == 3'd5) //判断最后一个字节,停止发送 begin j <= j + 1'd1; tx_ack <= 1'd1; tx_cnt <= 3'd0; end else begin j <= 4'd0; tx_ack <= 1'd0; tx_cnt <= tx_cnt + 1'd1; end end 4'd9:begin j <= 4'd0; tx_ack <= 1'd0; data_out <= GINGKO; end 4'd10:begin j <= 4'd0; tx_ack <= 1'd0; end endcase assign sda = (j >= 4'd1 && j <= 4'd8) ? send_data : 1'dz; endmodule

源代码下载链接:

链接: 密码:an3s

iCore4链接:

转载地址:http://zviel.baihongyu.com/

你可能感兴趣的文章
详解CSS的Flex布局
查看>>
域渗透——Pass The Hash & Pass The Key
查看>>
与Flutter第一次亲密接触-Android 视角
查看>>
Java设计模式---单例模式
查看>>
从源码角度看ContentProvider
查看>>
MMP,我说每年年会我怎么老是中不了奖,原来是这样
查看>>
十二、实战底部(二)
查看>>
阿里最全面试116题:阿里天猫、蚂蚁金服、阿里巴巴面试题含答案
查看>>
前端开发必备网站
查看>>
正则表达式大全(汇总)
查看>>
ELK 使用小技巧(第 5 期)
查看>>
Java并发(9)- 从同步容器到并发容器
查看>>
假如时光倒流,我会这么学习Java
查看>>
iOS--React Native浏览器插件
查看>>
一个JSON字符串和文件处理的命令行神器jq,windows和linux都可用
查看>>
Notification Swift 3 0
查看>>
Ionic Cordova实现软键盘的监听 以及操作大全
查看>>
Android小知识10则(下)
查看>>
Flask源码解析:从第一个版本开始阅读Flask源码
查看>>
JavaScript 工作原理之二-如何在 V8 引擎中书写最优代码的 5 条小技巧(译)
查看>>