pynq-z2はPFGA開発ボード、つまりピンク色のボードで、かなり高価です。それでは、uart0シリアルポートの使用方法について説明しましょう。
必要な機器:
pynq-z2、データを送信できるUSBケーブル、vivadoソフトウェアを搭載したコンピューター
1.新しいvivadoプロジェクトを作成し、新しいブロックデザインを作成してから、ZYNQやGPIOなどのIPコアを追加します。自動接続後、次の図に示すような回路図を取得できます。
- トップレベルのカプセル化を完了し、ビットストリームファイルの生成を包括的に実現し、xsaファイルをエクスポートすると、ハードウェア部分の準備が整います。
xsaファイル:
set_property PACKAGE_PIN R14 [get_ports {led_0[0]}]
set_property PACKAGE_PIN P14 [get_ports {led_0[1]}]
set_property PACKAGE_PIN N16 [get_ports {led_0[2]}]
set_property PACKAGE_PIN M14 [get_ports {led_0[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_0[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_0[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_0[3]}]
- vitisで新しいプロジェクトとcppファイルを作成し、同時にBSPファイルを作成し、シリアルポートの初期化、シリアルポートの割り込みの初期化、および割り込み処理機能を含むシリアル通信コードを記述します。シリアルポートのボーレートを115200に設定し、ビットを受信するとトリガーします。割り込みモードは通常モードです。
#include "xgpiops_hw.h"
#include <stdio.h>
#include "xil_printf.h"
#include "xuartps.h"
#include "xparameters.h"
#include "xscugic.h"
#include "xuartps_hw.h"
#define LED_BASE XPAR_GPIO_0_S00_AXI_BASEADDR
#define UART_Device_Id XPAR_PS7_UART_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define UART_INT_IRQ_ID XPAR_XUARTPS_0_INTR
#define INTC XScuGic
XUartPs UartPs;
INTC InterruptController;
void uart_init(XUartPs *UartInstPtr,u16 DeviceId)
{
XUartPs_Config *Config;
//根据ID查找配置信息
Config = XUartPs_LookupConfig(DeviceId);
//根据配置信息,初始化UART
XUartPs_CfgInitialize(UartInstPtr, Config, Config->BaseAddress);
//设置波特率
XUartPs_SetBaudRate(UartInstPtr, 115200);
//设置触发阈值
XUartPs_SetFifoThreshold(UartInstPtr, 1);
//改变模式为正常模式
XUartPs_SetOperMode(UartInstPtr, XUARTPS_OPER_MODE_NORMAL);
}
//中断处理函数
void UART_intr_handle(void *call_back_ref)
{
XUartPs *uart_instance_ptr = (XUartPs *)call_back_ref;
u32 rec_data = 0;
u32 isr_status;
//读取中断寄存器
isr_status = XUartPs_ReadReg(uart_instance_ptr->Config.BaseAddress,XUARTPS_IMR_OFFSET);
isr_status &= XUartPs_ReadReg(uart_instance_ptr->Config.BaseAddress,XUARTPS_ISR_OFFSET);
//中断标志状态位,是否为RxFIFO触发
if(isr_status & XUARTPS_IXR_RXOVR)
{
rec_data = XUartPs_RecvByte(XPAR_PS7_UART_0_BASEADDR);
XUartPs_WriteReg(uart_instance_ptr->Config.BaseAddress,XUARTPS_ISR_OFFSET,XUARTPS_IXR_RXOVR);//清除中断
}
XUartPs_SendByte(XPAR_PS7_UART_0_BASEADDR,rec_data);//将接受到的数据返回
XGpioPs_WriteReg(LED_BASE,0,rec_data&0x0f);//将接收到的数据后4位写入LED的状态
}
void uart_intr_int(INTC *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId)
{
//UART控制器中断初始化
XScuGic_Config *IntcConfig;
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler,
IntcInstancePtr);
XScuGic_Connect(IntcInstancePtr, UartIntrId,
(Xil_ExceptionHandler) UART_intr_handle,
(void *) UartInstancePtr);
XUartPs_SetInterruptMask(UartInstancePtr, XUARTPS_IXR_RXOVR);//设置触发leix
XScuGic_Enable(IntcInstancePtr, UartIntrId);//使能中断设备
Xil_ExceptionEnable();
}
int main()
{
//初始化
uart_init(&UartPs,UART_Device_Id);
//UART控制器初始化
uart_intr_int(&InterruptController, &UartPs,UART_INT_IRQ_ID);
//收发数据
print("Hello World\n\r");//打印hello World检测程序是否正常运行
while(1)
{}
return 0;
}
このようにして、シリアルポートの双方向伝送が実現され、シリアルポートが受信したデータを使用してLEDのステータスを制御します。たとえば、シリアルポートが0x0aを送信すると、LEDライトが点灯します。 1010として。