一、开发环境 Zynq7020 + Vivado2017.4
二、开发背景:会使用 Vivado 开发工具,不熟悉的可以参考正点原子开发文档
三、功能实现,LED 定时闪烁
四、实现步骤:
1、配置 PS 端 Block Design MIO 功能, 根据配置表编写代码
2、导出到 SDK,编写代码,编译运行
#include <xil_printf.h> // 包含 xil_printf()函数
#include "xparameters.h" // 器件参数信息 系统生成
#include "xstatus.h" // 包含 库的故障码 的宏定义
#include "xgpiops.h" // 包含 PS GPIO 的函数声明
#include "xplatform_info.h" // 获取当前的平台信息
#include "sleep.h" // 睡眠延时接口
#include "xtime_l.h"
/* 重新定义 */
#define printf xil_printf
/* gpio 设备,不知为何为 0 */
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID // 0
/* GPIO 映射 */
#define BOARD_LED0 (7)
#define BOARD_LED1 (8)
#define CORE_LED (0)
static XGpioPs s_psGpio = {0};
/* 毫秒延时 */
void msleep(int ms)
{
/* 64 bit 记录时间 */
XTime tEnd;
XTime tCur;
/* 获取当前时间 */
XTime_GetTime(&tCur);
/* 计算理论结束时间 */
tEnd = tCur + ((((XTime) ms) * COUNTS_PER_SECOND) / 1000);
/* 阻塞一致查询当前时间是否超时,一直占用 CPU */
do
{
XTime_GetTime(&tCur);
}while (tCur < tEnd);
}
int main(int argc, char* argv[])
{
printf("%s XGetPlatform_Info = %d\r\n", __func__, XGetPlatform_Info());
/* 通过设备 ID 找到对应的配置指针 */
XGpioPs_Config *ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
/* 通过配置指针初始化GPIO */
int Status = XGpioPs_CfgInitialize(&s_psGpio, ConfigPtr,
ConfigPtr->BaseAddr);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/* 设置 GPIO 方向输出,这里为什么会共用一个 GPIO 结构体?参数一致? */
XGpioPs_SetDirectionPin(&s_psGpio, BOARD_LED0, 1);
XGpioPs_SetDirectionPin(&s_psGpio, BOARD_LED1, 1);
XGpioPs_SetDirectionPin(&s_psGpio, CORE_LED, 1);
/* 使能 GPIO */
XGpioPs_SetOutputEnablePin(&s_psGpio, BOARD_LED0, 1);
XGpioPs_SetOutputEnablePin(&s_psGpio, BOARD_LED1, 1);
XGpioPs_SetOutputEnablePin(&s_psGpio, CORE_LED, 1);
/* 点灯 1s改变一次电平 */
for (int i = 0; i < 5; i++)
{
XGpioPs_WritePin(&s_psGpio, BOARD_LED0, 0);
XGpioPs_WritePin(&s_psGpio, BOARD_LED1, 0);
sleep(1);
XGpioPs_WritePin(&s_psGpio, BOARD_LED0, 1);
XGpioPs_WritePin(&s_psGpio, BOARD_LED1, 1);
sleep(1);
}
/* 点灯 0.2s改变一次电平 */
for (int i = 0; i < 10; i++)
{
XGpioPs_WritePin(&s_psGpio, CORE_LED, 0);
msleep(200);
XGpioPs_WritePin(&s_psGpio, CORE_LED, 1);
msleep(200);
}
return 0;
}
3、代码解释:
(1)void msleep(int ms) 接口,暂时只找到 sleep 秒级延时API,如果需要更小的延时,进入 sleep 接口内部,发现实现的方式是获取了CPU当前的计数时钟节拍,
这样就简单了,参考 sleep 的的实现方式,把需要等待的计数值 除以 1000 即可求出,毫秒级的延时时间。关键函数:XTime_GetTime
(2)GPIO MIO 驱动流程:
1)XGpioPs_LookupConfig:通过设备 ID 找到对应的配置指针
2)XGpioPs_CfgInitialize:初始化 GPIO
3)XGpioPs_SetDirectionPin:设置 GPIO 控制方向,可以是输出,也可以是输入,上述代码是输出部分
4)XGpioPs_SetOutputEnablePin:使能 GPIO 输出
5)XGpioPs_WritePin:控制电平高低,这样就可以自由控制输出啦