i/o 模拟IIC

//头文件 

#ifndef SOFT_I2C_H
#define SOFT_I2C_H


#include "../lib/microchip/include/GenericTypeDefs.h"


typedef struct
{
    BYTE pinSCL;
    BYTE pinSDA;
    WORD Delay;
}SOFT_I2C_DEF;


void I2C_Init(const SOFT_I2C_DEF *def);
void I2C_Start(const SOFT_I2C_DEF *def);
void I2C_Stop(const SOFT_I2C_DEF *def);
BOOL I2C_CheckAcknowledge(const SOFT_I2C_DEF *def);
void I2C_WriteByte(const SOFT_I2C_DEF *def,BYTE b);
BOOL I2C_WriteNBytes(const SOFT_I2C_DEF *def,BYTE *buffer,int n);
BYTE I2C_ReadByte(const SOFT_I2C_DEF *def);
BOOL I2C_ReadNBytes(const SOFT_I2C_DEF *def,BYTE SlaveAdr,int n,BYTE *buffer);


#endif

//源文件 
#include "soft_i2c.h"
#include "features.h"
#include "pins.h"


static inline void SDAset(const SOFT_I2C_DEF *def,BOOL v)
{
    SetDigitalOutLevel(def->pinSDA,v);
}


static inline void SCLset(const SOFT_I2C_DEF *def,BOOL v)
{
    SetDigitalOutLevel(def->pinSCL,v);
}


static inline BOOL SDAget(const SOFT_I2C_DEF *def)
{
    return PinGetPort(def->pinSDA);
}


static inline BOOL SCLget(const SOFT_I2C_DEF *def)
{
    return PinGetPort(def->pinSCL);
}


static inline void I2C_DELAY(WORD t)
{
    volatile int i,j;
    for(i=0;i<t;i++)for(j=0;j<1;j++);
}


static void I2C_SEND_0(const SOFT_I2C_DEF *def)
{
    //发送0,在SCL为高电平时使SDA信号为低
    SDAset(def,0);
    SCLset(def,1);
    I2C_DELAY(def->Delay);
    SCLset(def,0);
    I2C_DELAY(def->Delay);
}


static void I2C_SEND_1(const SOFT_I2C_DEF *def)
{
    //发送1,在SCL为高电平时使SDA信号为高
    SDAset(def,1);
    SCLset(def,1);
    I2C_DELAY(def->Delay);
    SCLset(def,0);
    I2C_DELAY(def->Delay);
}


void I2C_Init(const SOFT_I2C_DEF *def)
{
    SetPinDigitalOut(def->pinSDA,1,TRUE);
    SetPinDigitalOut(def->pinSCL,1,TRUE);
}


void I2C_Start(const SOFT_I2C_DEF *def)
{
    //启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变
    SDAset(def,1);
    SCLset(def,1);
    I2C_DELAY(def->Delay);
    SDAset(def,0);
    I2C_DELAY(def->Delay);
    SCLset(def,0);
    I2C_DELAY(def->Delay);
}


void I2C_Stop(const SOFT_I2C_DEF *def)
{
    //终止I2C总线,当SCL为高电平时使SDA产生一个正跳变
    SDAset(def,0);
    SCLset(def,1);
    I2C_DELAY(def->Delay);
    SDAset(def,1);
    I2C_DELAY(def->Delay);
    SCLset(def,0);
    I2C_DELAY(def->Delay);
}




BOOL I2C_CheckAcknowledge(const SOFT_I2C_DEF *def)
{
    //发送完一个字节后检验设备的应答信号
    SDAset(def,1);
    SCLset(def,1);
    I2C_DELAY(def->Delay/2);
    BYTE F0=SDAget(def);
    I2C_DELAY(def->Delay/2);
    SCLset(def,0);
    I2C_DELAY(def->Delay);
    if(F0==1)return FALSE;
    return TRUE;
}


void I2C_WriteByte(const SOFT_I2C_DEF *def,BYTE b)
{
    //向I2C总线写一个字节
    BYTE i;
    for(i=0;i<8;i++)
    {
        if((b<<i)&0x80)I2C_SEND_1(def);
        else I2C_SEND_0(def);
    }
}


BOOL I2C_WriteNBytes(const SOFT_I2C_DEF *def,BYTE *buffer,int n)
{
    //向I2C总线写n个字节
    BYTE i;
    I2C_Start(def);


    for(i=0;i<n;i++)
    {
        I2C_WriteByte(def,buffer[i]);
        if(!I2C_CheckAcknowledge(def))
        {
            I2C_Stop(def);
            return(i==n);
        }
    }
    I2C_Stop(def);
    return TRUE;
}


BYTE I2C_ReadByte(const SOFT_I2C_DEF *def)
{
    //从I2C总线读一个字节
    BYTE b=0,i;
    for(i=0;i<8;i++)
    {
        SDAset(def,1);    //释放总线
        SCLset(def,1);    //接受数据
        I2C_DELAY(def->Delay);
        BYTE F0=SDAget(def);
        I2C_DELAY(def->Delay);
        SCLset(def,0);
        if(F0==1)
        {
            b=b<<1;
            b=b|0x01;
        }
        else
            b=b<<1;
    }
    return b;
}


BOOL I2C_ReadNBytes(const SOFT_I2C_DEF *def,BYTE SlaveAdr,int n,BYTE *buffer)
{
    //从I2C总线读n个字节
    int i;
    I2C_Start(def);
    I2C_WriteByte(def,SlaveAdr);        //向总线发送接收器地址
    if(!I2C_CheckAcknowledge(def))     //等待接收器应答信号
        return FALSE;
    for(i=0;i<n;i++)
    {
        buffer[i]=I2C_ReadByte(def);
        if(i!=n)
            I2C_SEND_0(def);    //发送应答
        else
            I2C_SEND_1(def);    //发送非应答
    }
    I2C_Stop(def);
    return TRUE;
}



你可能感兴趣的:(c,struct,ini,buffer,byte,delay)