#define BSP_I2C_H
#include "BSP_I2C.h"
/********************************************************************************************************
函数名 : I2C_Configuration
描述 : I2C初始化
输入参数: 无
********************************************************************************************************/
void I2C_Configuration()
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 ,ENABLE); //打开I2C2时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE); //使能管脚时钟和复用时钟
GPIO_InitStructure.GPIO_Pin=(GPIO_Pin_6 | GPIO_Pin_7); //SCL和SDA
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD; //SCL和SDA开漏输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //输出速率50M
GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化
GPIO_InitStructure.GPIO_Pin=(GPIO_Pin_5); //读写控制脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //读写脚推免输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //输出速率50M
GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化
EEPROM_Protect_Disenable; //关闭写保护,不然无法写入参数
I2C_InitStructure.I2C_Mode=I2C_Mode_I2C; //选用I2C模式
I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2; //传输占空比2:1
I2C_InitStructure.I2C_ClockSpeed=I2C_Speed; //E方传输速率
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit; //7位寻址模式
I2C_InitStructure.I2C_OwnAddress1=EEPROM_Adress; //外部存储器地址
I2C_InitStructure.I2C_Ack=I2C_Ack_Enable; //应答使能
I2C_Init(I2C1,&I2C_InitStructure); //I2C参数初始化
I2C_Cmd(I2C1,ENABLE); //使能I2C
}
/********************************************************************************************************
函数名 : I2C_Write_Byte
描述 : 向指定地址写一个字节
输入参数: 需要写入数据的地址,写入的数据
********************************************************************************************************/
void I2C_Write_Byte(uint16_t Adress,uint8_t Data)
{
I2C_GenerateSTART(I2C1,ENABLE); //起始信号
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS ); //检测EV5事件
I2C_Send7bitAddress(I2C1,EEPROM_Adress,I2C_Direction_Transmitter); //发送设备地址和写指令
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS );//检测EV6事件
I2C_SendData(I2C1,Adress>>8); //发送需要写入存储器地址的高8位
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS ); //等待应答
I2C_SendData(I2C1,Adress); //发送需要写入存储器地址的低8位
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS ); //等待应答
I2C_SendData(I2C1,Data); //写入数据
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS ); //等待应答
I2C_GenerateSTOP(I2C1,ENABLE); //停止信号
Systick_Delayms(15); //两次写之间需要有间隔
}
/********************************************************************************************************
函数名 : I2C_Wait
描述 : 等待外部存储器写入完毕,相当于检测总线是否处于繁忙状态
输入参数: 无
********************************************************************************************************/
void I2C_Wait(void)
{
do
{
I2C_GenerateSTART(I2C1,ENABLE); //起始信号
I2C_Send7bitAddress(I2C1,EEPROM_Adress,I2C_Direction_Transmitter); //发送设备地址
}while(I2C_GetFlagStatus(I2C1,I2C_FLAG_ADDR) == RESET); //等待地址发送完毕
I2C_ClearFlag(I2C1,I2C_FLAG_AF); //清除应答失败标志
I2C_GenerateSTOP(I2C1,ENABLE); //发送停止信号
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY) == SET); //等待总线不繁忙
}
/********************************************************************************************************
函数名 : I2C_Read_Byte
描述 : 从指定地址读一个字节数据
输入参数: 指定读取的地址
********************************************************************************************************/
uint8_t I2C_Read_Byte(uint16_t Adress)
{
uint8_t Data;
I2C_Wait();
I2C_GenerateSTART(I2C1,ENABLE); //起始信号
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS ); //检测EV5事件
I2C_Send7bitAddress(I2C1,EEPROM_Adress,I2C_Direction_Transmitter); //发送设备地址和写指令
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS );//检测EV6事件
I2C_SendData(I2C1,Adress>>8); //发送需要读取数据的存储器地址的高8位
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS ); //检测EV8-2事件
I2C_SendData(I2C1,Adress); //发送需要读取数据的存储器地址的低8位
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS ); //检测EV8-2事件
I2C_GenerateSTART(I2C1,ENABLE); //起始信号
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS ); //检测EV5事件
I2C_Send7bitAddress(I2C1,EEPROM_Adress,I2C_Direction_Receiver); //发送设备地址和读指令
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) != SUCCESS); //检测EV6事件
I2C_AcknowledgeConfig(I2C1,DISABLE); //终止使能应答
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED) != SUCCESS); //检测EV7事件
Data=I2C_ReceiveData(I2C1); //读取数据
I2C_GenerateSTOP(I2C1,ENABLE); //停止信号
return(Data); //返回接收到的数据
}
/********************************************************************************************************
函数名 : I2C_Write_Word
描述 : 向指定地址写一个字
输入参数: 需要写入数据的地址,写入的数据
********************************************************************************************************/
void I2C_Write_Word(uint16_t Adress,uint16_t Data)
{
I2C_Write_Byte(Adress,Data>>8); //写数据高8位
I2C_Write_Byte(Adress+1,Data); //写数据低8位,注意地址要后移1位,不然会覆盖之前的数据
}
/****************************************************************