OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8932|回复: 1

[XILINX] ZYNQ7020领航者EMIO模拟IIC

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
3
金钱
3
注册时间
2021-3-30
在线时间
0 小时
发表于 2021-3-30 20:40:06 | 显示全部楼层 |阅读模式
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



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

712

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2178
金钱
2178
注册时间
2018-8-27
在线时间
258 小时
发表于 2021-4-9 09:34:43 | 显示全部楼层
参考正点原子的例程  用的也是模拟IIC
森罗万象
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 00:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表