PS 端控制GPIO 控制PL端外设

3 篇文章 0 订阅

通过PS 端控制GPIO 控制PL端外设

这篇文章不错,推荐大家去看:PYNQ上手笔记 | ③PS端+PL端点灯

板卡商提供了PL和PS的LED灯,区别在于PS_LED直接接的是PS端的引脚,可以通过PS端引出的MIO管脚进行控制(s2 第一章), PL_LED只能通过PL端的GPIO IP核来控制。

AXI_GPIO_0在硬件上分配好了地址,

最好还是一个GPIO channel分配一种PL外设,这样可以更明确的控制外设。

在对GPIO 一个channel写入数据的时候,是通过bit对相应的io进行控制,而且使用XGpio_SetDataDirection函数对
相应的io进行设置输入输出的模式,再在写入寄存器的去设置数值控制外设状态
,举例说明:

#define LED 0X03  二进制为 11 (如果设置为0X0F 对应为所有寄存器全部拉高)

函数 XGpio_SetDataDirection(&Gpio, LED_CHANNEL, ~LED) =》

XGpio_SetDataDirection(&Gpio, LED_CHANNEL, 1(省略30bits,因为都是1)00)  //1为input,0为output

XGpio_DiscreteWrite (&Gpio, LED_CHANNEL, LED) =》

XGpio_DiscreteWrite (&Gpio, LED_CHANNEL, 11)   //对LED1和2电平拉高点亮

以下为一部分代码与解释:

int main(void)
{
	int Status;
	volatile int Delay;

	/* Initialize the GPIO driver */
	Status = XGpio_Initialize(&Gpio, GPIO_EXAMPLE_DEVICE_ID);

	/* Set the direction for all signals as inputs except the LED output */
	XGpio_SetDataDirection(&Gpio, LED_CHANNEL, ~LED);

	/* Loop forever blinking the LED */

	while (1) {
		/* Set the LED to High */
		XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, LED);

		/* Wait a small amount of time so the LED is visible */
		for (Delay = 0; Delay < LED_DELAY; Delay++);

		/* Clear the LED bit Set 
		output discrete(s) to logic 0 for the specified GPIO channel.*/
		XGpio_DiscreteClear(&Gpio, LED_CHANNEL, LED);

		/* Wait a small amount of time so the LED is visible */
		for (Delay = 0; Delay < LED_DELAY; Delay++);
	}

	xil_printf("Successfully ran Gpio Example\r\n");
	return XST_SUCCESS;
}

XGpio Gpio; /* The Instance of the GPIO Driver */
/**
 * The XGpio driver instance data. The user is required to allocate a
 * variable of this type for every GPIO device in the system. A pointer
 * to a variable of this type is then passed to the driver API functions.
 */
typedef struct {
	UINTPTR BaseAddress;	/* Device base address */
	u32 IsReady;		/* Device is initialized and ready */
	int InterruptPresent;	/* Are interrupts supported in h/w */
	int IsDual;		/* Are 2 channels supported in h/w */
} XGpio;

/*
 * The following constants map to the XPAR parameters created in the
 * xparameters.h file. They are defined here such that a user can easily
 * change all the needed parameters in one place.
 */
#define GPIO_EXAMPLE_DEVICE_ID  XPAR_GPIO_0_DEVICE_ID

/* Canonical definitions for peripheral AXI_GPIO_0 */
#define XPAR_GPIO_0_DEVICE_ID XPAR_AXI_GPIO_0_DEVICE_ID

/* Definitions for peripheral AXI_GPIO_0 */
#define XPAR_AXI_GPIO_0_BASEADDR 0x41200000
#define XPAR_AXI_GPIO_0_HIGHADDR 0x4120FFFF
#define XPAR_AXI_GPIO_0_DEVICE_ID 0
//默认情况下interrupt为0,关闭状态
#define XPAR_AXI_GPIO_0_INTERRUPT_PRESENT 0 
//默认情况下使用单输出channel,这个和GPIO的IP核配置有关
//两个channel都是32位,通过两个通道同时控制两个PL端的外设,使用discrete write函数可以写入不同的data
#define XPAR_AXI_GPIO_0_IS_DUAL 0
//在对GPIO channel写入数据的时候,一个channel只能写入同一个控制信息数据,是整个channel的所有width信息一起被控制
//对外设进行相同的控制种类
/****************************************************************************/
/**
* Write to discretes register for the specified GPIO channel.
*
* @param	InstancePtr is a pointer to an XGpio instance to be worked on.
* @param	Channel contains the channel of the GPIO (1 or 2) to operate on.
* @param	Data is the value to be written to the discretes register.
*
* @return	None.
*
* @note		The hardware must be built for dual channels if this function
*		is  used with any channel other than 1.  If it is not, this
*		function will assert. See also XGpio_DiscreteSet() and
*		XGpio_DiscreteClear().
*
*****************************************************************************/
void XGpio_DiscreteWrite(XGpio * InstancePtr, unsigned Channel, u32 Data)
{
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertVoid((Channel == 1) ||
		     ((Channel == 2) && (InstancePtr->IsDual == TRUE)));

	XGpio_WriteReg(InstancePtr->BaseAddress,
			((Channel - 1) * XGPIO_CHAN_OFFSET) + XGPIO_DATA_OFFSET,
			Data);
}

PS端控制PL的外设就是,通过gpio的IP核去连接相应的管脚,然后在SDK开发的时候,在宏编译中电脑会设置好相应的AXI GPIO分配地址,只需要使用的时候先实例化相应的gpio,把结构体通过地址传入就可以了。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将Zynq的EMIO(Extended Multiplexed IO)映射到PS(Processing System)UART串口与外部PL(Programmable Logic)收发数据,需要进行以下步骤: 首先,打开Zynq的Vivado设计工具。创建一个新的工程,并选择适当的目标设备和项目名称。 然后,将Zynq的Processing System界面打开,并找到UART控制器。通过设置寄存器来配置UART的波特率、数据位、停止位等通信参数。确保UART控制器被使能和启用。 接下来,在Zynq的Block Design中,添加一个Zynq Processing System实例。在引脚规划中,将UART的引脚映射为EMIO模式,使其能够与外部PL通信。 在Block Design中,添加AXI GPIO实例,用于控制PL上的UART串口发送和接收数据的引脚。 然后,创建一个AXI UART Lite IP核,并将其连接到Processing System中的M_AXI_GP0总线。 在Block Design中,连接AXI UART Lite的接收和发送接口到AXI GPIO实例的引脚。这样就可以将数据从PL的UART接口发送到外部设备,也可以从外部设备接收数据到PL的UART接口。 完成连接后,生成Bitstream并将其下载到FPGA中。 在Petalinux系统中,通过在设备树(device tree)中配置UART串口和GPIO,来使EMIO与PS相关的外设得以识别并使用。 最后,在Linux系统中,使用UART串口的相应设备节点来进行数据的收发。 综上所述,通过对EMIO引脚和AXI UART Lite的配置,以及在设备树中的配置,就可以将Zynq的EMIO映射到PSUART串口与外部PL收发数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值