新手入门 
 
	- 积分
 - 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 
 
 
 
 |   
 
 
 
 
 
 |