在ZYNQ中打开IIC
在ZYNQ中,已经集成了IIC的外设的控制器,在配置ZYNQ核的时候,只需要打开IIC外设,就能够在SDK通过调用函数库中已经提供好的API就能够对IIC外设进行访问。
生成bit文件后导出硬件描述文件,然后打开SDK。
SDK中进行裸机开发
在system.mss中可以看到使用到的外设,在外设对应的文档中可以找到其对应的API。我只使用IIC的读写功能,主要的函数是发送和接收XIicPs_MasterRecvPolled(),XIicPs_MasterSendPolled();
程序设计
IIC的初始化过程首选需要去通过设备ID查找配置结构体,然后需要根据配置结构体来对设备进行初始化,在初始化的时候,我顺便设置了IIC的时钟的频率。封装了IIC的读写函数,可以在配置的时候,根据配置列表的值直接进行使用就行了。
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xiicps.h"
// IIC device ID
#define IIC_DEV_ID XPAR_PS7_I2C_0_DEVICE_ID
#define IIC_RATE 200000
//7位设备地址
#define SLAVE_ADDR 0x39
static XIicPs IicPs;
static XIicPs_Config * IicPs_Cfg;
//测试配置列表
u8 configList[12][2]={
{0x00,0x00},
{0x01,0x01},
{0x02,0x02},
{0x03,0x03},
{0x04,0x04},
{0x05,0x05},
{0x06,0x06},
{0x07,0x07},
{0x08,0x08},
{0x09,0x09},
{0x0A,0x0A},
{0x0B,0x0B}
};
// 初始化IIC,并设置IIC速率
int initIic()
{
int status;
// 1.查找IIC设备
IicPs_Cfg = XIicPs_LookupConfig(IIC_DEV_ID);
// 2.初始化
status = XIicPs_CfgInitialize(&IicPs, IicPs_Cfg, IicPs_Cfg->BaseAddress);
if(status != XST_SUCCESS)
{
print("initial IIC failed \n");
return XST_FAILURE;
}
//设置IIC速率
status = XIicPs_SetSClk(&IicPs, IIC_RATE);
if(status != XST_SUCCESS)
{
print("set IIC clock rate failed \n");
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************
* function IIC完成单个寄存器的配置
*
* @parameter : XIicPs * iicPs =====> IIC设备结构体
* @parameter : u16 slaveAddr =====> IIC从机设备地址
* @parameter : u8 * Cfg_Ptr ====> 配置寄存器的指针
*
* @return s32 XST_SUCCESS or XST_FAILURE
******************************************************************/
s32 writeReg(XIicPs * iicPs, u16 slaveAddr, u8 * Cfg_Ptr)
{
s32 status ;
//IIC写入数据,从机地址,寄存器地址和写入的数据
status = XIicPs_MasterSendPolled(iicPs, Cfg_Ptr, 2, SLAVE_ADDR );
if (status != XST_SUCCESS)
{
printf("configure register failed! \n");
return XST_FAILURE;
}
//两次IIC写入之间保持一定间隔
usleep(8000);
return status;
}
/******************************************************************
* function IIC从寄存器中读出数据
*
* @parameter : XIicPs * iicPs =====> IIC设备结构体
* @parameter : u16 slaveAddr =====> IIC从机设备地址
* @parameter : u8 * Cfg_Ptr ====> 配置寄存器的指针
*
* @return u8 registerData =====> 从寄存器中读出的数据
******************************************************************/
u8 readReg(XIicPs * iicPs, u16 slaveAddr, u8 * regAddr)
{
s32 status ;
u8 registerData;
//发送设备地址,寄存器地址
status = XIicPs_MasterSendPolled(iicPs, regAddr, 1, SLAVE_ADDR );
if (status != XST_SUCCESS)
{
printf("configure register failed! \n");
return XST_FAILURE;
}
//从寄存器中读出数据
status = XIicPs_MasterRecvPolled(iicPs, ®isterData, 1, SLAVE_ADDR);
if (status != XST_SUCCESS)
{
printf("configure register failed! \n");
return XST_FAILURE;
}
return registerData;
}
int main()
{
init_platform();
u8 dataBuf[31];
//初始化IIC
int status = initIic();
if(status != XST_SUCCESS)
{
printf("initialize IIC failed \n");
return XST_FAILURE;
}
//依次写入配置列表
for(int i=1; i < 12; i++ )
{
writeReg(&IicPs, SLAVE_ADDR, configList[i]);
}
//将值从寄存器中读出
for(int i = 0; i < 12; i++)
{
dataBuf[i] = readReg(&IicPs, SLAVE_ADDR, &configList[i][0]);
printf("dataBuf[%d] = %x \n",i , dataBuf[i]);
}
print("Hello World\n\r");
cleanup_platform();
return 0;
}
测试结果: