stm32 iic 读写

#include "I2C.h"
#include "bsp.h"
#include "stm32f10x_i2c.h"
u8 I2C_MODE = I2C_HardMode;
u8 I2C_ADDR = I2C_ADDR_DEF;
int SDA_DELAY=    8;         //SDA数据保持时间
int SCL_DELAY=    8;         //SCL沿变之后,延时SCL_DEALY,SDA再变
int STA_DELAY=    8;     //SDA在产生STA时序后,SCL保持STA_DELAY
int STO_DELAY=    8;         //SDA在产生STO时序后,SCL保持STA_DELAY

/****************************************************************
 * 函数名:I2C_START                               
 * 功能说明:发送Start命令        
 * 入口参数:N/A                
 * 出口参数:N/A                                                                     
 ****************************************************************/
void I2C_START(void)
{
    u16 i;
    //I2C_SDA_ON;                //SDA = 1
    I2C_SCL_ON;                //SCL = 1;
    for(i=SCL_DELAY;i>0;i--);
    I2C_SDA_OFF;            //SDA = 0;
    for(i=STA_DELAY;i>0;i--);
}
/****************************************************************
 * 函数名:I2C_STOP                                            
 * ¹功能说明:发送Stop命令      
 * 入口参数:N/A                
 * 出口参数:N/A                                                                       
 ****************************************************************/
void I2C_STOP(void)
{
    u16 i;
    I2C_SCL_OFF;
    I2C_SDA_OFF;
    I2C_SCL_ON;
    for(i=SCL_DELAY;i>0;i--);
    I2C_SDA_ON;
    for(i=STO_DELAY;i>0;i--);
}
/****************************************************************
 * 函数名:I2C_SEND_DATA                                            
 * 功能说明:I2C发送一个数据        
 * 入口参数:i2cdata:要发送的数据           
 * 出口参数:N/A                                                                             
 ****************************************************************/
void I2C_SEND_DATA(u8 i2cdata)
{
    u16 i;
    u16 j;
    u8 temp;

    for (i = 0; i < 8; i++)        // 8 λÊý¾Ý£¬High Bit First£»
    {
         I2C_SCL_OFF;
        for(j= SCL_DELAY;j>0;j--);
        temp = i2cdata & 0x80;
        if(temp == 0)
            I2C_SDA_OFF;
        else
            I2C_SDA_ON;
        i2cdata = i2cdata << 1;
        I2C_SCL_ON;
        for(j= SDA_DELAY;j>0;j--);
  }

    I2C_SCL_OFF;
//    I2C_SDA_ON;                    //SDA高,释放总线
}
/****************************************************************
 * 函数名:I2C_RECV_ACK                                            
 * 功能说明:I2C接收ACK数据          
 * 入口参数:N/A                
 * 出口参数:ack:0/1                                                                        
 ****************************************************************/
u8 I2C_RECV_ACK(void)
{
    u16 i;
    u8 ack;
//    I2C_SCL_OFF;
//    I2C_SDA_ON;
    for(i= SCL_DELAY;i>0;i--);     //Áô¸øSlaveÏìӦʱ¼ä
    I2C_SCL_ON;
    for(i= SDA_DELAY;i>0;i--);    
    ack = Get_SDA_Status;
    
    I2C_SCL_OFF;
    I2C_SDA_ON;                    //SDA¸ß£¬ÊÍ·Å×ÜÏß
    return ack;
}
/****************************************************************
 * 函数名:I2C_RECV_DATA                                            
 * 功能说明:I2C接收数据          
 * 入口参数:N/A                
 * 出口参数:i2c_data                                                                        
 ****************************************************************/
u8 I2C_RECV_DATA(void)
{
    int i,j;
    u8 i2cdata=0x00;
    u8 dsda;

    I2C_SCL_OFF;
//    SET_SDA_IN();
    //I2C_SDA_ON;
    for(i= SCL_DELAY;i>0;i--);
    for (i = 7; i >= 0; i--)
    {    
        I2C_SCL_ON;
        __nop();    __nop();   __nop();    __nop();  __nop();
        i2cdata|=(Get_SDA_Status<<i);
        for(j= SDA_DELAY;j>0;j--);        
        I2C_SCL_OFF;
        for(j= SCL_DELAY;j>0;j--);
    }
    I2C_SDA_ON;                    //SDA¸ß£¬ÊÍ·Å×ÜÏß
    return i2cdata;
}

/****************************************************************
 * 函数名:I2C_SEND_ACK                                            
 * 功能说明:I2C发送ACK响应          
 * 入口参数:ack:0/1                
 * 出口参数:N/A                                                                     
 ****************************************************************/
void I2C_SEND_ACK(u8 ack)
{
    u16 i;

    I2C_SCL_OFF;
    if(ack == 0)
        I2C_SDA_OFF;
    else
        I2C_SDA_ON;
    for(i= SCL_DELAY;i>0;i--);    
    I2C_SCL_ON;
    for(i= SDA_DELAY;i>0;i--);
    I2C_SCL_OFF;
    I2C_SDA_ON;                    //SDA高,释放总线
}

/****************************************************************
 * 函数名:I2C_START_HS                                            
 * 功能说明:发送Start命令         
 * 入口参数:N/A                
 * 出口参数:N/A                                                                           
 ****************************************************************/
void I2C_START_HS(void)
{
    u16 i;
    //I2C_SCL_OFF;            //SCL = 0;
    //I2C_SDA_ON;                //SDA = 1
    I2C_SCL_ON;                //SCL = 1;
    for(i=SCL_DELAY;i>0;i--);
    I2C_SDA_OFF;            //SDA = 0;
    for(i=STA_DELAY;i>0;i--);
}
/****************************************************************
 * 函数名:I2C_STOP_HS                                            
 * 功能说明:发送Stop命令           
 * 入口参数:N/A                
 * 出口参数:N/A                                                                            
 ****************************************************************/
void I2C_STOP_HS(void)
{
    u16 i;
    I2C_SCL_OFF;
    I2C_SDA_OFF;
    I2C_SCL_ON;
    for(i=SCL_DELAY;i>0;i--);
    I2C_SDA_ON;
    for(i=STO_DELAY;i>0;i--);
}
/****************************************************************
 * 函数名:I2C_SEND_DATA_HS                                            
 * 功能说明:I2C发送一个数据        
 * 入口参数:i2cdata:要发送的数据           
 * 出口参数:N/A                                                                      
 ****************************************************************/
void I2C_SEND_DATA_HS(u8 i2cdata)
{
    u16 i;
    for (i = 0; i < 8; i++)        // 8 位数据,High Bit First
    {
        I2C_SCL_OFF;
        if(i2cdata&(0x80>>i))
                I2C_SDA_ON;
        else
                I2C_SDA_OFF;
        I2C_SCL_ON;    
    }
    I2C_SCL_OFF;
//    I2C_SDA_ON;                    //SDA高,释放总线
//    //´此处是否需要立即将SDA配置才输入?或者直接拉高就可以了?
    for (i = 0; i < 2; i++);    //just to delay,wait for SDA to Low .yzx
}
/****************************************************************
 * 函数名:I2C_RECV_ACK                                            
 * 功能说明:I2C接收ACK数据      
 * 入口参数:N/A                
 * 出口参数:ack:0/1                                                                         
 ****************************************************************/
u8 I2C_RECV_ACK_HS(void)
{
    u8 ack;

//    I2C_SCL_OFF;
//    I2C_SDA_ON;
    
    //SET_SDA_IN();

    I2C_SCL_ON;
    //__nop();__nop();__nop();__nop();
    //__nop();__nop();__nop();__nop();
    //__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();    
    ack = Get_SDA_Status;
    
    I2C_SCL_OFF;
    I2C_SDA_ON;                    //SDA高,释放总线

    return ack;
}
/****************************************************************
 * 函数名:I2C_RECV_DATA_HS                                            
 * 功能说明:I2C接收数据       
 * 入口参数:N/A                
 * 出口参数:i2c_data                                                                           
 ****************************************************************/
u8 I2C_RECV_DATA_HS(void)
{
    int i;
    u8 i2cdata=0x00;
    for (i = 7; i >= 0; i--)        // 8 位数据,High Bit First
    {
    I2C_SCL_OFF;
    __nop();    __nop();    __nop();    __nop();    __nop();    __nop();    __nop();
//    for (j = 0; j < 1; j++);    //just to delay,wait for SDA to Low .yzx
//    SET_SDA_IN();
    I2C_SCL_ON;
    i2cdata|=(Get_SDA_Status<<i);        
    }
    I2C_SCL_OFF;
    I2C_SDA_ON;                    //SDA高,释放总线
    return i2cdata;
}
/****************************************************************
 * 函数名:I2C_SEND_ACK_HS                                            
 * 功能说明:I2C发送ACK响应     
 * 入口参数:ack:0/1                
 * 出口参数:N/A                                                                           
 ****************************************************************/
void I2C_SEND_ACK_HS(u8 ack)
{
    u16 i;

    I2C_SCL_OFF;
    if(ack)
        I2C_SDA_ON;
    else
        I2C_SDA_OFF;
    for(i= 1;i>0;i--);    
    I2C_SCL_ON;
    for(i= 2;i>0;i--);
    I2C_SCL_OFF;
    I2C_SDA_ON;                    //SDA高,释放总线
}

/****************************************************************
 * 函数名:I2C_Read_Byte_Soft                                            
 * 功能说明:I2C读字节(软件模拟方式)            
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                 
 ****************************************************************/
uint8_t I2C_Read_Byte_Soft(uint8_t SlaveAddress,uint8_t REG_Address)
{
    uint8_t REG_data,temp;
    if(I2C_MODE == I2C_HSMode)
        {
            I2C_START();
            I2C_SEND_DATA(I2C_MASTERCODE);        //MasterCode
            if(I2C_RECV_ACK())                                //接收,但不判断
                {
                    I2C_STOP();
                    return 0x10;
                }            
            I2C_START();                        //ReStart
            I2C_SEND_DATA_HS(SlaveAddress&0xFE);        //Addr+W        
            if(I2C_RECV_ACK_HS())
                {
                    I2C_STOP();
                    return 0x1;
                }        
            I2C_SEND_DATA_HS(REG_Address&0x7F);        //Addr
            if(I2C_RECV_ACK_HS())
                {
                    I2C_STOP();
                    return 0x2;
                }    
            I2C_START();    
            I2C_SEND_DATA_HS(SlaveAddress|0x01);        //Addr+R
            if(I2C_RECV_ACK_HS())
            {
                I2C_STOP();
                return 0x3;
            }
            REG_data = I2C_RECV_DATA_HS();
            I2C_SEND_ACK(1);        //NACK
            I2C_STOP();                
        }
    else    
        {
            I2C_START();
            I2C_SEND_DATA(SlaveAddress&0xFE);        //Addr+W    
            if(I2C_RECV_ACK())
                {
                    I2C_STOP();
                    return 0x1;
                }        
            I2C_SEND_DATA(REG_Address&0x7F);        //Addr
            if(I2C_RECV_ACK())
                {
                    I2C_STOP();
                    return 0x2;
                }
            I2C_START();        
            I2C_SEND_DATA(SlaveAddress|0x01);        //Addr+R
            if(I2C_RECV_ACK())
            {
                I2C_STOP();
                return 0x3;
            }                
            REG_data = I2C_RECV_DATA();
            I2C_SEND_ACK(1);        //NACK
            I2C_STOP();                
        }
return REG_data;
}

/****************************************************************
 * 函数名:I2C_Write_Byte_Soft                                            
 * 功能说明:I2C写字节(软件模拟方式)        
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                           
 ****************************************************************/
uint8_t I2C_Write_Byte_Soft(uint8_t SlaveAddress,uint8_t REG_Address,uint8_t REG_data)
{
    if(I2C_MODE == I2C_HSMode)
        {
            I2C_START();
            I2C_SEND_DATA(I2C_MASTERCODE);        //MasterCode
            if(I2C_RECV_ACK())                                //接收,但不判断
                {
                    I2C_STOP();
                    return 0x10;
                }            
            I2C_START();                        //ReStart
            I2C_SEND_DATA_HS(SlaveAddress&0xFE);        //Addr+W        
            if(I2C_RECV_ACK_HS())
                {
                    I2C_STOP();
                    return 0x1;
                }        
            I2C_SEND_DATA_HS(REG_Address&0x7F);        //Addr
            if(I2C_RECV_ACK_HS())
                {
                    I2C_STOP();
                    return 0x2;
                }    
            I2C_SEND_DATA_HS(REG_data);        //data
            if(I2C_RECV_ACK_HS())
                {
                    I2C_STOP();
                    return 0x3;
                }    
            I2C_STOP();                
        }
    else    
        {
            I2C_START();
            I2C_SEND_DATA(SlaveAddress&0xFE);        //Addr+W    
            if(I2C_RECV_ACK())
                {
                    I2C_STOP();
                    return 0x1;
                }        
            I2C_SEND_DATA(REG_Address&0x7F);        //Addr
            if(I2C_RECV_ACK())
                {
                    I2C_STOP();
                    return 0x2;
                }
            I2C_SEND_DATA(REG_data);        //data
            if(I2C_RECV_ACK())
                {
                    I2C_STOP();
                    return 0x3;
                }                
            I2C_STOP();
        }
        return 0x00;    
}
/****************************************************************
 * 函数名:I2C_Cont_Read_Byte_Soft                                            
 * 功能说明:I2C连续读字节(软件模拟方式)            
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                   
 ****************************************************************/
uint8_t I2C_Cont_Read_Byte_Soft(uint8_t SlaveAddress,uint8_t REG_Address,int Read_Num,uint8_t* REG_data)
{
    uint8_t temp;
    int i;
    if(I2C_MODE == I2C_HSMode)
        {        
            I2C_START();                        //ReStart
            I2C_SEND_DATA_HS(SlaveAddress&0xFE);        //Addr+W        
            if(I2C_RECV_ACK_HS())
                {
                    I2C_STOP();
                    return 0x01;
                }        
            I2C_SEND_DATA_HS(REG_Address&0x7F);        //Addr
            if(I2C_RECV_ACK_HS())
                {
                    I2C_STOP();
                    return 0x02;
                }    
            I2C_START();    
            I2C_SEND_DATA_HS(SlaveAddress|0x01);        //Addr+R
            if(I2C_RECV_ACK_HS())
            {
                I2C_STOP();
                return 0x03;
            }
                
        for(i=0;i<(Read_Num-1);i++)
            {    
                *(REG_data+i)= I2C_RECV_DATA_HS();//读出数据    
                I2C_SEND_ACK_HS(0);        //ACK
            }
        *(REG_data+i)= I2C_RECV_DATA_HS(); //读出最后一个数据             
            I2C_SEND_ACK_HS(1);        //NACK
            I2C_STOP();            
        }
    else    
        {        
            I2C_START();
            I2C_SEND_DATA(SlaveAddress&0xFE);        //Addr+W    
            if(I2C_RECV_ACK())
                {
                    I2C_STOP();
                    return 0x01;
                }        
            I2C_SEND_DATA(REG_Address&0x7F);        //Addr
            if(I2C_RECV_ACK())
                {
                    I2C_STOP();
                    return 0x02;
                }
            I2C_START();        
            I2C_SEND_DATA(SlaveAddress|0x01);        //Addr+R
            if(I2C_RECV_ACK())
            {
                I2C_STOP();
                return 0x03;
            }                
        for(i=0;i<(Read_Num-1);i++)
            {    
                *(REG_data+i)= I2C_RECV_DATA();//读出数据           
                I2C_SEND_ACK(0);        //ACK
            }
        *(REG_data+i)= I2C_RECV_DATA(); //读出最后一个数据                
            I2C_SEND_ACK(1);        //NACK
            I2C_STOP();                
        }
        return 0x00;            
}
/****************************************************************
 * 函数名:I2C_Cont_Write_Byte_Soft                                            
 * 功能说明:I2C连续写字节(软件模拟方式)        
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                         
 ****************************************************************/
uint8_t I2C_Cont_Write_Byte_Soft(uint8_t SlaveAddress,uint8_t REG_Address,int Write_Num,uint8_t* REG_data)
{
    int i;
    if(I2C_MODE == I2C_HSMode)
        {        
            I2C_START();                        //ReStart
            I2C_SEND_DATA_HS(SlaveAddress&0xFE);        //Addr+W        
            if(I2C_RECV_ACK_HS())
                {
                    I2C_STOP();
                    return 0x01;
                }        
            I2C_SEND_DATA_HS(REG_Address&0x7F);        //Addr
            if(I2C_RECV_ACK_HS())
                {
                    I2C_STOP();
                    return 0x02;
                }            
                for(i=0;i<Write_Num;i++)
                {    
                    I2C_SEND_DATA_HS(*(REG_data+i));        //data    
                    if(I2C_RECV_ACK_HS())
                        {
                            I2C_STOP();
                            return 0x03;
                        }    
                }
            I2C_STOP();                
        }
    else    
        {
            I2C_START();
            I2C_SEND_DATA(SlaveAddress&0xFE);        //Addr+W    
            if(I2C_RECV_ACK())
                {
                    I2C_STOP();
                    return 0x01;
                }        
            I2C_SEND_DATA(REG_Address&0x7F);        //Addr
            if(I2C_RECV_ACK())
                {
                    I2C_STOP();
                    return 0x02;
                }
                for(i=0;i<Write_Num;i++)
                {    
                    I2C_SEND_DATA(*(REG_data+i));        //data    
                    if(I2C_RECV_ACK())
                        {
                            I2C_STOP();
                            return 0x03;
                        }    
                }                
            I2C_STOP();
        }
        return 0x00;    
}
/****************************************************************
 * 函数名:I2C_Config                                            
 * 功能说明:I2C配置          
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                           
 ****************************************************************/
void I2C_Config(void)
{
    //I2C_Cmd(I2C1, DISABLE);
    I2C_InitTypeDef I2C_InitStructure;
    I2C_Cmd(I2C2, DISABLE);
    I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;
    I2C_InitStructure.I2C_OwnAddress1=0x0A;
    I2C_InitStructure.I2C_Ack=I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed=400000;
    I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
    I2C2->CR1 |=0x8000;
    I2C2->CR1 &=0x7fff;
    I2C_Init(I2C2,&I2C_InitStructure);
    
    I2C_Cmd(I2C2, ENABLE);
    I2C_Init(I2C1,&I2C_InitStructure);
    
    I2C_Cmd(I2C1, ENABLE);
}
/****************************************************************
 * 函数名:I2C_Read_Byte_Hard                                            
 * 功能说明:I2C读字节        
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                        
 ****************************************************************/
uint8_t I2C_Read_Byte_Hard(uint8_t SlaveAddress,uint8_t REG_Address)
{
        uint8_t REG_data;
        while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
        I2C_GenerateSTART(I2C2, ENABLE); //起始信号
        while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
        I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Transmitter);//发送设备地址+写信号
        while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
        I2C_SendData(I2C2,REG_Address); //发送存储单元地址,从0开始
        while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        I2C_GenerateSTART(I2C2, ENABLE); //起始信号
        while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
        I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Receiver); //发送设备地址+读信号
        while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
        I2C_AcknowledgeConfig(I2C2, DISABLE);
        I2C_GenerateSTOP(I2C2, ENABLE);
        while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)));
        REG_data=I2C_ReceiveData(I2C2); //读出寄存器数据

        return REG_data;
}
/****************************************************************
 * 函数名:I2C_Write_Byte_Hard                                            
 * 功能说明:I2C写字节         
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                           
 ****************************************************************/
void I2C_Write_Byte_Hard(uint8_t SlaveAddress,uint8_t REG_Address,uint8_t REG_data)
{
        I2C_GenerateSTART(I2C2, ENABLE);
        while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
        I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Transmitter);
        while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
        I2C_SendData(I2C2, REG_Address);
        while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        I2C_SendData(I2C2, REG_data);
        while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        I2C_GenerateSTOP(I2C2, ENABLE);

}
/****************************************************************
 * 函数名:I2C_Cont_Read_Byte_Hard                                            
 * 功能说明:I2C连续读字节          
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                            
 ****************************************************************/
uint8_t I2C_Cont_Read_Byte_Hard(uint8_t SlaveAddress,uint8_t REG_Address,int Read_Num,uint8_t* REG_data)
{
    int i;
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
    I2C_GenerateSTART(I2C2, ENABLE); //起始信号
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
    I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Transmitter);//发送设备地址+写信号
    while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
        
    I2C_SendData(I2C2,REG_Address); //发送存储单元地址,从0开始
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        
    I2C_GenerateSTART(I2C2, ENABLE); //起始信号
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
    I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Receiver); //发送设备地址+读信号
    while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    for(i=0;i<(Read_Num-1);i++)
        {    
            I2C_AcknowledgeConfig(I2C2, ENABLE);
            I2C_GenerateSTOP(I2C2, DISABLE);
            while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)));
            *(REG_data+i)=I2C_ReceiveData(I2C2); //¶读出寄存器数据 
        }
            I2C_AcknowledgeConfig(I2C2, DISABLE);        
            I2C_GenerateSTOP(I2C2, ENABLE);
            while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)));
            *(REG_data+i)=I2C_ReceiveData(I2C2); //读出寄存器数据
            return 0x00;
    
}
/****************************************************************
 * 函数名:I2C_Cont_Write_Byte_Hard                                        
 * 功能说明:I2C连续写字节        
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                     
 ****************************************************************/
uint8_t I2C_Cont_Write_Byte_Hard(uint8_t SlaveAddress,uint8_t REG_Address,int Write_Num,uint8_t* REG_data)
{
    int i;
    I2C_GenerateSTART(I2C2, ENABLE);
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
    I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    I2C_SendData(I2C2, REG_Address);
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    for(i=0;i<Write_Num;i++)
        {    
        I2C_SendData(I2C2,*(REG_data+i));
        while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        }
    I2C_GenerateSTOP(I2C2, ENABLE);

    return 0x00;        
}
/****************************************************************
 * 函数名:I2C_Speed_Ctrl                                            
 * 功能说明:I2C速率切换
 * 入口参数:I2CSpeed
 * 出口参数:返回00表示修改成功,返回EE表示失败                                                          
 ****************************************************************/
u8 I2C_Speed_Ctrl(u8 I2CSpeed)
{
    int DelayTemp;
    I2C_InitTypeDef I2C_InitStructure;
    if(I2CSpeed == 0xFF)     //-1默认
        {
            I2C_MODE = I2C_HardMode;
                
            GPIOPinxConfig(I2C_PORT,I2C_SCL, GPIO_Speed_50MHz, GPIO_Mode_AF_OD);
            GPIOPinxConfig(I2C_PORT,I2C_SDA, GPIO_Speed_50MHz, GPIO_Mode_AF_OD);    
        
            RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);        //不需超频

            RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);        //使能I2C2时钟
            
            I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;
            I2C_InitStructure.I2C_OwnAddress1=0x0A;
            I2C_InitStructure.I2C_Ack=I2C_Ack_Enable;
            I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
            I2C_InitStructure.I2C_ClockSpeed=400000;
            I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
            I2C_Init(I2C2,&I2C_InitStructure);

            
            DelayTemp = 8;
        }
        
    else if(I2CSpeed == 0xFE)   //-2 HS模式  3.4MHz.【注】程序中无法超频,需要在运行之前配置 I2C_MODE = I2C_HSMode,且运行I2C_Speed_Ctrl(-2)
        {
            I2C_MODE = I2C_HSMode;
                
            GPIOPinxConfig(I2C_PORT,I2C_SCL, GPIO_Speed_50MHz, GPIO_Mode_Out_OD);//软件模拟用
            GPIOPinxConfig(I2C_PORT,I2C_SDA, GPIO_Speed_50MHz, GPIO_Mode_Out_OD);
        
//            RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_16);        //需超频
                            
            DelayTemp = 1;
        }            
    else if(I2CSpeed&0x80)    //Ó²¼þ
        {
            if((I2CSpeed&0x7F)<=40)//´óÓÚ400k
                {
                    I2C_MODE = I2C_HardMode;
                        
                    GPIOPinxConfig(I2C_PORT,I2C_SCL, GPIO_Speed_50MHz, GPIO_Mode_AF_OD);
                    GPIOPinxConfig(I2C_PORT,I2C_SDA, GPIO_Speed_50MHz, GPIO_Mode_AF_OD);    
                
                    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);        //不需超频

                    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);        //使能I2C2时钟
                    
                    DelayTemp = 8;

                    I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;
                    I2C_InitStructure.I2C_OwnAddress1=0x0A;
                    I2C_InitStructure.I2C_Ack=I2C_Ack_Enable;
                    I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
                    I2C_InitStructure.I2C_ClockSpeed=(I2CSpeed&0x7F)*10000;
                    I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
                    I2C_Init(I2C2,&I2C_InitStructure);
                }
            else
                {
                    return 0xEE;        //切换失败
                }

        }
        else                                           //软件
        {
                    I2C_MODE = I2C_FSMode;
                        
                    GPIOPinxConfig(I2C_PORT,I2C_SCL, GPIO_Speed_50MHz, GPIO_Mode_Out_OD);//Èí¼þÄ£ÄâÓÃ
                    GPIOPinxConfig(I2C_PORT,I2C_SDA, GPIO_Speed_50MHz, GPIO_Mode_Out_OD);
                
                    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);        //²»Ð賬Ƶ
                    DelayTemp = I2CSpeed;    
        }

        SDA_DELAY=    DelayTemp;         //SDA数据保持时间
        SCL_DELAY=    DelayTemp;         //SCL沿变之后,延时SCL_DELAY,SDA再变
        STA_DELAY=    DelayTemp;     //SDA在产生STA时序后,SCL保持STA_DELAY
        STO_DELAY=    DelayTemp;         //SDA在产生STO时序后,SCL保持STA_DELAY

        return 0x00;        //切换成功
    
}
/****************************************************************
 * 函数名:I2C_Slave_Addr_Ctrl                                            
 * 功能说明:I2C速率切换(通过改变延时实现)
 * 入口参数:I2C_Addr
                (1)I2C_Addr==0xFF,硬件实现400kHz  (默认)
                (2)否则,清除读写位(最低位)后配置
 * 出口参数:NA                                                    
 ****************************************************************/
void I2C_Slave_Addr_Ctrl(u8 I2C_Addr)
{
    if(I2C_Addr==0x00)
        I2C_ADDR = I2C_ADDR_DEF;//00,配置成默认值
    else
        I2C_ADDR = I2C_Addr&0xFE;        //否则,清除读写位(最低位)后配置
}
/****************************************************************
 * 函数名:I2C_Cont_Read_Byte                                            
 * 功能说明:I2C连续读字节         
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                          
 ****************************************************************/
uint8_t I2C_Cont_Read_Byte(uint8_t SlaveAddress,uint8_t REG_Address,int Read_Num,uint8_t* REG_data)
{
     if(I2C_MODE==I2C_HardMode)
         {
                return I2C_Cont_Read_Byte_Hard(SlaveAddress,REG_Address,Read_Num,REG_data);
         }
     else
         {
                return I2C_Cont_Read_Byte_Soft(SlaveAddress,REG_Address,Read_Num,REG_data);
         }    
}    
/****************************************************************
 * 函数名:I2C_Cont_Write_Byte                                        
 * 功能说明:I2C连续写字节        
 * 入口参数:N/A                    
 * 出口参数:N/A                                                                       
 ****************************************************************/
uint8_t I2C_Cont_Write_Byte(uint8_t SlaveAddress,uint8_t REG_Address,int Write_Num,uint8_t* REG_data)
{
     if(I2C_MODE==I2C_HardMode)
         {
                return I2C_Cont_Write_Byte_Hard(SlaveAddress,REG_Address,Write_Num,REG_data);
         }
     else
         {
                return I2C_Cont_Write_Byte_Soft(SlaveAddress,REG_Address,Write_Num,REG_data);
         }    
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值