STM32单片机硬件I2C驱动程序(软件轮询方式)---摘自:FeoTech

匿名 (未验证) 提交于 2019-12-02 22:56:40

http://feotech.com/?p=69

本程序主要用于驱动STM32单片机芯片的硬件I2C寄存器,实现通过使用芯片自带的I2C寄存器进行数据的发送与接收.

本例程中采用I2C寄存器查询的方式来实现数据传输,当I2C对应寄存器指定状态时方可执行下一步操作.

 /**   ******************************************************************************   * @file    Hardware_I2C.c    * @author  Ryan Zhao   * @version V1.0.0   * @date    2017-04-27   * @brief   STM32硬件I2C底层驱动.   ******************************************************************************   * @attention   Null   *    ******************************************************************************   */    /** * @brief  I2C引脚与寄存器功能配置. * @param  None. * @retval None. */ void I2C_Configuration(void) {   /*GPIO与IIC初始化结构体*/     GPIO_InitTypeDef GPIO_InitStructure;     I2C_InitTypeDef I2C_InitStructure;      /*GPIO与IIC时钟使能*/     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );     //GPIOB时钟使能     RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE );      //I2C时钟使能      /*初始化GPIO*/     GPIO_InitStructure.GPIO_Pin =  HW_I2C_SDA_PIN | HW_I2C_SCL_PIN;   //初始化 IIC GPIO    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //最高输出速度50Hz     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;     //输入输出模式为复用功能开漏输出     GPIO_Init( GPIOB, &GPIO_InitStructure );            //根据GPIO初始化结构体初始化GPIOB      /*初始化I2C*/     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;                  //设置为I2C模式     I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;          //设置I2C的占空比,低电平除以高电平值为2      I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;                 //使能ACK信号     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   //指定7位地址     I2C_InitStructure.I2C_ClockSpeed = 400000;                  //时钟频率,必须小于等于400KHz      I2C_Cmd( HW_I2C, ENABLE );                                    //使能I2C    I2C_Init( HW_I2C, &I2C_InitStructure );                       //根据I2C初始化结构体初始化I2C      /*允许一字节一应答模式*/     I2C_AcknowledgeConfig( HW_I2C, ENABLE );                      //使能I2C应答状态  }   /** * @brief  从I2C指定地址中读取数据; * @param  读取的地址,读取后返回的数据; * @retval 1:读取数据成功,0:读取数据无效; */ unsigned char  I2C_ReadByte(unsigned char Read_Address,unsigned char * Read_Data) {    unsigned char wait_time_out = wait_time_value;//等待I2C器件响应的延时   * Read_Data = 0;    while (I2C_GetFlagStatus(HW_I2C, I2C_FLAG_BUSY))   //判断IIC接口状态.当IIC状态为BUSY时,一直停在这里循环     {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }    /*发送START之后要等待,意味着START条件被正确释放,此时IIC总线上没有其它外设*/     I2C_GenerateSTART( HW_I2C, ENABLE );                                          //产生START条件        while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT))             //判断开始信号是否已经发送完成     {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }    I2C_Send7bitAddress(HW_I2C, ADXL_WRITE, I2C_Direction_Transmitter );          //发送从机地址ADXL_WRITE以选择从机,主机为发送模式     while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))  //如果主机发射模式被选中(死循环等待从机发送ACK信号)     {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }    I2C_SendData(HW_I2C, Read_Address );                                         //将write_address,即要读的地址通过IIC2发送出去    while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))         //如果地址已经从IIC成功发射出去(死循环等待ACK信号   {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }    I2C_GenerateSTART(HW_I2C, ENABLE );                                            //产生START条件     while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT))                //如果主机被选中(死循环等待ACK信号)   {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }    /***主机接收数据***/     I2C_Send7bitAddress(HW_I2C, ADXL_READ, I2C_Direction_Receiver );              //主机设置为接收模式     while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))      //如果主机接收模式被选中(死循环等待ACK信号)    {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }    I2C_AcknowledgeConfig(HW_I2C, DISABLE );                                        //失能IIC的应答状态 NACK     I2C_GenerateSTOP( HW_I2C, ENABLE );                                           //产生STOP条件     while (!(I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)))           //判断数据是否接收完成          {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }    I2C_AcknowledgeConfig(HW_I2C, ENABLE );                                      //再一次使能IIC的应答状态     * Read_Data = I2C_ReceiveData(HW_I2C);                                        //返回IIC接收的数据    return 1; }    /** * @brief  通过I2C接口将数据写入从机指定地址中. * @param  要写入的数据,接收数据的地址; * @retval 1:数据写入成功 0:数据写入失败 */ unsigned char  I2C_Write_Byte(uint8_t Point_Buffer,uint8_t Write_Address) {   unsigned char wait_time_out = wait_time_value;//等待I2C器件响应的延时    while (I2C_GetFlagStatus(HW_I2C, I2C_FLAG_BUSY))   //判断当前I2C接口状态是否为Busy    {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }    I2C_GenerateSTARTHW_I2C, ENABLE );                                          //产生Start信号     while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT))               //判断Start信号是否已经发送   {     if((wait_time_out --) == 0) //延时等待     {         return 0;   //响应超时,返回无效标志     }   }    I2C_Send7bitAddress(HW_I2C, ADXL_WRITE, I2C_Direction_Transmitter );              //发送从机地址以选择从机,主机为发送模式     while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))   //判断发送的地址是否与从机匹配,等待从机发送ACK信号   {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }     I2C_SendData(HW_I2C, Write_Address );                                        //将write_address,即要写的寄存器地址通过IIC发送出去        while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))          //判断数据是否发送完成   {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }    /*往寄存器发送数据data*/     I2C_SendData(HW_I2C, Point_Buffer );     while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))            //判断数据是否发送完成   {     if((wait_time_out --) == 0) //延时等待     {       return 0; //响应超时,返回无效标志     }   }    I2C_GenerateSTOP( HW_I2C, ENABLE );                                           //IIC2产生STOP条件      return 1;//数据写入完成 1 }
 /**   ******************************************************************************   * @file    Hardware_I2C.h    * @author  Ryan Zhao   * @version V1.0.0   * @date    2017-04-27   * @brief   STM32硬件I2C底层驱动.   ******************************************************************************   * @attention   Null   *    ******************************************************************************   */    /*********************I2C 物理层GPIO定义*******************/ #define HW_I2C                           I2C1       //第一组I2C接口 #define HW_I2C_SDA_PIN                   GPIO_Pin_7                #define HW_I2C_SDA_GPIO_PORT             GPIOB                       #define HW_I2C_SCL_PIN                   GPIO_Pin_6                   #define HW_I2C_SCL_GPIO_PORT             GPIOB   #define wait_time_value                  200         //等待I2C器件响应的延时

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!