Xilinx_MicroBlaze的使用-Uartlite
说明:通过Vivado生成MicroBlaze工程导入SDK实现LED的控制、串口与PC的通信。
环境:Vivado2018.3。
IP核:MicroBlaze。
参考手册:
pg142: AXI UART Lite v2.0
文章目录
1. MicroBlaze简介
MicroBlaze嵌入式软核是一个被Xilinx公司优化过的可以嵌入在FPGA中的RISC处理器软核,具有运行速度快、占用资源少、可配置强等优点,和其他外设IP核一起,可以完成可编程系统芯片(SOPC)的设计。
FPGA是可编程的硬件逻辑电路,MicroBlaze是一种处理器电路,使用MicroBlaze就相当于在FPGA内部做了一个CPU在里面,可以用C语言编写程序,在这个CPU上跑C语言的软件程序,FPGA偏向逻辑,做控制比较麻烦,CPU做控制比较方便。
2.MicroBlaze设计流程
2.1 .新建工程:
路径、工程名:
芯片选型,针对自己手中的芯片:
2.2 创建Block Design
新建一个Block Design,并重命名:
添加MicroBlaze软核:
添加串口核-AXI Uartlite:(详细了解这个核可以转到Xilinx AXI Uartlite IP核的使用)
添加GPIO核用于控制两个LED:
点击Run Block Automation生成软核必要的一些IP:
点击Run Connection Automation实现自动连线:
全貌:
对以上生成的Block Design进行一下更改:
可以通过一下方式改端口名:
修改
1、时钟:根据自己手中板子输入正确的时钟(比如我用的板子为25MHz单端输入)
取消复位以及锁定信号:
通过以下方式将clk_in1端口引出:
2、复位:将ext_reset_in复位端口删除,引入常量IP核保持不复位
引入常量IP核
设置常量值:
连接复位端口:
3、led:根据自己板子上的LED特性设置IP端口数核输入输出模式(比如我使用的LED低电平亮、高电平灭,两个LED占用两个端口)
4、串口波特率:
最终全貌:
生成HDL顶层文件:
端口约束:
根据自己电路进行端口,并保存至.XDC文件:
在.XDC文件中加入以下语句(对bit文件进行压缩)
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
生成bit流文件:
导出:
选择Include bitstream
Launch SDK:
SDK自动打开…
3. SDK中串口通信与LED实验
.hdf中显示模块IP的操作地址(很重要)
新建Project
编辑工程名:
类型选择C
生成模板:
调试:先进行调试设置
设置完成后点击:
出现以下画面:
在底部显示窗口打开串口终端,在设备管理器查看自己的串口号:
此处波特率要配置与创建IP Block Design里Uartlite中的波特率一样。
点击run
看到串口窗口打印出Hello Word,这就是FPGA通过串口向PC发送的数据。
更改主函数,增加LED的控制。
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
int main()
{
init_platform();
XGpio led;
XGpio_Initialize(&led,XPAR_GPIO_0_DEVICE_ID);
XGpio_SetDataDirection(&led,1,0x00);
//串口
print("Hello World\n\r");
//led
XGpio_DiscreteClear(&led,1,0x03);//亮
XGpio_DiscreteWrite(&led,1,0x03);//灭
cleanup_platform();
return 0;
}
编译(Ctrl+s就可以实现编译)→Debug→Run,分别打了三个断点(Debug状态下,点击函数左边缘处),观察LED亮灭(串口窗口没显示出来实际是打印了Hello World)。
如果直接下载不进入调试:
3. Block Design 在SDK中的灵活运用
在最开始生成SDK工程时显示的这个地址如何使用,在上面的LED实验和串口实验都是用Xil的库函数实现的,现在我们用下面的地址来实现LED实验和串口收发。~~~
首先我们要知道:
访问地址=基地址+偏移地址
基地址:
偏移地址:
3.1 利用地址信息操作GPIO-LED的亮灭
更改主函数如下,利用地址直接控制LED:
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
int main()
{
init_platform();
u32 *ADDR_LED;
ADDR_LED = (u32*)0x40000000;
*ADDR_LED = 0x02;//一灭一亮 0010
*ADDR_LED = 0x01;//一亮一灭 0001
*ADDR_LED = 0x00;//全亮 0000
*ADDR_LED = 0x03;//全亮 0011
cleanup_platform();
return 0;
}
3.2 利用地址信息实现串口的收发
控制串口前我们先阅读手册 pg142-axi-uartlite,并阅读博客Xilinx AXI Uartlite IP核的使用
得到以下寄存器的偏移地址信息(我们目前先读取一下STAT_REG寄存器的初始数据,以及实现串口的数据的发送)
3.2.1 查看串口状态:
观察一下寄存器映射表,地址为08h的状态寄存器的初始值为32‘h0000_0004。
08h:STAT_REG
状态寄存器,包含接收核发送数据FIFO的状态。
更改主函数如下,查看状态寄存器中的值:
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
int main()
{
init_platform();
u32 uart_state;
u32 *ADDR_UART;
ADDR_UART = (u32*)(0x40600000+0x08);
uart_state = *ADDR_UART;
cleanup_platform();
return 0;
}
3.2.2 通过串口发送数据:
串口发送数据,是将数据给TX FIFO即可,即地址为04h的寄存器。
04h:TX FIFO
更改主函数如下,查看状态寄存器中的值:
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
int main()
{
init_platform();
u32 *ADDR_UART;
ADDR_UART = (u32*)(0x40600000+0x04);
*ADDR_UART = 0x55;
*ADDR_UART = 0xAA;
*ADDR_UART = 0xA5;
cleanup_platform();
return 0;
}
★★★如有错误欢迎指导!!!