打印
[PIC®/AVR®/dsPIC®产品]

I2C的IO的标准模拟时序

[复制链接]
984|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mintspring|  楼主 | 2023-11-16 09:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
i2c.h
#ifndef __FILE_I2CBASIC_H
#define __FILE_I2CBASIC_H

// Send the I2C start command to the target device
void I2CSendStart( void );
// Send the I2C stop command to the target device
void I2CSendStop( void );
// Send a clock pulse and check SDA for an ACK
// Target will send an ACK as a 1
// If SDA is 0 there is no ACK what means NACK
unsigned char I2CCheckACK( void );
// Send a NACK
void I2CSendNACK( void );
// Send a ACK
void I2CSendACK( void );
// Send a byte to the target
void I2CSendByte(unsigned char SendByte);
// Receive a byte from the target
unsigned char I2CGetByte( void );
// ClkSyncByte, do the garbage collection if bus fault
void I2CClkSyncByte(void);

#endif


使用特权

评论回复
沙发
mintspring|  楼主 | 2023-11-16 09:22 | 只看该作者
/********************************************************************/
/* Function    : I2C Basic Funktions                           FILE */
/*------------------------------------------------------------------*/
/* Description : This File has the basic functions needed for       */
/*               I2C comunication and is optimized to meet the      */
/*               requirements of 100KHz I2C running on normal       */
/*               8051 Core [url=home.php?mod=space&uid=72445]@[/url] 24MHz                                  */
/*------------------------------------------------------------------*/
/* Author      : Michael Schmitt                                    */
/*------------------------------------------------------------------*/
/* Input       : none                                               */
/*------------------------------------------------------------------*/
/* Returnvalue : none                                               */
/*------------------------------------------------------------------*/
/* History     : 00/03    V1.0 Initial Version                      */
/*                                                                  */
/********************************************************************/
#ifndef __FILE_I2CBASIC_C
#define __FILE_I2CBASIC_C

//#define I2C_DEBUG_MODE

void I2CDelay( void )
{
    NOP;
    NOP;
    NOP;
    NOP;
    NOP;
    NOP;
}

// Send the I2C start command to the target device
// "safety start" for 100kHz devices (24MHz)
void I2CSendStart( void )
{
#ifdef I2C_DEBUG_MODE
    printf("\n\r<Start>");
#endif
    // Start Condition SDA 1->0 while SCL is 1
    I2CDelay();
    I2CSDA = 1;
    I2CDelay();
    I2CSCL = 1;
    I2CDelay();
    I2CSDA = 0;
    I2CDelay();
    I2CSCL = 0;
    I2CDelay();
}


// Send the I2C stop command to the target device
// "safety stop" for 100kHz devices (24MHz)
void I2CSendStop( void )
{
#ifdef I2C_DEBUG_MODE
printf("<Stopp>");
#endif
    // Stop Condition SDA 0->1 while SCL is 1
    I2CDelay();
    I2CSDA = 0;
    I2CDelay();
    I2CSCL = 1;
    I2CDelay();
    I2CSDA = 1;
    I2CDelay();
}


// Send a clock pulse and check SDA for an ACK
// Target will send an ACK as a 1
// If SDA is 0 there is no ACK what means NACK
unsigned char I2CCheckACK( void )
{
    unsigned char return_value;
    I2CSDA = 1;
        NOP;
        NOP;
        NOP;
        NOP;
//    I2CDelay();
    I2CSCL = 1;
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//      NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
//    I2CDelay();
    return_value = !I2CSDA;   // invert
#ifdef I2C_DEBUG_MODE
    if( return_value == 1 )
    {
        printf("<?ACK>");
    }
    else
    {
        printf("<?NACK>");
    }
#endif
    I2CSCL = 0;
    return( return_value ); // 1=ACK 0=NACK
}

// Send a NACK
void I2CSendNACK( void )
{
#ifdef I2C_DEBUG_MODE
printf("<!NACK>");
#endif
    // NACK by Master sending a single 1
    I2CSDA = 1;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
//    I2CDelay();
    I2CSCL = 1;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
//    I2CDelay();
    I2CSCL = 0;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
//    I2CDelay();
    I2CSDA = 0;
}

// Send a ACK
void I2CSendACK( void )
{
#ifdef I2C_DEBUG_MODE
    printf("<!ACK>");
#endif
    // ACK by Master sending a single 0
        I2CSDA = 0;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
//    I2CDelay();
    I2CSCL = 1;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
//    I2CDelay();
    I2CSCL = 0; // Cmd executin lasts 1usec so clk 100KHz
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//    I2CDelay();
//  I2CSDA = 0;
}

// Send a byte to the target
void I2CSendByte(unsigned char SendByte)
{
    register unsigned char i;
#ifdef I2C_DEBUG_MODE
printf("<S:%02X>",(unsigned int)SendByte);
#endif
    for (i=0; i<8; i++)
    {
//      I2CDelay();
        if ( SendByte & 0x80)
        {
            I2CSDA = 1;        // MSB first -> LSB last
        }
        else
        {
            I2CSDA = 0;
        }
//      NOP;
//      NOP;
//      NOP;
//      NOP;
        I2CSCL = 1;
        /* doing the shift during clocking, otherwise the pulse width would be to short */
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        SendByte = SendByte << 1;
//      I2CDelay();
        I2CSCL = 0;
//      I2CDelay();
    }
}

// Receive a byte from the target
unsigned char I2CGetByte( void )
{
    register unsigned char i, res;

    I2CSDA = 1; /* release SDA-Line */
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//  I2CDelay();
    res = 0;
    for (i=0;i<8;i++)     // each bit at a time, MSB first
    {
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        I2CSCL = 1;
        res = res << 1;
//      I2CDelay();
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//      NOP;
        if (I2CSDA) res++;
//      I2CDelay();
//      NOP;
//      NOP;
//      NOP;
//      NOP;
//      NOP;
        I2CSCL = 0;
//      I2CDelay();
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
    }
#ifdef I2C_DEBUG_MODE
printf("<G:%02X>",(unsigned int)res);
#endif
    return(res);
}

// ClkSyncByte fclk=100kHz
void I2CClkSyncByte(void)
{
    register unsigned char i;
#ifdef I2C_DEBUG_MODE
printf("<SYNC>");
#endif
    for (i=0; i<8; i++)
    {
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
//      I2CDelay();
        I2CSCL = 1;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
//      I2CDelay();
        I2CSCL = 0;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
//      I2CDelay();
    }
}

#endif

使用特权

评论回复
板凳
mintspring|  楼主 | 2023-11-16 09:23 | 只看该作者
在这个基础上根据自己情况替换成相应的操作即可。

使用特权

评论回复
地板
Jacquetry| | 2023-11-20 10:36 | 只看该作者
模拟方式就是适合移植啊

使用特权

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

本版积分规则

296

主题

4893

帖子

24

粉丝