您的位置:首页 > 其它

【iCore4 双核心板_FPGA】例程十二:基于UART的ARM与FPGA通信实验

2017-09-14 09:09 597 查看
实验现象:

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

2、打开串口精灵,会接收到字符GINGKO。

3、通过串口精灵发送命令可以控制ARM·LED和FPGA·LED。



核心代码:

int main(void)
{

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

/* USER CODE BEGIN 2 */
uart4.initialize(115200);
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){                //ARMºìµÆÁÁ
LED_RED_ON;
LED_GREEN_OFF;
LED_BLUE_OFF;
uart4.printf("LEDR\n");                                    //´®¿Ú2Êä³ö
}
if(memcmp(buffer,"ledg",strlen("ledg")) == 0){               //ARMÂ̵ÆÁÁ
LED_GREEN_ON;
LED_RED_OFF;
LED_BLUE_OFF;
uart4.printf("LEDG\n");                                    //´®¿Ú2Êä³ö
}
if(memcmp(buffer,"ledb",strlen("ledb")) == 0){               //ARMÀ¶µÆÁÁ
LED_BLUE_ON;
LED_GREEN_OFF;
LED_RED_OFF;
uart4.printf("LEDB\n");                                    //´®¿Ú2Êä³ö
}
}
if (uart4.receive_ok_flag){                                    //´®¿Ú2½ÓÊÕÍê³É
uart4.receive_ok_flag = 0;
for(i = 0;i < 20;i++){
buffer1[i] = uart4.receive_buffer[i];
}
usart6.printf(buffer1);                                      //´®¿Ú4Êä³ö
}
}
/* USER CODE END 3 */

}


module txd_rxd(
input rst_n,
input uart_clk,
input rx,
output tx,
output led_red,
output led_green,
output led_blue
);
//---------------------------parameter--------------------------//
parameter ledr = 40'b01001100_01000101_01000100_01010010_00001010,
ledg = 40'b01001100_01000101_01000100_01000111_00001010,
ledb = 40'b01001100_01000101_01000100_01000010_00001010;

//---------------------------------rx---------------------------//
/* 接收模块 */
reg[3:0]j;
reg[7:0]data_in;
reg [39:0]receive_data,data_inr;

always@(posedge uart_clk or negedge rst_n)
if(!rst_n)
begin
j <= 4'd0;
data_in <= 8'd0;
data_inr <= 40'd0;
receive_data <= 40'd0;
end
else case(j)
4'd0:                                                    //判断起始标志
begin
if(!rx)
begin
data_in <= 8'd0;
j <= j + 1'd1;
end
else j <= j;
end
4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8:                //接收数据
begin
j <= j + 1'd1;
data_in <= {rx,data_in[7:1]};
end
4'd9:                                                   //接收校验位
begin
receive_data <= {receive_data[31:0],data_in};
j <= j + 1'd1;
end
4'd10:                                                             //接收停止位
begin
j <= 1'd0;
if(receive_data[7:0] == 8'b00001010)
begin
data_inr <= receive_data;
end
end
default: j <= 4'd0;
endcase

//---------------------------------led---------------------------//
/*对比接收数据 */
reg [2:0]led;

always@(posedge uart_clk or negedge rst_n)
if(!rst_n)
begin
led <= 3'b101;
end
else if (data_inr == ledr)
led <= 3'b011;
else if (data_inr == ledg)
led <= 3'b101;
else if (data_inr == ledb)
led <= 3'b110;

assign {led_red,led_green,led_blue} = led;

//---------------------------------tx---------------------------//

/*发送模块,定时发送GINGKO*/
reg tx_r;                                                                                  //串行发送数据的寄存器,空闲状态默认为1
reg[16:0]i;
reg[7:0]data_out;
reg[3:0]cnt;
reg[63:0]GINGKO;

always @(posedge uart_clk or negedge rst_n)
if (!rst_n)
begin
i <= 17'd0;
tx_r <= 1'd1;                                                                 //空闲状态为1
cnt <= 4'd0;
data_out <= 8'd0;
GINGKO <= {8'd71,8'd73,8'd78,8'd71,8'd75,8'd79,8'd13,8'd10};
end
else                                                                                      //开始发送DATA
case(i)
17'd0: begin                                                                 //先发送起始位0
i <= i + 1'd1;
{data_out,GINGKO[63:8]} <= GINGKO;
tx_r <= 1'd0;
end
17'd1,14'd2,14'd3,14'd4,14'd5,14'd6,14'd7,14'd8:                 //tx_r
begin
i <= i + 1'd1;
{data_out[6:0],tx_r} <= data_out;                          //串口发送时,低位在先
end
17'd9: begin                                                                 //1位奇偶校验位和1位停止位
i <= i + 1'd1;
tx_r <= 1'd1;
end
17'd10: begin                                                                 //1位停止位
if(cnt == 4'd7)
begin
i <= i + 1'd1;
cnt <= 4'd0;
end
else
begin
i <= 14'd0;
cnt <= cnt + 1'd1;
end
end
17'd115200: begin                                                            //定时约为1s
i <= 14'd0;
GINGKO <= {8'd71,8'd73,8'd78,8'd71,8'd75,8'd79,8'd13,8'd10};
end
default: i <= i + 1'd1;                                                  //i为其他无效数值时,直接转到退出TXD模块状态
endcase

assign tx = tx_r;

endmodule


源代码下载链接:

链接:http://pan.baidu.com/s/1nv836RZ 密码:iky7

iCore4链接:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐