基础知识
概述
- 半双工,任意时刻只能单向通信
- 支持多主控,谁控制 SCL 谁就是主机
- SCL 和 SDA 均需要上拉电压,阻值 3.3K ~ 10K
信号线分类
时序图
-
写数据
-
读数据
数据有效性
- IIC信号在数据传输过程中,当 SCL 为高电平时,数据线 SDA 必须保持稳定状态,不允许有电平跳变
- SCL = 1 时,数据线 SDA 的任何电平变换会看做是总线的起始信号或者停止信号
应答信号
主机SCL拉高,读取从机SDA的电平,为低电平表示产生应答
- 应答信号为低电平时,规定为有效应答位(ACK),表示接收器已经成功地接收了该字节
- 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功
伪代码
void IIC_init(){
SCL=1;
delay_us(4);
SDA=1;
delay_us(4);
}
void IIC_Start(){
SDA=1;
delay_us(5);
SCL=1;
delay_us(5);
SDA=0;
delay_us(5);
}
void IIC_Stop(void){
IIC_SCL=0;
IIC_SDA=0;
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;
delay_us(4);
}
void I2C_Ack(void){
IIC_SCL=0;
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(5);
IIC_SCL=0;
}
void I2C_NAck(void){
IIC_SCL=0;
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(5);
IIC_SCL=0;
}
void IIC_Send_Byte(u8 txd){
u8 t;
SDA_OUT();
IIC_SCL=0;
for(t = 0; t < 8; t++){
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
u8 IIC_Read_Byte(unsigned char ack){
unsigned char i, receive=0;
SDA_IN();
for(i = 0;i < 8; i++ ){
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();
else
IIC_Ack();
return receive;
}
API
HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c,
uint16_t DevAddress,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c,
uint16_t DevAddress,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c,
uint16_t DevAddress,
uint16_t MemAddress,
uint16_t MemAddSize,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c,
uint16_t DevAddress,
uint16_t MemAddress,
uint16_t MemAddSize,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
Demo
-
通过 STM32Cube 配置 IIC
- Master Features
- I2C Speed Mode:快速模式/标准模式
- I2C Clock Speed:选择传输速率,默认为 100Khz
- Slave Features
- Clock No Stretch Mode:时钟拓展模式,大多数设备不支持
- Primary?Address?Length?selection:从设备地址长度,大部分为7位
- Dual?Address?Acknowledged:双地址确认
- Primary?slave?address:从设备初始地址
-
参考 API
|