创建硬件工程,很简单,PS接出两个EMIO和一个74.25M时钟
管脚约束
# ADV7511 I2C_SCL
set_property PACKAGE_PIN AA18 [get_ports {gpio_0_tri_io[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[0]}]
# ADV7511 I2C_SDA
set_property PACKAGE_PIN Y16 [get_ports {gpio_0_tri_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[1]}]
# ADV7511 HDMI_CLK
set_property PACKAGE_PIN W18 [get_ports {FCLK_CLK1}]
set_property IOSTANDARD LVCMOS33 [get_ports {FCLK_CLK1}]
导出 Hardware,启动SDK,新建一个应用,添加以下代码
EMIO_init.c
#include "EMIO_init.h"
static XGpioPs psGpioInstancePtr;
int EMIO_I2C_init(void)
{
XGpioPs_Config* GpioConfigPtr;
int xStatus;
GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
if(GpioConfigPtr == NULL)
return XST_FAILURE;
xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr,GpioConfigPtr->BaseAddr);
if(XST_SUCCESS != xStatus)
print("EMIO INIT FAILED \n\r");
XGpioPs_SetDirectionPin(&psGpioInstancePtr, SIOC_PIN,DIRECTION_OUTPUT);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, SIOD_PIN,DIRECTION_OUTPUT);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, SIOC_PIN,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, SIOD_PIN,1);
return xStatus;
}
void CLOCK_HIGH(void)
{
XGpioPs_WritePin(&psGpioInstancePtr,SIOC_PIN, 1);
}
void CLOCK_LOW(void)
{
XGpioPs_WritePin(&psGpioInstancePtr,SIOC_PIN, 0);
}
int GET_DATA(void)
{
return XGpioPs_ReadPin(&psGpioInstancePtr,SIOD_PIN);
}
void DATA_INPUT(void)
{
XGpioPs_SetDirectionPin(&psGpioInstancePtr, SIOD_PIN,DIRECTION_INPUT);//
}
void DATA_OUTPUT(void)
{
XGpioPs_SetDirectionPin(&psGpioInstancePtr, SIOD_PIN,DIRECTION_OUTPUT);//
}
void DATA_HIGH(void)
{
XGpioPs_WritePin(&psGpioInstancePtr,SIOD_PIN, 1);
}
void DATA_LOW(void)
{
XGpioPs_WritePin(&psGpioInstancePtr,SIOD_PIN,0);
}
EMIO_init.h
#ifndef EMIO_INIT_H_
#define EMIO_INIT_H_
#include "xgpiops.h"
int EMIO_I2C_init(void);
#define SIOC_PIN 54
#define SIOD_PIN 55
#define RESET_PIN 56
#define DIRECTION_INPUT 0
#define DIRECTION_OUTPUT 1
void CLOCK_HIGH(void);
void CLOCK_LOW(void);
void DATA_HIGH(void);
void DATA_LOW(void);
void DATA_INPUT(void);
void DATA_OUTPUT(void);
int GET_DATA(void);
#endif /* EMIO_INIT_H_ */
I2C_ctrl.c
#include "sleep.h"
#include "EMIO_init.h"
#define I2C_DELAY usleep(10)
void I2C_start(void)
{
CLOCK_HIGH();
DATA_HIGH();
I2C_DELAY;
DATA_LOW();
I2C_DELAY;
CLOCK_LOW();
I2C_DELAY;
}
void I2C_end(void)
{
DATA_LOW();
I2C_DELAY;
CLOCK_HIGH();
I2C_DELAY;
DATA_HIGH();
I2C_DELAY;
}
int I2C_sendbyte( unsigned char value )
{
unsigned char tmp = value;
unsigned char i=0,ack;
for(i=0; i<8; i++)
{
if(tmp & 0x80 )
DATA_HIGH();
else
DATA_LOW();
I2C_DELAY;
CLOCK_HIGH();
I2C_DELAY;
CLOCK_LOW();
I2C_DELAY;
tmp<<=1;
}
DATA_HIGH();
DATA_INPUT();
I2C_DELAY;
CLOCK_HIGH();
ack = GET_DATA();
I2C_DELAY;
CLOCK_LOW();
I2C_DELAY;
DATA_OUTPUT();
if(ack==1)
{
return -1;
}
return 0;
}
unsigned char I2C_readbyte( unsigned char addr)
{
unsigned char i=0,data=0;
DATA_HIGH();
DATA_INPUT();
for(i=0; i<8; i++)
{
CLOCK_HIGH();
I2C_DELAY;
data <<= 1;
if(GET_DATA())
data |= 1;
I2C_DELAY;
CLOCK_LOW();
I2C_DELAY;
}
DATA_OUTPUT();
DATA_HIGH();
I2C_DELAY;
CLOCK_HIGH();
I2C_DELAY;
CLOCK_LOW();
I2C_DELAY;
DATA_HIGH();
return data;
}
int I2C_readdata(unsigned char id, unsigned char addr, unsigned char *value)
{
// 两相写
I2C_start();
if(I2C_sendbyte(id<<1) != 0)
{
goto error;
}
if(I2C_sendbyte(addr) != 0)
{
goto error;
}
// 两相读
I2C_start();
if(I2C_sendbyte((id<<1)|0x1) != 0)
{
goto error;
}
*value = I2C_readbyte(addr);
I2C_end();
return 0;
error:
I2C_end();
return -1;
}
int I2C_senddata(unsigned char id, unsigned char addr,unsigned char value)
{
I2C_start();
if(I2C_sendbyte(id<<1) != 0)
{
goto error;
}
if(I2C_sendbyte(addr) != 0)
{
goto error;
}
if(I2C_sendbyte(value)!= 0)
{
goto error;
}
I2C_end();
return 0;
error:
I2C_end();
return -1;
}
#ifndef I2C_CTRL_H_
#define I2C_CTRL_H_
void I2C_start(void);
void I2C_end(void);
//void I2C_sendbyte( unsigned char value );
int I2C_senddata(unsigned char id, unsigned char subaddr,unsigned char value);
int I2C_readdata(unsigned char id, unsigned char addr, unsigned char *value);
#endif /* I2C_CTRL_H_ */
helloworld.c
#define ADV7511_I2C_ADDR (0x72 >> 1)
int main()
{
unsigned char data;
int Status;
init_platform();
EMIO_I2C_init();
usleep(500*1000);
while(1)
{
//读取PID
data = 0;
I2C_senddata(ADV7511_I2C_ADDR,0x41,0x40);
sleep(1);
if(I2C_readdata(ADV7511_I2C_ADDR,0x41,&data) != 0)
{
print("error\n\r");
}
else
{
if(data != 0x40)
print("error\n\r");
}
data = 0;
if(I2C_readdata(ADV7511_I2C_ADDR,0xf5,&data) != 0)
{
print("error\n\r");
}
else
{
if(data != 0x75)
print("error\n\r");
}
data = 0;
if(I2C_readdata(ADV7511_I2C_ADDR,0xf6,&data) != 0)
{
print("error\n\r");
}
else
{
if(data != 0x11)
print("error\n\r");
}
sleep(2);
}
cleanup_platform();
return 0;
}