ZYNQ系列---I2C控制器使用教程

免责声明

本文所提供的信息和内容仅供参考。作者对本文内容的准确性、完整性、及时性或适用性不作任何明示或暗示的保证。在任何情况下,作者不对因使用本文内容而导致的任何直接或间接损失承担责任,包括但不限于数据丢失、业务中断或其他经济损失。

读者在使用本文信息时,应自行验证其准确性和适用性,并对其使用结果负责。本文内容不构成专业技术咨询或建议,具体的技术实现和应用应根据实际情况和需要进行详细分析和验证。

本文所涉及的任何商标、版权或其他知识产权均属于其各自的所有者。若本文中引用了第三方的资料或信息,引用仅为学术交流目的,不构成对第三方内容的认可或保证。

若有任何疑问或需进一步信息,请联系本文作者或相关专业人士。


前言

I2C是FPGA入门总线之一,相信大家已经编写过无数遍了,本篇文章将讲述ZYNQ系列---I2C控制器使用方法。


一、搭建SOC系统工程

1.调出ZYNQ核;

2.检查DDR配置是否正确;

3.打开I2C控制器,并选择EMIO,通过EMIO可以路由到PL端的引脚上。

二、搭建 Vitis-sdk 工程

1.创建 SDK Platform 工程

创建成功后,可以在驱动中看见I2C


2.了解I2C的读写函数

本文的用途为配置从设备的寄存器。
* @param    InstancePtr is a pointer to the XIicPs instance.
* @param    MsgPtr is the pointer to the send buffer.
* @param    ByteCount is the number of bytes to be sent.
* @param    SlaveAddr is the address of the slave we are sending to.
****************************************************************************/

I2C的写数据函数,MsgPtr指向数据buffer;ByteCount表示要写入的数据字节个数;SlaveAddr表示从设备的设备地址。
XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount, u16 SlaveAddr);

   那怎么往一个寄存器里写一个数据呢?

      我们可以把寄存器号也当成数据,假设从设备地址0xa1,待写入的寄存器号为0x3033,待写入的数据为0x01,

即:

   u8 RegAddrBytes[3];

    RegAddrBytes[0] = 0x30;
    RegAddrBytes[1] = 0x33;
    RegAddrBytes[2] = 0x01;

XIicPs_MasterSendPolled(XIicPs *InstancePtr, RegAddrBytes, 3, 0xa1);


* @param    InstancePtr is a pointer to the XIicPs instance.
* @param    MsgPtr is the pointer to the receive buffer.
* @param    ByteCount is the number of bytes to be received.
* @param    SlaveAddr is the address of the slave we are receiving from.
****************************************************************************

I2C的读数据函数,MsgPtr指向数据buffer;ByteCount表示要接收的数据字节个数;SlaveAddr表示从设备的设备地址。
XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr,s32 ByteCount, u16 SlaveAddr)

这个读函数与写函数类似,但要注意它是从当前的寄存器地址读取数据,因此我们在读取想要的寄存器数据时,需要先把待读取的寄存器号用写函数写入。

3.完整的程序

/******************************************************************************
*
* Copyright (C) 2009 - 2014 Xilinx, Inc.  All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/

/*
 * helloworld.c: simple test application
 *
 * This application configures UART 16550 to baud rate 9600.
 * PS7 UART (Zynq) is not initialized by this application, since
 * bootrom/bsp configures it to baud rate 115200
 *
 * ------------------------------------------------
 * | UART TYPE   BAUD RATE                        |
 * ------------------------------------------------
 *   uartns550   9600
 *   uartlite    Configurable only in HW design
 *   ps7_uart    115200 (configured by bootrom/bsp)
 */

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
//下面两个头文件不能缺少
#include "xiicps.h"
#include "xparameters.h"

#define IIC_DEVICE_ID	XPAR_XIICPS_0_DEVICE_ID
//IIC 的速率 300K
#define IIC_SCLK_RATE	300000

int main()
{
	XIicPs Iic;
	XIicPs_Config *Config;

        s32 Status;
        // 1.查找IIC设备
        Config = XIicPs_LookupConfig(IIC_DEVICE_ID);
        if (Config == NULL) {
        	print("IIC_DEVICE_ID ERROR\n\r");
            return XST_FAILURE;
        }
        // 2.初始化
        Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
        if (Status != XST_SUCCESS) {
        	print("initial IIC failed \n\r");
            return XST_FAILURE;
        }

        //设置IIC速率
        Status = XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
        if(Status != XST_SUCCESS)
        	{
        		print("set IIC clock rate failed \n\r");
        		return XST_FAILURE;
        	}

        ///写入
        u8  RegAddrBytes[3];
            RegAddrBytes[0] = 0x30;
            RegAddrBytes[1] = 0x05;
            RegAddrBytes[2] = 0x01;
        XIicPs_MasterSendPolled(&Iic, RegAddrBytes,3,0x1A);

        ///读取
        //
        u8 receivedData;
        u8  RegAddr[2];
            RegAddr[0] = 0x30;
            RegAddr[1] = 0x05;
            XIicPs_MasterSendPolled(&Iic, RegAddr,2,0x1A);
            XIicPs_MasterRecvPolled(&Iic, &receivedData, 1, 0x1A);

    return 0;
}

4.调试验证

读到的数据与写入的数据一致,因此I2C配置没有任何问题。


总结

I2C控制器使用起来简单方便,底层驱动已经很完善了,我们只需要了解对应的函数就可以完成I2C的读写,是不是又学会一个偷懒的技巧,最后强调一下,I2C的设备ID和ZYNQ的DDR配置不要搞错。

  • 34
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值