STM32 IIC 通信 模拟方式

reading stucture                              
  device address   read command write address to board     device address read data from board    
start 0xb0 ack 0x01 ack address high ack address low ack start 0xb1 ack data high ack data low nack stop
example to read   address 0x1234 and result 0x789A                        
start 0xb0 ack 0x01 ack 0x12 ack 0x34 ack start 0xb1 ack 0x78 ack 0x9a nack stop
                                 
                                 
                                 
                                 
writing   stucture                              
  device address   write command write address to board read data from board          
start 0xb0 ack 0x81 ack address high ack address low ack data high ack data low ack stop      
example to write   address 0x5678 with data 0xcdef                        
start 0xb0 ack 0x81 ack 0x56 ack 0x78 ack 0xcd ack 0xef ack stop 0x9a    

 

ReadSensor
uint16_t IIC_ReadSensor(uint8_t byAD, uint16_t byRA, uint8_t byCount )
{
    uint8_t tmp_h=0, tmp_l=0;

    IIC_Start();                   /*启动总线*/
    IIC_WriteBit(byAD);                /*发送器件地址*/   
    IIC_WaitAck();
    
    IIC_WriteBit(0x01);                /*发送器件地址*/   
    IIC_WaitAck();

    IIC_WriteBit(byRA>>8);                /*发送器件子地址---数据寄存器*/
    IIC_WaitAck();
    IIC_WriteBit((uint8_t)byRA);                /*发送器件子地址---数据寄存器*/
    IIC_WaitAck();

    IIC_Start();                   /*重新启动总线*/

    IIC_WriteBit(byAD + 1);//address_read
    IIC_WaitAck();

    
    tmp_h=IIC_ReadBit();                /*接收数据*/
    IIC_Respond(0);                       /*发送就答位*/  

    tmp_l=IIC_ReadBit();
    IIC_Respond(1);                    /*发送非应位*/
    IIC_Stop();                    /*结束总线*/ 
    
    return((tmp_h<<8) | tmp_l);    
}
WriteSensor
uint16_t IIC_WriteSensor(uint8_t byAD, uint16_t byRA, uint16_t data )
{
    uint8_t tmp_h=0, tmp_l=0;

    IIC_Start();                   /*启动总线*/
    IIC_WriteBit(byAD);                /*发送器件地址*/   
    IIC_WaitAck();
    
    IIC_WriteBit(0x81);                /*发送器件地址*/   
    IIC_WaitAck();

    IIC_WriteBit(byRA>>8);                /*发送器件子地址---数据寄存器*/
    IIC_WaitAck();
    IIC_WriteBit((uint8_t)byRA);                /*发送器件子地址---数据寄存器*/
    IIC_WaitAck();
    
    IIC_WriteBit(data>>8);                /*发送数据高八位*/
    IIC_WaitAck();
    IIC_WriteBit((uint8_t)data);                /*发送数据低八位*/
    IIC_WaitAck();

    IIC_Stop();                    /*结束总线*/ 
        
}
IIC_Start
void IIC_Start(void)                                   //IIC开始函数
{
    IIC_SDA_Out();
    IIC_SDA_SET;
    IIC_SCL_SET;
    Delay_Us(4);
    IIC_SDA_RESET;
    Delay_Us(4);
    IIC_SCL_RESET;               
}
IIC_Stop
void IIC_Stop(void)                                       //IIC结束函数
{
    IIC_SDA_Out();
    IIC_SCL_RESET;
    IIC_SDA_RESET;
    Delay_Us(4);
    IIC_SCL_SET;
    Delay_Us(4);
    IIC_SDA_SET;
    
}
IIC_Respond
void IIC_Respond(u8 re)                                   //IIC应答函数
{
    u8 i;
    IIC_SDA_Out();
    if(re)     IIC_SDA_SET;
    else    IIC_SDA_RESET;
    IIC_SCL_SET;
    Delay_Us(5);     
    IIC_SCL_RESET;
    Delay_Us(2);
}
IIC_WaitAck
u8 IIC_WaitAck(void)
{
    u8 Out_Time=350;
    
    IIC_SDA_SET;
    IIC_SDA_In();
    Delay_Us(1);
    IIC_SCL_SET;
    Delay_Us(1);
//    IIC_SDA_In();
    while(IIC_SDA_GET)
    {
        
        if(--Out_Time)
        {
            printf("IIC time out!");
            IIC_Stop();
            return 1;
        }
    }
    IIC_SCL_RESET;
    return 0;

}
IIC_Init
void IIC_Init(void)                                           //IIC初始化函数
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    
  IIC_SDA_Out();
  IIC_SDA_SET;
  IIC_SCL_SET;
}
IIC_SDA_Out & IIC_SDA_In
void IIC_SDA_Out(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = IIC_SDA;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
    GPIO_Init(IIC_PORT, &GPIO_InitStructure);
}
void IIC_SDA_In(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = IIC_SDA;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        
    GPIO_Init(IIC_PORT, &GPIO_InitStructure);
}
IIC_ReadBit
u8 IIC_ReadBit(void)                       //从2402中读取一字节函数
{
    u8 i,Temp;
    
    IIC_SDA_In();
    for(i=0;i<8;i++)
    {
        IIC_SCL_RESET;
        Delay_Us(2);
        IIC_SCL_SET;
        Temp<<=1;                               //错误原来在这里 写成Temp<<1;
        if(IIC_SDA_GET)Temp++;
        Delay_Us(2);             
    }
    IIC_SCL_RESET;
    return Temp;
}
IIC_WriteBit
void IIC_WriteBit(u8 Temp)           //向2402中写一字节数据
{
    u8 i;
    IIC_SDA_Out();
    IIC_SCL_RESET;
    for(i=0;i<8;i++)
    {
        if(Temp&0x80)
        {
            IIC_SDA_SET;                        
        }
        else
        {

            IIC_SDA_RESET;
        }
        Temp<<=1;
        Delay_Us(2);
        IIC_SCL_SET;
        Delay_Us(4);
        IIC_SCL_RESET;
        Delay_Us(2);
        
    }

}

此代码为朋友所写,记录在此学习用。
谢谢东林

 

在I2C总线传输过程中,将两种特定的情况定义为开始和停止条件(见图3):当SCL保持“高”时,SDA由“高”变为“低”为开始条件;当SCL保持“高”且SDA由“低”变为“高”时为停止条件。开始和停止条件均由主控制器产生。

SDA线上的数据在时钟“高”期间必须是稳定的,只有当SCL线上的时钟信号为低时,数据线上的“高”或“低”状态才可以改变。输出到SDA线上的每个字节必须是8位,每次传输的字节不受限制,但每个字节必须要有一个应答ACK。

posted @ 2013-03-06 12:18  wwjdwy  阅读(752)  评论(0编辑  收藏  举报