zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    JAVA集合类汇总
    springmvc执行流程详细介绍
    java文件上传和下载
    Java中的Filter过滤器
    JSTL介绍及使用
    JSP知识汇总
    JAVA集合类汇总
    服务治理框架dubbo中zookeeper的使用
    map进程数量和reduce进程数量
    Hadoop的序列化
  • 原文地址:https://www.cnblogs.com/wwjdwy/p/2945817.html
Copyright © 2011-2022 走看看