1、I2c启动
由上图可知SDA在SCL为高电平时由高变为低表示启动I2c,注意时间。
2、I2c关闭
由上图可知SDA在SCL为高电平时由低变为高表示启动I2c,注意时间。
3、数据0
由上图可知SDA在SCL为高电平时拉低表示0,注意时间。
4、数据1
由上图可知SDA在SCL为高电平时拉高表示0,注意时间。
5、I2c写数据(数据由51到设备)
由上图可以看书写数据的步骤为:1)启动I2c;
2)写入设备地址(七位设备地址加一位读写命令,最后1为读,0为写);
3)等待应答(由设备发出,读数据时由51给应答),这一步可以和第二部写在一个函数中;
4)写入数据要存放的地址;
5)等待应答;
6)写入数据;
7)等待应答;
8)关闭I2c。
若将等待应答与写数据放在一个函数中可简化为:1)启动I2c;
2)写入设备地址
3)写入数据要存放的地址;
4)写入数据;
5)关闭I2c。
6、I2c读数据(51从设备中读取数据)
由上图可以看书写数据的步骤为:1)启动I2c;
2)写入设备地址;
3)写入要读取数据存放的地址;
4)启动I2c;
5)写入设备地址(第八位为1,表示读数据);
6)读数据;
7)给设备发送应答信号;
8)关闭I2c;
7、对应的51程序
- #include <STC12C5A60S2.H>
- #define uchar unsigned char
- #define uint unsigned int
-
- sbit SCL=P2^1;
- sbit SDA=P2^0;
- uchar code duan[]=
- {
- 0xfc,0x60,0xda,
- 0xf2,0x66,0xb6,
- 0xbe,0xe0,0xfe,0xf6
- };
- void delay(uint time)
- {
- uint i,j;
- for(i=0;i<time;i++)
- for(j=0;j<10;j++);
- }
- void I2c_start()
- {
- SDA=1;
- delay(1);
- SCL=1;
- delay(1);
- SDA=0;
- delay(1);
- SCL=0;
- delay(1);
- }
- void I2c_stop()
- {
- SDA=0;
- delay(1);
- SCL=1;
- delay(1);
- SDA=1;
- delay(1);
- }
- //·¢Ëíack
- void I2c_sendAck(bit ack)
- {
- SDA = ack;
- SCL = 1;
- delay(1);
- SCL = 0;
- delay(1);
-
- }
- //»ñè¡ack
- bit I2c_getAck(void)
- {
- bit ack;
- SDA = 1;
- SCL = 1;
- delay(1);
- ack = SDA;
- SCL = 0;
- return ack;
- }
- uchar I2c_read()
- {
- uchar i,dat=0;
- SDA=1;
- delay(1);
- for(i=0;i<8;i++)
- {
- SCL=1;
- delay(1);
- dat<<=1;
- dat|=SDA;
- delay(1);
- SCL=0;
- }
- return dat;
- }
- void I2c_write(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- SDA=dat>>7;
- dat<<=1;
- delay(1);
- SCL=1;
- delay(1);
- SCL=0;
- delay(1);
- }
- I2c_getAck();
- }
- void I2c_toDevice(uchar deviceAdd,uchar datAdd,uchar dat)
- {
- I2c_start();
- I2c_write(deviceAdd);
- I2c_write(datAdd);
- I2c_write(dat);
- I2c_stop();
- }
- uchar I2c_fromDevice(uchar deviceAdd,uchar datAdd )
- {
- uchar dat;
- I2c_start();
- I2c_write(deviceAdd);
- I2c_write(datAdd);
- I2c_start();
- I2c_write(deviceAdd+1);
- dat=I2c_read();
- I2c_sendAck(1);
- I2c_stop();
- return dat;
- }
- void main()
- {
- uchar num;
- I2c_toDevice(0xa0,3,7);
- delay(130);
- num=I2c_fromDevice(0xa0,3);
- while(1)
- {
- P0=0x00;
- P1=duan[num];
- delay(10);
- P1=0x00;
- }
- }
复制代码
8、注意事项
1)关闭I2c和启动I2c之间要有1ms间隔,给IO口准备时间,否则乱码。
2)关于应答,当写数据时由设备应答,读数据时MCU应答。
3)读数据时启动两次I2c。
|