打印
[技术问答]

AC7811 IO口开漏输出如何配置

[复制链接]
529|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Cjy_JDxy|  楼主 | 2019-10-18 19:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
Cjy_JDxy|  楼主 | 2019-10-22 19:38 | 只看该作者
没人懂吗?我想搞模拟I2C

使用特权

评论回复
板凳
TechHolder| | 2019-10-23 13:22 | 只看该作者
Cjy_JDxy 发表于 2019-10-22 19:38
没人懂吗?我想搞模拟I2C

直接将pin设置为GPIO,可模拟I2C功能。

使用特权

评论回复
地板
AutochipsMCU| | 2019-10-23 13:32 | 只看该作者
本帖最后由 AutochipsMCU 于 2019-10-23 13:35 编辑
Cjy_JDxy 发表于 2019-10-22 19:38
没人懂吗?我想搞模拟I2C

贴一个模拟I2C的配置,供您参考://EEPROM
#define EEPROM_WP                   GPIO_PC11
#define EEPROM_SCL                  GPIO_PC12
#define EEPROM_SDA                  GPIO_PC13
//  E2PROM操作
#define SET_SDA                GPIO_SetPinBits(EEPROM_SDA)            //SDA = 1
#define CLR_SDA                GPIO_ResetPinBits(EEPROM_SDA)          //SDA = 0
#define SDA_IN          GPIO_GetPinValue(EEPROM_SDA)           //Read SDA
#define SET_SCL                GPIO_SetPinBits(EEPROM_SCL)            //SCL = 1
#define CLR_SCL                GPIO_ResetPinBits(EEPROM_SCL)          //SCL = 0
#define E2P_DIS                GPIO_SetPinBits(EEPROM_WP)             //DIS = 1  (WP)
#define E2P_EN                GPIO_ResetPinBits(EEPROM_WP)           //EN = 0
void I2C_Delay(uint16_t number)
{
        uint16_t j;
        for(j=0;j<number;j++);
}

void DIR_In(void)
{       
    GPIO_SetDir(EEPROM_SDA, 0);//设置SDA引脚为输入
    GPIO_SetPullupEnable(EEPROM_SDA, ENABLE); //上拉使能
}

void DIR_Out(void)
{       
    GPIO_SetDir(EEPROM_SDA, 1);//设置SDA引脚为输出
}

void Start_I2c(void)
{       
    DIR_Out();
        SET_SDA;
        I2C_Delay(400);
        SET_SCL;
        I2C_Delay(400);
        CLR_SDA;
        I2C_Delay(400);
        CLR_SCL;
        I2C_Delay(400);

}

void Stop_I2c(void)
{       
    DIR_Out();
        CLR_SDA;
        I2C_Delay(400);
        SET_SCL;
        I2C_Delay(400);
        SET_SDA;
        I2C_Delay(400);
        CLR_SCL;
        I2C_Delay(400);

}

void WriteAByte(uint16_t data)
{       
    uint16_t i;
          DIR_Out();
          for(i=0;i<8;i++)
          {
            CLR_SCL;
            I2C_Delay(400);
            if ((data>>7)&0x0001)
        {
            SET_SDA;
        }
            else
        {
            CLR_SDA;
        }
            I2C_Delay(400);
            SET_SCL;
            data <<= 1;
            I2C_Delay(400);
          }
           CLR_SCL;
          I2C_Delay(400);
}

uint16_t ReadAByte(void)
{
          uint16_t i,bit=0,data=0;
          DIR_In();                                                     
    CLR_SCL;
          I2C_Delay(400);
          for (i=0; i<8; i++)
          {
            SET_SCL;
            I2C_Delay(400);
            if(SDA_IN)
        {
            bit=1;
        }
            else
        {
            bit=0;
        }
            data = (data << 1) | bit;
            CLR_SCL;
            I2C_Delay(400);
        }
          return (data);
}

uint16_t ReceiveI2CAck(void)
{
          uint16_t i=5000;

           SET_SDA;
          DIR_In();
          SET_SCL;
          I2C_Delay(400);
       
        while (SDA_IN)
          {
            if(!(--i))
            {
            CLR_SCL;
            return(FALSE);
            }
          }
          CLR_SCL;
          I2C_Delay(400);
          return(TRUE);
}


void SendI2CAck(void)
{
          CLR_SCL;
          I2C_Delay(400);
          DIR_Out();
          CLR_SDA;
          SET_SCL;
          I2C_Delay(400);
          CLR_SCL;
          I2C_Delay(400);
}

void SendI2CNAck(void)
{
          CLR_SCL;
          I2C_Delay(400);
          DIR_Out();
          SET_SDA;
          SET_SCL;
          I2C_Delay(400);
          CLR_SCL;
          I2C_Delay(400);
}
/**
*  EEPROM_Config
*
* @param[in] void
*
* @return void
*
* @brief config eeprom pinmux and gpio
*
*/
void EEPROM_Config(void)
{
    GPIO_SetDir(EEPROM_WP, 1);//设置WP引脚为输出
        GPIO_SetDir(EEPROM_SCL, 1);//设置SCL引脚为输出
        GPIO_SetDir(EEPROM_SDA, 1);//设置SDA引脚为输出

}
/**
*  EEPROM_Read
*
* @param[in] address range 0-511(24c08)
*
* @return the value from address.
*
* @brief read eeprom
*
*/
uint16_t EEPROM_Read(uint16_t address)
{
        uint16_t AX;       
       
        if( address >=384 )     // the forth page
        {
         AX = (address - 384) << 1;
         Start_I2c();
         WriteAByte(WriteDeviceDddress);
         if (!ReceiveI2CAck())
         {
             return (FALSE);
         }
         WriteAByte(AX);       
         if (!ReceiveI2CAck())
         {
             return( FALSE );       
         }
         Start_I2c();       
         WriteAByte(ReadDviceDddress);

         if (!ReceiveI2CAck())
         {
             return( FALSE );
         }
         AX = ReadAByte();
         SendI2CAck();
         AX += (ReadAByte()) << 8;
         SendI2CNAck();
         Stop_I2c();
         return (AX);           // 读成功,返回实际数据,否则返回零
    }
        else if( address >=256 )     // the third page
        {
         AX = (address - 256)<<1;
         Start_I2c();
         WriteAByte(WriteDeviceCddress);
         if (!ReceiveI2CAck())
         {
             return( FALSE );       
         }
         WriteAByte(AX);       
         if (!ReceiveI2CAck())
         {
             return( FALSE );       
         }
         Start_I2c();       
         WriteAByte(ReadDviceCddress);
         if(!ReceiveI2CAck())
         {
             return( FALSE );
         }

         AX = ReadAByte();
         SendI2CAck();
         AX += (ReadAByte()) << 8;
         SendI2CNAck();
         Stop_I2c();
         return( AX );           // 读成功,返回实际数据,否则返回零
    }
        else  if( address >=128 )     // the second page
        {
         AX = (address - 128) << 1;
         Start_I2c();
         WriteAByte(WriteDeviceBddress);
         if (!ReceiveI2CAck())
         {
             return( FALSE );       
         }
         WriteAByte(AX);       
         if (!ReceiveI2CAck())
         {
             return( FALSE );       
         }
         Start_I2c();       
         WriteAByte(ReadDviceBddress);

         if (!ReceiveI2CAck())
         {
             return( FALSE );
         }

         AX = ReadAByte();
         SendI2CAck();
         AX += (ReadAByte()) << 8;
         SendI2CNAck();
         Stop_I2c();
         return( AX );           // 读成功,返回实际数据,否则返回零
    }
    else           // the first page
        {
        AX = address << 1;
        Start_I2c();
        WriteAByte(WriteDeviceAddress);
        if (!ReceiveI2CAck())
        {
            return( FALSE );       
        }
        WriteAByte( AX );       
        if (!ReceiveI2CAck())
        {
            return( FALSE );       
        }
        Start_I2c();       
        WriteAByte(ReadDviceAddress);
        if (!ReceiveI2CAck())
        {
            return( FALSE );
        }

        AX = ReadAByte();
        SendI2CAck();
        AX += (ReadAByte()) << 8;
        SendI2CNAck();
        Stop_I2c();
        return( AX );              // 读成功,返回实际数据,否则返回零

    }

}
/**
*  EEPROM_Write
*
* @param[in] address: 0-511(24c08), data: a 16bit value
*
* @return void
*
* @brief write eeprom
*
*/
void EEPROM_Write(uint16_t address, uint16_t data)
{
       
    uint16_t AX;       
       
        E2P_EN;
        if ( address >=384 )     // the forth page
        {
         AX = (address - 384)<<1;
         Start_I2c();
         WriteAByte(WriteDeviceDddress);
         ReceiveI2CAck();
         WriteAByte( AX );
         ReceiveI2CAck();
         WriteAByte(data);
         ReceiveI2CAck();     
         WriteAByte((data)>>8);
         ReceiveI2CAck();      
         Stop_I2c();  
    }
        else if( address >=256 )     // the third page
        {
         AX = (address - 256)<<1;
         Start_I2c();
         WriteAByte(WriteDeviceCddress);
         ReceiveI2CAck();
         WriteAByte( AX );
         ReceiveI2CAck();
         WriteAByte(data);
         ReceiveI2CAck();     
         WriteAByte((data)>>8);
         ReceiveI2CAck();      
         Stop_I2c();  
    }
        else if( address >=128 )     // the second page
        {
         AX = (address - 128)<<1;
         Start_I2c();
         WriteAByte(WriteDeviceBddress);
         ReceiveI2CAck();
         WriteAByte( AX );
         ReceiveI2CAck();
         WriteAByte(data);
         ReceiveI2CAck();     
         WriteAByte((data)>>8);
         ReceiveI2CAck();      
         Stop_I2c();  
    }
        else
        {
         AX = address <<1;
         Start_I2c();
         WriteAByte(WriteDeviceAddress);
         ReceiveI2CAck();
         WriteAByte( AX );
         ReceiveI2CAck();
         WriteAByte(data);
         ReceiveI2CAck();     
         WriteAByte((data)>>8);
         ReceiveI2CAck();      
         Stop_I2c();  
    }
    I2C_Delay(5000);
    I2C_Delay(5000);
        I2C_Delay(5000);
        I2C_Delay(5000);
        I2C_Delay(5000);
    I2C_Delay(5000);
        I2C_Delay(5000);
        I2C_Delay(5000);
        E2P_DIS;
}

uint16_t test[512]  = {0};
/**
*  EEPROM_Test
*
* @param[in] void
*
* @return 0 : ok, 1:ng
*
* @brief test eeprom
*
*/
uint8_t EEPROM_Test(void)
{
    uint16_t i = 0;
    uint16_t read = 0;
    memset(test, 0x00, sizeof(test));
    for (i = 0; i < 512; i++)
    {
        EEPROM_Write(i, i);
        read = EEPROM_Read(i);
        test = read;
    }
    return 0;

}


使用特权

评论回复
5
Cjy_JDxy|  楼主 | 2019-10-23 13:56 | 只看该作者
AutochipsMCU 发表于 2019-10-23 13:32
贴一个模拟I2C的配置,供您参考://EEPROM
#define EEPROM_WP                   GPIO_PC11
#define EEPRO ...

谢谢!我试试

使用特权

评论回复
6
Cjy_JDxy|  楼主 | 2019-10-23 13:58 | 只看该作者
TechHolder 发表于 2019-10-23 13:22
直接将pin设置为GPIO,可模拟I2C功能。

我·试了不行。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:绿水本无忧因风皱面,青山原不老为雪白头。

553

主题

3520

帖子

19

粉丝