新手入门
- 积分
- 3
- 金钱
- 3
- 注册时间
- 2021-3-30
- 在线时间
- 0 小时
|
1金钱
使用EMIO模拟IIC写入和读取时从机无ACK,代码附后,有无大佬指点一下
//模拟IIC
void I2C_Delay(void)
{
usleep(1);
}
void I2C_Start(void)
{
SET_I2C_SDA_HIGH;
I2C_Delay();
SET_I2C_SCL_HIGH;
I2C_Delay();
SET_I2C_SDA_LOW;
I2C_Delay();
SET_I2C_SCL_LOW;
I2C_Delay();
}
void I2C_Stop(void)
{
SET_I2C_SDA_LOW;
I2C_Delay();
SET_I2C_SCL_HIGH;
I2C_Delay();
SET_I2C_SDA_HIGH;
I2C_Delay();
}
void I2C_Ack(void)
{
SET_I2C_SDA_LOW;
I2C_Delay();
SET_I2C_SCL_HIGH;
I2C_Delay();
SET_I2C_SCL_LOW;
I2C_Delay();
SET_I2C_SDA_HIGH;
}
void I2C_NAck(void)
{
SET_I2C_SDA_HIGH;
I2C_Delay();
SET_I2C_SCL_HIGH;
I2C_Delay();
SET_I2C_SCL_LOW;
I2C_Delay();
}
uint8_t I2C_GetAck(void)
{
int8_t ret;
I2C_Delay();
SET_I2C_SDA_HIGH;
I2C_Delay();
SET_I2C_SCL_HIGH;
I2C_Delay();
if(READ_I2C_SDA == 0)
{
ret=ACK;
printf("ACK \n");
}
else
{
ret=NACK;
}
SET_I2C_SCL_LOW;
I2C_Delay();
return ret;
}
void I2C_WriteByteData(uint8_t data)
{
uint8_t i;
uint8_t tmp;
for(i=0;i<8;i++)
{
if(data&0x80)
{
SET_I2C_SDA_HIGH;
}
else
{
SET_I2C_SDA_LOW;
}
data=data<<1;
I2C_Delay();
SET_I2C_SCL_HIGH;
I2C_Delay();
SET_I2C_SCL_LOW;//add by billy
//I2C_Delay();
}
I2C_Delay();
}
uint8_t I2C_ReadByteData(void)
{
uint8_t i,data;
data=0x00;
SET_I2C_SDA_HIGH;
for(i=0;i<8;i++)
{
data=data<<1;
SET_I2C_SCL_HIGH;
I2C_Delay();
if(READ_I2C_SDA==0x01)
{
data++;
}
SET_I2C_SCL_LOW;
I2C_Delay();
}
return data;
}
int32_t I2C_WriteBuffer (uint8_t SlaveAddr ,uint32_t MemoAddr,uint8_t ByteofMemoAddr ,uint8_t* data ,uint8_t len)
{
int8_t Data[5],i;
//judge the length of address and data
if(ByteofMemoAddr>4||ByteofMemoAddr<0)
{
return I2C_AddrLen_Err;
}
else
{
switch(ByteofMemoAddr)
{
case 0:
Data[0]=SlaveAddr<<1;
break;
case 1:
Data[0]=SlaveAddr<<1;
Data[1]=(uint8_t)(MemoAddr);
break;
case 2:
Data[0]=SlaveAddr<<1;
Data[1]=(uint8_t)(MemoAddr>>8);
Data[2]=(uint8_t)(MemoAddr);
break;
case 3:
Data[0]=SlaveAddr<<1;
Data[1]=(uint8_t)(MemoAddr>>16);
Data[2]=(uint8_t)(MemoAddr>>8);
Data[3]=(uint8_t)(MemoAddr);
break;
case 4:
Data[0]=SlaveAddr<<1;
Data[1]=(uint8_t)(MemoAddr>>24);
Data[2]=(uint8_t)(MemoAddr>>16);
Data[3]=(uint8_t)(MemoAddr>>8);
Data[4]=(uint8_t)(MemoAddr);
break;
default:
break;
}
}
if(len<=0)
{
//printf("Present Line: %d\n", __LINE__);
return I2C_DataLen_Err;
}
I2C_Start();
for(i=0;i<(ByteofMemoAddr+1);i++)
{
I2C_WriteByteData(Data[i]);
if(I2C_GetAck()==NACK)
{
//printf("Present Line: %d\n", __LINE__);
//printf("I2C Write Data Get NACK\n");
I2C_Stop();
break;
}
}
if(i!=(ByteofMemoAddr+1))
{
return I2C_WriteData_Err;
}
//send data
for(i=0;i<len;i++)
{
I2C_WriteByteData(data[i]);
if(I2C_GetAck()==NACK)
{
//printf("Present Line: %d\n", __LINE__);
//printf("I2C Write Data Get NACK\n");
I2C_Stop();
break;
}
}
if(i!=len)
{
return I2C_WriteData_Err;
}
I2C_Stop();
return 0;
//return value
}
int32_t I2C_ReadBuffer (uint8_t SlaveAddr ,uint32_t MemoAddr,uint8_t ByteofMemoAddr ,uint8_t* data ,uint8_t len)
{
int8_t Data[5],i;
//judge the length of address and data
if(ByteofMemoAddr>4||ByteofMemoAddr<0)
{
return I2C_AddrLen_Err;
}
else
{
switch(ByteofMemoAddr)
{
case 0:
Data[0]=SlaveAddr<<1;
break;
case 1:
Data[0]=SlaveAddr<<1;
Data[1]=(uint8_t)(MemoAddr);
break;
case 2:
Data[0]=SlaveAddr<<1;
Data[1]=(uint8_t)(MemoAddr>>8);
Data[2]=(uint8_t)(MemoAddr);
break;
case 3:
Data[0]=SlaveAddr<<1;
Data[1]=(uint8_t)(MemoAddr>>16);
Data[2]=(uint8_t)(MemoAddr>>8);
Data[3]=(uint8_t)(MemoAddr);
break;
case 4:
Data[0]=SlaveAddr<<1;
Data[1]=(uint8_t)(MemoAddr>>24);
Data[2]=(uint8_t)(MemoAddr>>16);
Data[3]=(uint8_t)(MemoAddr>>8);
Data[4]=(uint8_t)(MemoAddr);
break;
default:
break;
}
}
if(len<=0)
{
return I2C_DataLen_Err;
}
//device has slave address
if(ByteofMemoAddr!=0x00)
{
I2C_Start();
for(i=0;i<(ByteofMemoAddr+1);i++)
{
I2C_WriteByteData(Data[i]);
if(I2C_GetAck()==NACK)
{
I2C_Stop();
break;
}
}
if(i!=(ByteofMemoAddr+1))
{
return I2C_WriteData_Err;
}
}
//resend Address for reading
I2C_Start();
Data[0]=Data[0]+1;
I2C_WriteByteData(Data[0]);
if(I2C_GetAck())
{
I2C_Stop();
return I2C_WriteData_Err;
}
//send data
for(i=0;i<len;i++)
{
data[i]=I2C_ReadByteData();
if(i==(len-1))
{
I2C_NAck();
break;
}
I2C_Ack();
}
I2C_Stop();
return 0;
}
.h文件
#ifndef SRC_IIC_H_
#define SRC_IIC_H_
#include "stdio.h"
#include "xiicps.h"
#include "xparameters.h"
#include "gpio.h"
#include "sleep.h"
#define I2C_StartSingle_Err -1
#define I2C_SendAddr_Err -2
#define I2C_WriteData_Err -3
#define I2C_ReadData_Err -4
#define I2C_Busy_Err -5
#define I2C_DataLen_Err -27// Add for compatible with software I2C protocal
#define I2C_AddrLen_Err -28// Add for compatible with software I2C protocal
#define IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID
#define IIC_SCLK_RATE 100000 //IIC速度
#define SET_I2C_SDA_HIGH GPIO_HIGH(EMIO54_IIC_SDA)
#define SET_I2C_SDA_LOW GPIO_LOW(EMIO54_IIC_SDA)
#define SET_I2C_SCL_HIGH GPIO_HIGH(EMIO55_IIC_SCL)
#define SET_I2C_SCL_LOW GPIO_LOW(EMIO55_IIC_SCL)
#define READ_I2C_SDA GET_DATA(EMIO54_IIC_SDA)
#define ACK 0x00
#define NACK 0x01
void I2C_Delay(void);
void I2C_Start(void);
void I2C_Stop(void);
void I2C_Ack(void);
void I2C_NAck(void);
uint8_t I2C_GetAck(void);
void I2C_WriteByteData(uint8_t data);
uint8_t I2C_ReadByteData(void);
//SlaveAddr:器件地址,MemoAddr:
int32_t I2C_WriteBuffer (uint8_t SlaveAddr ,uint32_t MemoAddr,uint8_t ByteofMemoAddr ,uint8_t* data ,uint8_t len);
int32_t I2C_ReadBuffer (uint8_t SlaveAddr ,uint32_t MemoAddr,uint8_t ByteofMemoAddr ,uint8_t* data ,uint8_t len);
//int IIC_initialization(); //IIC初始化
//int IIC_write(u8 *MsgPtr, s32 ByteCount, u16 SlaveAddr); //IIC写数据
//int IIC_read(u8 *MsgPtr, s32 ByteCount, u16 SlaveAddr); //IIC读数据
#endif
|
|