STM32 具有 IIC 接口,接口有以下主要特性
 
多主机功能:该模块既可做主设备也可做从设备
 
主设备功能
 
C 地址检测
 
产生和检测 7 位 /10 位地址和广播呼叫
 
支持不同的通讯速度
 
状态标志:
 
发送器 / 接收器模式标志
 
字节发送结束标志
 
总线忙标志
 
错误标志
 
2 个中断向量
 
可选的拉长时钟功能
 
具单字节缓冲器的 DMA
 
虽然很多人说 STM 的硬件 IIC 不好用,但是对于这么一个设备去探索一下还是很有必要的,指不定哪天就用上了呢,
 
IIC 借口一共有九个寄存器,比较重要的几个寄存器分别如下
 
1.CR1
 
 
 
由这几个位我们可以正常产生标准 IIC 的 START 条件 STOP 条件,ACK 与 NOACK
 
CR2
 
 
控制 IIC 的通行频率
 
这两位检测 IIC 总线是否收到数据
 
 
1. 对于硬件 IIC 的初始化流程包括
 
1. 配置 IO 口,配置为 GPIO_Mode_AF_OD 模式
 
2. 选择 IIC 模式
 
3. 选择是否使能自动应答以及设备地址长度
 
4. 设置 IIC 总线的传输速率
 
2. 硬件 IIC 的读写操作其实逻辑上和标准总线类似,也是发送地址等待 ack 发送数据等待 ACK,但是因为有硬件的自动参与,所以我们不需要延时了
 
具体代码如下
 
voidHmcIICInit(void)
 
{
 
/*GPIO 初始化*/
 
GPIO_InitTypeDefGPIO_InitStructure;
 
/*配置硬件 IIC 需要的变量*/
 
I2C_InitTypeDefI2C_InitStructure;
 
/*使能与 I2C1 有关的时钟*/
 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
 
/*PB6-I2C1_SCL、PB7-I2C1_SDA*/
 
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
 
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
 
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD;
 
GPIO_Init(GPIOB,&GPIO_InitStructure);
 
/*IIC 外设初始化*/
 
/*I2C 配置*/
 
I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;// 配置为普通 IIC 模式
 
//I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
 
//I2C_InitStructure.I2C_OwnAddress1=SlaveAddress;
 
I2C_InitStructure.I2C_Ack=I2C_Ack_Enable;// 使能自动应答
 
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
 
I2C_InitStructure.I2C_ClockSpeed=50000;//5K 的速度?
 
/*I2C1 初始化*/
 
I2C_Init(I2C1,&I2C_InitStructure);
 
/*使能 I2C1*/
 
I2C_Cmd(I2C1,ENABLE);
 
/*允许应答模式*/
 
I2C_AcknowledgeConfig(I2C1,ENABLE);
 
}
 
voidHmcByteWrite(u8addr,u8dataValue)
 
{
 
I2C_GenerateSTART(I2C1,ENABLE);
 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
 
I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Transmitter);
 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 
I2C_SendData(I2C1,addr);
 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
I2C_SendData(I2C1,dataValue);
 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
I2C_GenerateSTOP(I2C1,ENABLE);
 
}
 
u8HmcByteRead(u8addr)
 
{
 
u8dataValue;
 
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
 
I2C_GenerateSTART(I2C1,ENABLE);// 起始信号
 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
 
I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_DirecTIon_Transmitter);// 发送设备地址+写信号
 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//
 
I2C_Cmd(I2C1,ENABLE);
 
I2C_SendData(I2C1,addr);// 发送存储单元地址,从 0 开始
 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
I2C_GenerateSTART(I2C1,ENABLE);// 起始信号
 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
 
I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_DirecTIon_Receiver);// 发送设备地址+读信号
 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
 
I2C_AcknowledgeConfig(I2C1,DISABLE);
 
I2C_GenerateSTOP(I2C1,ENABLE);
 
while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)));
 
dataValue=I2C_ReceiveData(I2C1);// 读出寄存器数据
 
returndataValue;
 
}