51模拟I2c,原理+程序
2016-07-29 22:48
323 查看
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) //ÑÓ³Ù9us { 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); //ÑÓ³ÙÖÁÉÙ4.7us SDA=0; delay(1); //±£³Öʱ¼ä>4us SCL=0; delay(1); } void I2c_stop() { SDA=0; delay(1); SCL=1; delay(1); //ÑÓ³ÙÖÁÉÙ4.7us 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。
相关文章推荐
- 智慧短信项目笔记1
- 仿QQ5.5登陆框
- Android图片缓存之Lru算法(二)
- 注解实现Bean依赖注入
- JS 代码编一个倒时器
- replace的用法
- Android Permission整理
- [USACO Training] Section 1.1
- 23中设计模式之单例(Singleton)模式
- python基础-列表,文件,运算符
- hive中partition如何使用
- Android ndk socket客户端
- POJ 1751 Highways (最小生成树)
- 自动测试-仪器
- 2016第31周五
- 【剑指offer】替换空格
- indexOf的用法
- 『.NET Core CLI工具文档』(八)dotnet-restore
- 『.NET Core CLI工具文档』(八)dotnet-restore
- 实现电话自动拨打、挂断