总结IIC协议学习心得_学习心得
总结IIC协议学习心得由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“学习心得”。
无论在51或者stm32的学习中,我们都会使用到IIC总线的数据传送,从当初51到现在的stm32的学习。iic一直都是只会简单的使用并未很仔细的去研究中间每一个过程或者时序。今天用了一天的时间去理解IIC。当然这都是建立在以往的学习经验之中而得。一下都是我自己的一些理解和对照程序而写的一些IIC的使用过程。
iic总线时序理解:
24C04 引脚: NC(1)VCC(8)A1(2)WP(7)A2(3)SCL(6)GBD(4)SDA(5)注:SCL 设置start信号和stop信号,由于此时是STM32对24c02发送信号,所以SCL和SDA设置为输出状态,即:SDA_OUT();由时序图可知:
START:SCL=1,SDA=1,delay(),SDA=0,delay(),SCL=0,//时钟线为高,数据线从高到低的跳变 STOP :SCL=0,SDA=0,delay(),SCL=1,delay(),SDA=1,//时钟线为高,数据线从低到高的跳变 STM32程序: void IIC_Start(void){ SDA_OUT();//sda线输出 IIC_SDA=1;IIC_SCL=1;delay_us(4);IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4);IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 } void IIC_Stop(void){ SDA_OUT();//sda线输出 IIC_SCL=0;IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay_us(4);IIC_SCL=1;IIC_SDA=1;//发送I2C总线结束信号 delay_us(4);} iic每成功传送完一个字节后,接收器都必须产生一个应答信号,应答器件在第九个时钟周期讲SDA拉低,表示已经接
收到8位,此时对于24c02有两种可能的工作方式,第一种是24c02工作于读,另一种则是工作于写。
@当工作于读的方式时,SDA为输入状态,即:SDA_IN();此时24c02发送完一个8位数据之后,释放SDA线,将SDA为输出
状态,即:SDA_OUT();并等待stm32发送一个应答信号,若接收到应答信号,则SDA又切换为输入状态,即:SDA_IN();然后继续发送下一个8位数据;若没有接受到应答信号,则不切换SDA的工作方式。等待STM32发送停止信号。
@当工作于写的方式时,则在每接收一个8位字节之后响应一个应答信号。由时序图可知:
产生应答信号:SCL=0;SDA_OUT();SDA=0,delay(),SCL=1,delay(),SCL=1;STM32程序:
void IIC_Ack(void)//产生ACK应答 { IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;} void IIC_NAck(void)//不产生ACK应答 { IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;} 当iic发送一个起始信号或者是发送一个写操作时,我们必须要做出应答,因此便设计了应答查询程序。目的 是为了查询某一个操作以后通过是否应答来继续下一步的操作。
应答程序主要是对SDA的读操作,所以在读之前必须设置SDA为输入状态,即:SDA_IN();STM32程序: u8 IIC_Wait_Ack(void){ u8 ucErrTime=0;SDA_IN();IIC_SDA=1;delay_us(1);IIC_SCL=1;delay_us(1);while(READ_SDA){ ucErrTime;if(ucErrTime>250){ IIC_Stop();return 1;} } IIC_SCL=0;//时钟输出0
return 0;} 设置write信号,由于此时是STM32对24c02的发送信号,所以SCL和SDA设置为输出状态,即:SDA_OUT();由时序图可知:
write:在SCL跳变时,对SDA赋值即位写数据,只需主要在一个周期内,SDA不许有电平变化,否则会认 为是开启或停止信号。STM32程序:
void IIC_Send_Byte(u8 txd){ u8 t;SDA_OUT();IIC_SCL=0;//拉低时钟开始数据传输 for(t=0;t>7)IIC_SDA=1;else IIC_SDA=0;txd
Read:在8个SCL周期内,读取8个SDA的输入,就可以知道一个字节的数据。要弄清楚的很,在发送完 之后弄清楚是否需要应答。STM32程序:
u8 IIC_Read_Byte(unsigned char ack){ unsigned char i,receive=0;SDA_IN();//SDA设置为输入 for(i=0;i
} if(!ack)IIC_NAck();//发送nACK else IIC_Ack();//发送ACK return receive;s } 我们必须要知道芯片的器件地址:我用的是24C04: 1 0 1 0 A2 A1 a8 R/W(1/0)
A0 A1和A2对应器件的管脚1 2和3 a8 a9和a10对应存储阵列地址字地址 弄清楚完整数据读/写过程:
起始信号->发送地址->读/写->应答->数据->应答->数据->应答->终止信号 STM32程序:
//在AT24CXX指定地址读出一个数据 //ReadAddr:开始读数的地址 //返回值 :读到的数据
u8 AT24CXX_ReadOneByte(u16 ReadAddr){ u8 temp=0;IIC_Start();IIC_Send_Byte(0XA0((ReadAddr/256)
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite){ IIC_Start();IIC_Send_Byte(0XA0((WriteAddr/256)
IIC_Stop();//产生一个停止条件 delay_ms(10);}