当前位置:   article > 正文

VIVADO SDK的使用

vivado sdk

目录

一、创建 Vivado 工程

二、创建 Processing System

三、配置ZYNQ7 Processing System

(1)配置 PS 的 UART

(2)配置 PS 的 GPIO MIO

(3)配置 PS 的 IIC

 (4)配置 PS 的 DDR3 控制器

(5)配置 PS 的时钟

(6)取消勾选没有用到的接口        

四、导出到SDK

五、SDK设计

六、IIC设计


一、创建 Vivado 工程

1-1 打开 Vivado ,进入 Vivado 界面后,点击“ Quick Start ”栏的 “ Create Project ”。然后在弹出的创
建 Vivado 工程向导界面,点击“Next”。
1-2 进入工程命名界面。设置工程名为“ hello_world” ,工程路径可使用任意路径,本章我们将该工程 放在 F:\ZYNQ\Embedded_System 文件夹下。注意, 工程名和路径只能由英文字母、数字和下划线组成 能包含中文、空格以及特殊字符!
确认已经勾选“ Create project subdirectory , 点击“ Next ”。

1-3 进入图 1.3.4 所示的界面,在此界面设置工程类型。此处我们选择 “ RTL Project ”。本次实验不
需要添加源文件和约束文件,所以勾选“ Do not specify sources at this time ”。勾选之后会省略后面添加源文件和约束文件的步骤,点击“Next ”直接跳到器件选型界面。
1-4 器件选型界面。所选择的器件型号一定要跟领航者核心板上的 ZYNQ 芯片型号保持一致。 大家可以通过查看核心板上 ZYNQ 芯片的丝印来确认所使用的芯片型号。 XC7Z020 的为“-2”,这在器件选型的时候需要注意。此处以 XC7Z020 为例。 选择器件型号的方式有两种,一种是根据 Parts,另一种是根据 Boards ,此处我们使用 Parts 选择器件。 在 Family 栏里选择“ Zynq-7000 , Speed 栏选择“-2”,需要注意的是,在 Package 栏选择“ clg400 ”。然后根据所使用的领航者核心板上的 ZYNQ 芯片型号,在下面的器件列表中选择“ xc7z020clg400-2”。选中之后,点击“ Next ”。
1-5 工程摘要界面。这是创建工程的最后一步,显示工程摘要信息,如 1.3.6 所示。在此界面检查前面所设置的工程名称、所选择的器件型号等信息。如果发现工程设置有误,则可以通过 Back 按钮返回前面的步骤,重新设置。检查无误后点击“Finish ”,完成工程创建。

二、创建 Processing System

        Vivado 开发套件中提供了一个图形化的设计开发工具 ——IP 集成器( IP Integrator ),在 IP 集成器中可以非常方便的插入各种功能模块(IP )。它支持关键 IP 接口的智能自动连接、一键式 IP 子系统生成、实时 DRC 等功能,能够帮助我们快速组装复杂系统,加速设计流程。接下来我们将在 IP 集成器中完成 ZYNQ 嵌入式系统的搭建。
2-1 在左侧导航栏( Flow Navigator )中,单击 IP Integrator 下的 Create Block Design 。然后在弹出的对话框中指定所创建的 Block Design 的名称,在 Design name 栏中输入“ system ”。如下图所示:

2-2 点击“ OK ”按钮,此时 Vivado 界面如下图所示。注意右侧的 Diagram 窗口,我们将在该窗口中以图形化的方式完成设计。

2-3 接下来在 Diagram 窗口中给设计添加 IP 。点击上图中箭头所指示的加号“ + ”,会打开 IP 目录( IP Catalog)。也可以通过快捷键 Ctrl + I ,或者右键点击 Diagram 工作区中的空白位置,然后选择“ ADD IP ”。
2-4 打开 IP 目录后,在搜索栏中键入“ zynq ”,找到并双击“ ZYNQ7 Processing System ”,将 ZYNQ7 处理系统 IP 添加到设计中。
2-5 添加完成后,ZYNQ7 Processing System 模块出现在 Diagram 中,如下图所示:
2-6 双击所添加的 ZYNQ7 Processing System 模块,进入 ZYNQ7 处理系统的配置界面。界面左侧为页 面导航面板,右侧为配置信息面板。如下图所示:
        下面我们简要地介绍一下页面导航面板中各个页面的作用。
        在 Zynq Block Design 页面,显示了 Zynq 处理系统( PS )的各种可配置块,其中灰色部分是固定的, 绿色部分是可配置的,按工程实际需求配置。可以直接单击各种可配置块(以绿色突出显示)进入相应的 配置页面进行配置,也可以选择左侧的页导航面板进行系统配置。
PS-PL Configuration 页面能够配置 PS-PL 接口,包括 AXI HP ACP 总线接口。
Peripheral IO Pins 页面可以为不同的 I/O 外设选择 MIO/EMIO 配置。
MIO Configuration 页面可以为不同的 I/O 外设具体配置 MIO/EMIO
Clock Configuration 页面用来配置 PS 输入时钟、外设时钟,以及 DDR CPU 时钟等。
DDR Configuration 页面用于设置 DDR 控制器配置信息。
SMC Timing Calculation 页面用于执行 SMC 时序计算。
Interrupts 页面用于配置 PS-PL 中断端口。

三、配置ZYNQ7 Processing System

(1)配置 PS UART

        点击 Peripheral I/O Pins 页面,出现以下 IO 引脚配置界面。

        PS 和外部设备之间的连接主要是通过复用的输入 / 输出( Multiplexed Input/Output MIO )来实现的。PS的 54 MIO 引脚可以用于连接不同的外设接口,如图 中的 MIO14 MIO15 ,既可以配置成 UART0 的引脚接口,也可以配置成 I2C0 CAN0 的引脚接口。最终所选择的配置需要与开发板的原理图相对应。
        点击左侧的 MIO Configuration 页面,在右侧展开 I/O Peripherals > UART0 ,可以看到更具体的引脚配置信息。其中 MIO14 作为 RX 引脚、 MIO15 作为 TX 引脚,如下图所示:
        点击左侧的 PS-PL Configuration 页面,我们可以在这里设置 UART0 串口通信的波特率。在 General 目录下,可以看到 UART0 的波特率默认是 115200 。通过下拉按钮可以选择其他波特率,一般保持默认设置。

(2)配置 PS 的 GPIO MIO

        点击左侧的 Peripheral I/O Pins ,在右侧的界面中勾选 GPIO_MIO ,另外开发板上的Bank1 即原理图中的 BANK501 1.8V ,所以我们选择 3 处的 Bank1 电压为 LVCOMS 1.8V 。勾选 GPIO_MIO 后,发现在 GPIO_MIO 这一栏 GPIO_MIO14 15 是灰色的,这是因为这两个 GPIO_MIO 用做 UART0 的接口引脚了。

(3)配置 PS 的 IIC

        要勾选上Quad SPI Flash

         配置I2C 0 为14 15

 (4)配置 PS DDR3 控制器

        点击左侧的 DDR Configuration 页面,在右侧 DDR Controller Configuration 下的“ Memory Part ”一栏选择 DDR 的器件,课题组自己制作的zynq7020板子为MT41K128M16JT-125,DRAM为16Bit;领航者XC7Z020 的核心板选择 MT41J256M16RE-125 XC7Z010 的核心板选择 MT41J128M16 HA-125 。领航者选择的型号并不是领航者核心板上的 DDR3 型号,而是参数接近的型号,或者说兼容的型号。其他的配置选项保持默认即可。

(5)配置 PS 的时钟

        点击左侧的 Clock Configuration 页面,该界面主要是配置 ZYNQ PS 中的时钟频率。比如输入时钟默认 是 33.33333Mhz ,这与我们领航者核心板上的 PS 端输入时钟频率相同。对于 CPU 的时钟、 DDR 的时钟以及其它外设的时钟,我们直接保持默认设置即可。如下图所示:

(6)取消勾选没有用到的接口        

        因为本实验是搭建 ZYNQ 的嵌入式最小系统,只需要使用 ZYNQ 中的 PS 端。因此我们将 PS 中与 PL 端交互的接口信号移除。 同样是在 Clock Configuration 页面,展开 PL Fabric Clocks ,取消勾选 FCLK_CLK0 ,如下图所示:
        点击左侧的 PS-PL Configuration 页面,然后在右侧展开 General 下的 Enable Clock Resets ,取消勾选其中的 FCLK_RESET0_N 。 另外在当前界面中展开 AXI Non Secure Enablement 下的 GP Master AXI Interface ,取消勾选其中的 MAXI GP0 interface。如下图所示:

        配置 ZYNQ7 Processing System 完成,点击“OK”。

       

 点击上图中箭头所指示的位置“Run Block Automation”,会弹出如下图所示的对话框:

        在该界面中我们可以选择自动连接 IP 模块的接口,包括导出外部端口,甚至可以自动添加模块互联过程中所需的IP 。在我们本次设计中只有一个 IP 模块,在左侧确认勾选 processing_system7_0 ,然后点击“ OK ”。 此时 ZYNQ7 PS 模块引出了两组外部接口,分别是 DDR FIXED_IO ,引出的接口将会被分配到 ZYNQ 器件具体的引脚上。大家也可以通过点击 ZYNQ7 PS 模块接口处的加号 “+” ,来展开这两组接口,观察其中都有哪些信号。如下图所示:

四、导出到SDK

        (1)本次实验不需要添加其它 IP ,直接按快捷键 Ctrl+S 保存当前设计。接下来点击下图箭头所指示的按钮,验证当前设计。验证完成后弹出对话框提示没有错误或者关键警告,点击“OK”,如下图所示:
如果验证结果报出错误或者警告,大家需要重新检查自己的设计。
         (2)在 Sources 窗口中,选中 Design Sources 下的 sysetm.bd, 这就是我们刚刚完成的 Block Design 设计。 右键点击 sysetm.bd ,在弹出的菜单栏中选择“ Generate Output Products ”,如下图所示:

         在对话框中 Synthesis Options 选择 Global Run Setings 用于设置生成过程中要使用的处理器的线程数,进行多线程处理,保持默认或设置为个人电脑处理器最大可使用线程数都可以,一般选择最大可使用线程数的一般。然后点击“Generate ”来生成设计的综合、实现和仿真文件。
        在“Generate ”过程中会为设计生成所有需要的输出结果。比如 Vivado 工具会自动生成处理系统的 XDC 约束文件,因此我们不需要手动对 ZYNQ PS 引出的接口(DDR 和 FIXED_IO)进行管脚分配。
        Generate 完成后,在弹出的对话框中点击“OK ”。
        在 Sources 窗口中,点击“ IP Source ”标签页,可以看到 Generate 过程生成的输出结果。
       (3)在“ Hierarchy ”标签页再次右键点击 system.bd ,然后选择“ Create HDL Wrapper ”。

          在弹出的对话框中确认勾选“Let Vivado manage wrapper and auto-update”,然后点击“ OK ”。
        (4)在菜单栏选择 File > Export > Export hardware。

        在弹出的对话框中,因为没有生成 bitstream 文件,所以无需勾选“ Include bitstream ”,直接点击“ OK ” 按钮。 

        在上图中,因为选择了“Exort to <Local to Project>” Vivado 工具会在当前工程目录下新建一个文件夹, 名为“hello_world.sdk” ,它是我们接下来软件开发的工作空间。 在 Export Hardware 的过程中,工具会将硬件以一个 ZIP 压缩文件的形式导出到该工作空间中,文件名为“system_wrapper.hdf” 。该文件包含了我们前面所搭建的硬件平台的配置信息,其后缀名 .hdf 的含义为“Hardware Definition File”,即硬件定义文件。
        (5)硬件导出完成后,在菜单栏中选择 File > Launch SDK ,启动 SDK 开发环境。如下图所示:

        在弹出对话框中,直接点击“OK”,到这里,我们已经完成了 ZYNQ 嵌入式系统的硬件设计部分。接下来需要到 SDK 软件中进行应用程序开发,也就是软件设计部分。

五、SDK设计

         (1)SDK 打开后,主页面会显示硬件描述文件 system.hdf 的内容。如下图所示:

         system.hdf 标签页显示了整个 PS 系统的地址映射信息。大家应该还记得,在启动 SDK 之前,我们将硬件以一个 ZIP 压缩文件(system_wrapper.hdf)的形式导出到软件的工作空间。在 SDK 启动时,该文件会自动解压,大家可以在图 1.4.1 的左侧看到解压后的所有文件。其中,前四个文件(ps7_init_gpl.cps7_init_gpl.hps7_init.c ps7_init.h)包含了 Zynq SOC 处理系统的初始化代码,以及 DDR、时钟、pll MIO 的初始化设置信息。在初始化过程中,SDK 使用这些信息去配置相应的模块,使得应用程序能够在 PS 上运行。

        (2)在菜单栏选择 File > New > Application Project, 新建一个 SDK 应用工程。

        (2)在弹出的图 2.4.4 所示界面中,输入工程名“ gpio_mio ”,注意 2 处的硬件平台,如果我们没有删除 system_wrapper_hw_platform_0 ,该处可能是 system_wrapper_hw_platform_0 ,所以要注意选择正确。其它选项保持默认即可,点击“Next > ”按钮。

        (3) 选择工程模版 Empty Application ,然后点击“Finish”按钮。
        (4)
可以看到 SDK 创建了一个 gpio_mio 目录和 gpio_mio_bsp 目录。我们打开 gpio_mio_bsp 目录下的system.mss 文件,找到 ps7_gpio_0,如下图 所示:

        点击 Documentation 将在浏览器窗口打开 GPIO API 文档,里面有关于 GPIO 的详细信息。
        点击 Import Examples ,会弹出下图所示的导入示例界面,关于 GPIO 有两个示
例,如下图所示:

         xgpiops_intr_example.c 包含有关如何直接使用 XGpiops 驱动程序的示例。此示例显示了中断模式下驱动程序的用法,并使用 GPIO 的中断功能检测按钮事件,根据输入控制 LED 输出。xgpiops_polled_example.c 同样包含有关如何直接使用 XGpiops 驱动程序的示例。此示例提供了用于读取/写入各个引脚的 API 的用法。从上面的介绍中,我们因为本实验暂未使用到中断,所以应该选择 xgpiops_polled_example 示例。选择好示例后,点击“OK”按钮。

        (5)在 Project Explorer 中,新增了 gpio_mio_bsp_xgpiops_polled_example_1 目录,我们打开其 src 目录下的 xgpiops_polled_example.c 文件。

        xgpiops_polled_example.c 文件有四个函数,其中 GpioInputExample 函数由于我们本实验只用 MIO 输出所以未用到。该文件代码虽然是为特定开发板使用的,不过我们稍作修改也可以拿来使用。我们看到有一 LED 接到 PS MIO0 ,所以当我们修改该文件第 172 行的 Output_Pin 0 时,保存该文件,然后编译,编译完成后下载到领航者开发板会看到核心板上的 LED2 灯闪烁。

六、IIC设计

        下面为LT8619C IIC的读写测试代码

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "xil_types.h"
  5. #include "xil_cache.h"
  6. #include "xparameters.h"
  7. //#include "xgpio.h"
  8. #include "xaxivdma.h"
  9. #include "xaxivdma_i.h"
  10. //#include "display_ctrl/display_ctrl.h"
  11. #include "vdma_api/vdma_api.h"
  12. //#include "xv_tpg.h"
  13. #include "xcsi2txss.h"
  14. //#include "xcsiss.h"
  15. #include "xgpiops.h"
  16. #include "xtime_l.h"
  17. //#include "xvtc.h"
  18. //#include "xvidc.h"
  19. //#include "xvprocss.h"
  20. //#include "xrgb2ycrcb.h"
  21. //#include "xiicps.h"
  22. #include "LT8619C.h"
  23. #include "xiicps.h"
  24. //宏定义
  25. #define IIC_SLAVE_ADDR 0x55
  26. //#define IIC_SCLK_RATE 400000
  27. #define TEST_BUFFER_SIZE 132
  28. #define FRAME_BUFFER_NUM 3 //帧缓存个数
  29. #define BYTES_PIXEL 3 //像素字节数,RGB8883个字节
  30. //#define DYNCLK_BASEADDR XPAR_AXI_DYNCLK_0_BASEADDR //动态时钟基地址
  31. #define VDMA_ID XPAR_AXIVDMA_0_DEVICE_ID //VDMA器件ID
  32. //#define DISP_VTC_ID XPAR_VTC_0_DEVICE_ID //VTC器件ID
  33. //#define AXI_GPIO_0_ID XPAR_AXI_GPIO_0_DEVICE_ID //PL端 AXI GPIO 0(lcd_id)器件ID
  34. //#define AXI_GPIO_0_CHANEL 1 //PL按键使用AXI GPIO(lcd_id)通道1
  35. #define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
  36. #define XRGB_DEVICE_ID XPAR_RGB2YCRCB_0_DEVICE_ID
  37. //XGpioPs InstancePtr;
  38. //XGpioPs* XGInstancePtr = &InstancePtr;
  39. //函数声明
  40. //void colorbar(u8 *frame, u32 width, u32 height, u32 stride);
  41. //全局变量
  42. XAxiVdma vdma;
  43. //XGpio Gpio; /* The Instance of the GPIO Driver */
  44. //DisplayCtrl dispCtrl;
  45. //XGpio axi_gpio_inst; //PL端 AXI GPIO 驱动实例
  46. //VideoMode vd_mode;
  47. //frame buffer的起始地址
  48. unsigned int const frame_buffer_addr = (XPAR_PS7_DDR_0_S_AXI_BASEADDR+0x1000000);
  49. unsigned int lcd_id=0; //LCD ID
  50. XCsi2TxSs csitx_inst;
  51. XIicPs Iic; /**< Instance of the IIC Device */
  52. //XCsiSs csirx_inst;
  53. int Status;
  54. u32 volatile *gpio_hlsIpReset;
  55. u32 volatile *gpio_videoLockMonitor;
  56. XGpioPs_Config * XGpio_Cif;
  57. char * FUNCTION = "[XGpiops_Init]";
  58. XCsi2TxSs_Config *mipiTxConfigPtr;
  59. //XCsiSs_Config *mipiRxConfigPtr;
  60. int driverInit();
  61. int Rgb2YCrCb_Update_Example(u16 DeviceId);
  62. int IicPsMasterPolledExample(u16 DeviceId);
  63. /*
  64. * The following buffers are used in this example to send and receive data
  65. * with the IIC.
  66. */
  67. u8 SendBuffer[TEST_BUFFER_SIZE]; /**< Buffer for Transmitting Data */
  68. u8 RecvBuffer[TEST_BUFFER_SIZE]; /**< Buffer for Receiving Data */
  69. int main(void)
  70. {
  71. driverInit();
  72. int Status=0;
  73. XIicPs_Config *Config;
  74. //***********************************************************************************
  75. //mipi tx
  76. XCsi2TxSs_ReportCoreInfo(&csitx_inst);
  77. XCsi2TxSs_Reset(&csitx_inst);
  78. XCsi2TxSs_SetClkMode(&csitx_inst, 1); //non-continuous clock mode
  79. usleep(300000);
  80. XCsi2TxSs_Activate(&csitx_inst, XCSI2TX_ENABLE);
  81. //***********************************************************************************
  82. //配置VDMA
  83. run_vdma_frame_buffer(&vdma, VDMA_ID, 1280, 1024,frame_buffer_addr,0, 0,BOTH);
  84. // usleep(300000);
  85. //*********************************************************************************
  86. LT8619C_intial();
  87. //*********************************************************************************
  88. Config = XIicPs_LookupConfig(IIC_DEVICE_ID);
  89. if (NULL == Config) {
  90. return XST_FAILURE;
  91. }
  92. Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
  93. if (Status != XST_SUCCESS) {
  94. return XST_FAILURE;
  95. }
  96. /*
  97. * Perform a self-test to ensure that the hardware was built correctly.
  98. */
  99. Status = XIicPs_SelfTest(&Iic);
  100. if (Status != XST_SUCCESS) {
  101. return XST_FAILURE;
  102. }
  103. Status = XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
  104. while(1)
  105. {
  106. SendBuffer[0]=0x60;
  107. SendBuffer[1]=0x00;
  108. Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1);
  109. Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer,1, 0x64>>1);
  110. SendBuffer[0]=0x60;
  111. SendBuffer[1]=0x01;
  112. Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1);
  113. Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer+1,1, 0x64>>1);
  114. SendBuffer[0]=0x60;
  115. SendBuffer[1]=0x02;
  116. Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1);
  117. Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer+2,1, 0x64>>1);
  118. SendBuffer[0]=0x60;
  119. SendBuffer[1]=0x05;
  120. SendBuffer[2]=0x65;
  121. Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,3, 0x64>>1);
  122. usleep(1);
  123. Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1);
  124. Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer+3,1, 0x64>>1);
  125. SendBuffer[0]=0x60;
  126. SendBuffer[1]=0x07;
  127. SendBuffer[2]=0x84;
  128. Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,3, 0x64>>1);
  129. usleep(1);
  130. Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1);
  131. Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer+4,1, 0x64>>1);
  132. }
  133. /*
  134. while(1)
  135. {
  136. usleep(300000);
  137. XGpioPs_WritePin(&InstancePtr,7,1);
  138. usleep(300000);
  139. XGpioPs_WritePin(&InstancePtr,7,0);
  140. }
  141. */
  142. return 0;
  143. }
  144. int driverInit()
  145. {
  146. int status;
  147. //***********************************************************************************
  148. //GPIO
  149. XGpio_Cif = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
  150. status = XGpioPs_CfgInitialize(&InstancePtr,XGpio_Cif,XGpio_Cif->BaseAddr);
  151. if(status != 0) {
  152. xil_printf("%s XGpioPs_CfgInitialize error status:%d \n\r",FUNCTION,status);
  153. return -1;
  154. }
  155. //set MIO 0 as output & set MIO 13 as output
  156. XGpioPs_SetDirectionPin(&InstancePtr,7,1);
  157. XGpioPs_SetDirectionPin(&InstancePtr,10,1);
  158. //Enable
  159. XGpioPs_SetOutputEnablePin(&InstancePtr,7,1);
  160. XGpioPs_SetOutputEnablePin(&InstancePtr,10,1);
  161. //***********************************************************************************
  162. //mipi tx
  163. mipiTxConfigPtr = XCsi2TxSs_LookupConfig(XPAR_CSI2TXSS_0_DEVICE_ID);
  164. if (!mipiTxConfigPtr) {
  165. return XST_FAILURE;
  166. }
  167. status=XCsi2TxSs_CfgInitialize(&csitx_inst, mipiTxConfigPtr,mipiTxConfigPtr->BaseAddr);
  168. if (status != XST_SUCCESS) {
  169. xil_printf("MIPI CSI TX SS config initialization failed.\n\r");
  170. return XST_FAILURE;
  171. }
  172. //***********************************************************************************
  173. //lt8619C
  174. LT8619_Config = XIicPs_LookupConfig(IIC_DEVICE_ID);
  175. if (NULL == LT8619_Config) {
  176. return XST_FAILURE;
  177. }
  178. status = XIicPs_CfgInitialize(&Iic, LT8619_Config, LT8619_Config->BaseAddress);
  179. if (status != XST_SUCCESS) {
  180. return XST_FAILURE;
  181. }
  182. status = XIicPs_SelfTest(&Iic);
  183. if (status != XST_SUCCESS) {
  184. return XST_FAILURE;
  185. }
  186. XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
  187. }
  188. int IicPsMasterPolledExample(u16 DeviceId)
  189. {
  190. int Status;
  191. XIicPs_Config *Config;
  192. int Index;
  193. /*
  194. * Initialize the IIC driver so that it's ready to use
  195. * Look up the configuration in the config table,
  196. * then initialize it.
  197. */
  198. Config = XIicPs_LookupConfig(DeviceId);
  199. if (NULL == Config) {
  200. return XST_FAILURE;
  201. }
  202. Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
  203. if (Status != XST_SUCCESS) {
  204. return XST_FAILURE;
  205. }
  206. /*
  207. * Perform a self-test to ensure that the hardware was built correctly.
  208. */
  209. Status = XIicPs_SelfTest(&Iic);
  210. if (Status != XST_SUCCESS) {
  211. return XST_FAILURE;
  212. }
  213. /*
  214. * Set the IIC serial clock rate.
  215. */
  216. XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
  217. /*
  218. * Initialize the send buffer bytes with a pattern to send and the
  219. * the receive buffer bytes to zero to allow the receive data to be
  220. * verified.
  221. */
  222. for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
  223. SendBuffer[Index] = (Index % TEST_BUFFER_SIZE);
  224. RecvBuffer[Index] = 0;
  225. }
  226. /*
  227. * Send the buffer using the IIC and ignore the number of bytes sent
  228. * as the return value since we are using it in interrupt mode.
  229. */
  230. Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,
  231. TEST_BUFFER_SIZE, IIC_SLAVE_ADDR);
  232. if (Status != XST_SUCCESS) {
  233. return XST_FAILURE;
  234. }
  235. /*
  236. * Wait until bus is idle to start another transfer.
  237. */
  238. while (XIicPs_BusIsBusy(&Iic)) {
  239. /* NOP */
  240. }
  241. Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer,
  242. TEST_BUFFER_SIZE, IIC_SLAVE_ADDR);
  243. if (Status != XST_SUCCESS) {
  244. return XST_FAILURE;
  245. }
  246. /*
  247. * Verify received data is correct.
  248. */
  249. for(Index = 0; Index < TEST_BUFFER_SIZE; Index ++) {
  250. /* Aardvark as slave can only set 64 bytes for output */
  251. if (RecvBuffer[Index] != Index % 64) {
  252. return XST_FAILURE;
  253. }
  254. }
  255. return XST_SUCCESS;
  256. }

         用逻辑分析仪观测信号:

SendBuffer[0]=0x60;

SendBuffer[1]=0x05;

SendBuffer[2]=0x35;

Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,3, 0x64>>1);//写操作

 Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1); //读操作

Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer+3,1, 0x64>>1); //读操作

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/431422
推荐阅读
相关标签
  

闽ICP备14008679号