您的位置:首页 > 其它

I2C—读写EEPROM学习笔记之STM32的I2C库函数

2019-06-11 16:03 567 查看

stm32f10x_i2c.h

typedef struct
{
uint32_t I2C_ClockSpeed;          /*!< Specifies the clock frequency.传输速率
This parameter must be set to a value lower than 400kHz */

uint16_t I2C_Mode;                /*!< Specifies the I2C mode.设置工作模式I2C/SMBUS
This parameter can be a value of @ref I2C_mode */

uint16_t I2C_DutyCycle;           /*!< Specifies the I2C fast mode duty cycle.占空比
This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */

uint16_t I2C_OwnAddress1;         /*!< Specifies the first device own address.自身I2C设备地址
This parameter can be a 7-bit or 10-bit address. */

uint16_t I2C_Ack;                 /*!< Enables or disables the acknowledgement.使能或关闭响应
This parameter can be a value of @ref I2C_acknowledgement */

uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged.指定地址长度
This parameter can be a value of @ref I2C_acknowledged_address */
}I2C_InitTypeDef;

• I2C_ClockSpeed
设置I2C的传输速率,在调用初始化函数时,函数会根据我们输入的数值经过运算后把时钟因子写入到I2C的时钟控制寄存器CCR。而我们写入的这个参数值不得高于400KHz。
实际上由于CCR寄存器不能写入小数类型的时钟因子,影响到SCL的实际频率可能会低于本成员设置的参数值,这时除了通讯稍慢一点以外,不会对I2C的标准通讯造成其它影响。
• I2C_Mode
选择I2C的使用方式,有I2C模式(I2C_Mode_I2C )和SMBus主、从模式(I2C_Mode_SMBusHost、 I2C_Mode_SMBusDevice ) 。
I2C不需要在此处区分主从模式,直接设置I2C_Mode_I2C即可。
• I2C_DutyCycle
设置I2C的SCL线时钟的占空比。该配置有两个选择,分别为低电平时间比高电平时间为2: 1 ( I2C_DutyCycle_2)和16: 9(I2C_DutyCycle_16_9)。
其实这两个模式的比例差别并不大,一般要求都不会如此严格,这里随便选就可以了。
• I2C_OwnAddress1
配置STM32的I2C设备自己的地址,每个连接到I2C总线上的设备都要有一个自己的地址,作为主机也不例外。地址可设置为7位或10位(受下面I2C_AcknowledgeAddress成员决定),只要该地址是I2C总线上唯一的即可。
STM32的I2C外设可同时使用两个地址,即同时对两个地址作出响应,这个结构成员I2C_OwnAddress1配置的是默认的、 OAR1寄存器存储的地址,若需要设置第二个地址寄存器OAR2,可使用I2C_OwnAddress2Config函数来配置, OAR2不支持10位地址。
• I2C_Ack_Enable
配置I2C应答是否使能,设置为使能则可以发送响应信号。 一般配置为允许应答(I2C_Ack_Enable),这是绝大多数遵循I2C标准的设备的通讯要求,改为禁止应答(I2C_Ack_Disable)往往会导致通讯错误。
• I2C_AcknowledgeAddress
选择I2C的寻址模式是7位还是10位地址。这需要根据实际连接到I2C总线上设备的地址进行选择,这个成员的配置也影响到I2C_OwnAddress1成员,只有这里设置成10位模式时,I2C_OwnAddress1才支持10位地址。

配置完这些结构体成员值,调用库函数I2C_Init即可把结构体的配置写入到寄存器中。

其他库函数:

void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)
//产生一个起始条件
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Generate a START condition */
I2Cx->CR1 |= CR1_START_Set;
}
else
{
/* Disable the START condition generation */
I2Cx->CR1 &= CR1_START_Reset;
}
}
FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
//检查flag位,检查I2C工作状态
{
FlagStatus bitstatus = RESET;
__IO uint32_t i2creg = 0, i2cxbase = 0;

/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_I2C_GET_FLAG(I2C_FLAG));

/* Get the I2Cx peripheral base address */
i2cxbase = (uint32_t)I2Cx;

/* Read flag register index */
i2creg = I2C_FLAG >> 28;

/* Get bit[23:0] of the flag */
I2C_FLAG &= FLAG_Mask;

if(i2creg != 0)
{
/* Get the I2Cx SR1 register address */
i2cxbase += 0x14;
}
else
{
/* Flag in I2Cx SR2 Register */
I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);
/* Get the I2Cx SR2 register address */
i2cxbase += 0x18;
}

if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET)
{
/* I2C_FLAG is set */
bitstatus = SET;
}
else
{
/* I2C_FLAG is reset */
bitstatus = RESET;
}

/* Return the I2C_FLAG status */
return  bitstatus;
}
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)
//发送地址7位
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_I2C_DIRECTION(I2C_Direction));
/* Test on the direction to set/reset the read/wri
1f7a6
te bit */
if (I2C_Direction != I2C_Direction_Transmitter)
{
/* Set the address bit0 for read */
Address |= OAR1_ADD0_Set;
}
else
{
/* Reset the address bit0 for write */
Address &= OAR1_ADD0_Reset;
}
/* Send the address */
I2Cx->DR = Address;
}
void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)
//发送数据
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
/* Write in the DR register the data to be sent */
I2Cx->DR = Data;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: