单片机模拟iic(通用版)

typedef unsigned char           u8;

#define I2C_Pin_SCL        GPIO_Pin_4
#define I2C_Pin_SDA        GPIO_Pin_5

#define SCL_H         GPIOA_SetBits( I2C_Pin_SCL ) 
#define SCL_L         GPIOA_ResetBits( I2C_Pin_SCL ) 
#define SDA_H         GPIOA_SetBits( I2C_Pin_SDA ) 
#define SDA_L         GPIOA_ResetBits( I2C_Pin_SDA ) 
#define SCL_read      GPIOA_ReadPortPin( I2C_Pin_SCL ) 
#define SDA_read      GPIOA_ReadPortPin( I2C_Pin_SDA )  
#define SCL_out          GPIOA_ModeCfg(I2C_Pin_SCL, GPIO_ModeOut_PP_5mA) 
#define SCL_in          GPIOA_ModeCfg(I2C_Pin_SCL, GPIO_ModeIN_PU) 
#define SDA_out          GPIOA_ModeCfg(I2C_Pin_SDA, GPIO_ModeOut_PP_5mA)  
#define SDA_in          GPIOA_ModeCfg(I2C_Pin_SDA, GPIO_ModeIN_PU)  
            

void I2CInit(void);  
int I2C_7bit_Single_Write(u8 SlaveAddress,u8 REG_data);    
u8 I2C_7bit_Single_Read(u8 SlaveAddress);
int I2C_7bit_Mult_Read(u8 SlaveAddress,u8 * ptChar,u8 size);

int I2C_10bit_Single_Write(u8 SlaveAddress,u8 REG_Address,u8 REG_data);    
u8 I2C_10bit_Single_Read(u8 SlaveAddress,u8 REG_Address);
int I2C_10bit_Mult_Read(u8 SlaveAddress,u8 REG_Address,u8 * ptChar,u8 size);

void I2C_delay(void);
int I2C_Start(void);
void I2C_Stop(void);
void I2C_Ack(void); 
void I2C_NoAck(void);
int I2C_WaitAck(void);      //返回为:=1有ACK,=0无ACK
void I2C_SendByte(u8 SendByte);
u8 I2C_ReadByte(void);  //数据从高位到低位//




void I2CInit(void)
{
    SCL_out;        
    SDA_out;        
}


void I2C_delay(void)
{
   mDelayuS(100);
}

int I2C_Start(void)
{
    SDA_H;
    SDA_out;        
    SCL_H;
    I2C_delay();
    if(!SDA_read)return 0;    //SDA线为低电平则总线忙,退出
    SDA_L;
    I2C_delay();
    if(SDA_read) return 0;    //SDA线为高电平则总线出错,退出
    SDA_L;
    I2C_delay();
    return 1;    
}

void I2C_Stop(void)
{
    SCL_L;
    I2C_delay();
    SDA_L;
    SDA_out;        
    I2C_delay();
    SCL_H;
    I2C_delay();
    SDA_H;
    I2C_delay();
} 

void I2C_Ack(void)
{    
    SCL_L;
    I2C_delay();
    SDA_L;
    SDA_out;        
    I2C_delay();
    SCL_H;
    I2C_delay();
    I2C_delay();
    SCL_L;
    I2C_delay();
}   

void I2C_NoAck(void)
{    
    SCL_L;
    I2C_delay();
    SDA_H;
    SDA_out;        
    I2C_delay();
    SCL_H;
    I2C_delay();
    SCL_L;
    I2C_delay();
} 

int I2C_WaitAck(void)      //返回为:=1有ACK,=0无ACK
{
    SCL_L;
    I2C_delay();
    I2C_delay();
    SCL_H;
    SDA_in;        
    I2C_delay();
    I2C_delay();
    if(SDA_read)
    {
        SCL_L;
        return 0;
    }
    SCL_L;
    return 1;
}

void I2C_SendByte(u8 SendByte) //数据从高位到低位//
{
    u8 i=8;
    SDA_out;        
    while(i--)
    {
        SCL_L;
        I2C_delay();
        if(SendByte&0x80)
            SDA_H;  
        else 
            SDA_L;   
        SendByte<<=1;
        I2C_delay();
        SCL_H;
        I2C_delay();
        I2C_delay();
    }
    SCL_L;
}  

u8 I2C_ReadByte(void)  //数据从高位到低位//
{ 
    u8 i=8;
    u8 ReceiveByte=0;

    SDA_H;                
    SDA_out;        
    while(i--)
    {
        ReceiveByte<<=1;      
        SCL_L;
        I2C_delay();
        I2C_delay();
        SCL_H;
        SDA_in;        
        I2C_delay();    
        I2C_delay();
        if(SDA_read)
        {
            ReceiveByte|=0x01;
        }
    }
    SCL_L;
    return ReceiveByte;
} 

//7bit地址单字节写入*******************************************
int I2C_7bit_Single_Write(u8 SlaveAddress, u8 REG_data)        
{
    if(!I2C_Start())return 0;
    I2C_SendByte(SlaveAddress);   //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址 
    if(!I2C_WaitAck()){I2C_Stop(); return 0;}
    I2C_SendByte(REG_data);
    I2C_WaitAck();   
    I2C_Stop(); 
    return 1;
}

//7bit地址单字节读取*****************************************
u8 I2C_7bit_Single_Read(u8 SlaveAddress)
{   
    unsigned char REG_data;         
    if(!I2C_Start())return 0;
    I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址 
    if(!I2C_WaitAck())
    {
        I2C_Stop();
        return 0;
    }
    I2C_Start();
    I2C_SendByte(SlaveAddress+1);
    I2C_WaitAck();

    REG_data= I2C_ReadByte();
    I2C_NoAck();
    I2C_Stop();
    //return TRUE;
    return REG_data;

}    

//7bit地址多字节读取*****************************************
int I2C_7bit_Mult_Read(u8 SlaveAddress,u8 * ptChar,u8 size)
{
    u8 i;
    
    if(size < 1)
        return 0;
    if(!I2C_Start())
        return 0;
    I2C_SendByte(SlaveAddress);
    if(!I2C_WaitAck())
    {
        I2C_Stop();
        return 0;
    }
    I2C_Start();
    I2C_SendByte(SlaveAddress+1);
    I2C_WaitAck();
    
    for(i=1;i<size; i++)
    {
        *ptChar++ = I2C_ReadByte();
        I2C_Ack();
    }
    *ptChar++ = I2C_ReadByte();
    I2C_NoAck();
    I2C_Stop();
    return 1;    
}    



//10bit地址单字节写入*******************************************
int I2C_10bit_Single_Write(u8 SlaveAddress,u8 REG_Address,u8 REG_data)        
{
    if(!I2C_Start())return 0;
    I2C_SendByte(SlaveAddress);   //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址 
    if(!I2C_WaitAck()){I2C_Stop(); return 0;}
    I2C_SendByte(REG_Address );   //设置低起始地址      
    I2C_WaitAck();    
    I2C_SendByte(REG_data);
    I2C_WaitAck();   
    I2C_Stop(); 
    return 1;
}

//10bit地址单字节读取*****************************************
u8 I2C_10bit_Single_Read(u8 SlaveAddress,u8 REG_Address)
{   
    unsigned char REG_data;         
    if(!I2C_Start())return 0;
    I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址 
    if(!I2C_WaitAck())
    {
        I2C_Stop();
        return 0;
    }
    I2C_SendByte((u8) REG_Address);   //设置低起始地址      
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(SlaveAddress+1);
    I2C_WaitAck();

    REG_data= I2C_ReadByte();
    I2C_NoAck();
    I2C_Stop();
    //return TRUE;
    return REG_data;

}    

//10bit地址多字节读取*****************************************
int I2C_10bit_Mult_Read(u8 SlaveAddress,u8 REG_Address,u8 * ptChar,u8 size)
{
    u8 i;
    
    if(size < 1)
        return 0;
    if(!I2C_Start())
        return 0;
    I2C_SendByte(SlaveAddress);
    if(!I2C_WaitAck())
    {
        I2C_Stop();
        return 0;
    }
    I2C_SendByte(REG_Address);    
    I2C_WaitAck();
    
    I2C_Start();
    I2C_SendByte(SlaveAddress+1);
    I2C_WaitAck();
    
    for(i=1;i<size; i++)
    {
        *ptChar++ = I2C_ReadByte();
        I2C_Ack();
    }
    *ptChar++ = I2C_ReadByte();
    I2C_NoAck();
    I2C_Stop();
    return 1;    
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值