同步: 共用一个时钟信号进行数据传输。 如一个时钟周期信号可进行收发一位数据.
即按已约定好的方式进行工作,工作开始前不需要再发出通知信号
异步: 工作开始前需要再发出通知信号。 没有共用时钟信号,收发两端都有自己的时钟信号(uart: tx, rx, gnd, cts, rts)
中断是异步的
//
主机(master): 发起操作方,一般是i2c控制器
从机(slave): 被操作方,一般是芯片设备
i2c是一种电路接口,可接I2C接口的芯片设备. 飞利普公司发明的.
i2c接口由两根线组成,一根数据线(SDA), 一根时钟线(SCL)
SCL, SDA这两根线需接上拉。默认处于高电平状态
开始信号: SCL高电平状态, SDA下降沿. 此信号由主机发出, 表示传输的开始.
停止信号: SCL高电平状态, SDA上升沿. 此信号由主机发出, 表示传输的结束.
i2c的接口可并接多个I2C设备,在同一接口上的每个设备都有一个不同的设备地址. 每次读写数据时需要指定所操作的设备地址. 而且通常情况下,应一个传输过程中只访问一个设备.
I2C的设备地址(一般是7位), 注意读写位不能算是地址位.
//
I2C传输以8位为一个单位,传输8位后,应由接收方回一个应答
i2c的传输协议:
上图背景是白色的表示是从主机发出的
背景是黑色的表示是从机发出的
Write Mode:
主机先发出开始信号, 接着发出8位数据(由7位设备地址和一位读写位), 读写位的值为0。 同一I2C接口的所有设备都会接收到设备地址,会与自身的地址进行比较,如果地址是一样,则由匹配的设备回应答信号.
如果没有设备匹配设备地址,则没有应答信号. 主机收到应答信号后,再发出8位数据, 从机收到数据应回应答,表示已收到数据。主机如需再发数据,则在接收到应答信号后,再发出8位数据…最后发出停止信号
Read Mode:
主机先发出开始信号, 接着发出8位数据(由7位设备地址和一位读写位), 读写位的值为1. 从机匹配上后,回应答信号, 从机再输入8位数据, 主机接收数据后,如需再接收数据,则应回应答信号给从机. 从机收到应答信号后,再发出8位数据…最后主机发出停止信号.
//注意: 主机发出设备地址,读写位后,发出数据. 这个数据可以是多个字节,而且数据可表示其它不同的用途,不单单只是数值. 例如, i2c接口的eeprom的写操作,主机除了设备地址、读写位外还需发出两个字节数据。第一个数据表示要写到eeprom的第几个字节位置, 第二个数据表示要存放的数值
//
SCL一个时钟周期, SDA传输一位数据
I2C波特率: 100KHz(标准模式), 400KHz(高速模式)
I2C是半双工传输方式
SCL拉成低电平可以暂停传输
/
下面代码是在cc2530里操作i2c接口的lcd屏的代码,可通过代码了解下具体的i2c协议
//此屏不用发设备地址, 也不用管应答信号,直接发数据就可以了
#define LCD_SCL P1_2 // SCL
#define LCD_SDA P1_3 // SDA
void LCD_WrDat(unsigned char dat) //发出8位数据
{
unsigned char i=8, temp=0;
LCD_DC=1;
for(i=0;i<8;i++) //每次发出一位数据, 共8位
{
LCD_SCL=0; //时钟线低电平
temp = dat&0x80; // I2C是从数据的最高位开始发出的,这里是取出数据的最高位的值
if (temp == 0)
{
LCD_SDA = 0; //如发出的值是0, 则SDA拉成低电平
}
else
{
LCD_SDA = 1; //如发出的值是1, 则SDA拉成高电平
}
LCD_SCL=1; //SCL拉成高电平。SCL是低电平时准备数据, 真正发出数据是在高电平时(也就是接收方是在上升沿后判断SDA的电平来接收数据的)
dat<<=1; //这里是丢弃已传输的最高位数据
}
}
在低端的SOC里,通常是由代码来控制IO的电平来实现I2C协议.
在高端点的SOC里,通常会有i2c控制器(一个专门根据i2c协议自动控制io口电平的硬件). 发数据时,我们只需把数据提交到控制器,由控制器负责控制io口电平来发出。接收数据时,由控制器负责根据SCL的时钟信号来判断SDA的电平,存储数据。我们只需从控制器里取回数据即可。