查看I2C 总线精要的源代码
←
I2C 总线精要
跳转到:
导航
,
搜索
因为以下原因,你没有权限编辑本页:
您刚才请求的操作只有这个用户组中的用户才能使用:
用户
您可以查看并复制此页面的源代码:
== 软件模拟 == To initialize the ports set the output resisters to 0 and the tristate registers to 1 which disables the outputs and allows them to be pulled high by the resistors. The following 4 functions provide the primitive start, stop, read and write sequences. All I2C transactions can be built up from these. <source lang=cpp> #define I2C_DELAY 4 /* us delay */ #define I2C_MAXWAIT 5000 #define TWI_SDA 11 /* PIN14_PD7 */ #define TWI_SCL 16 /* PIN21_PF2 */ #define SDA_LOW() digitalWrite(TWI_SDA, LOW) #define SDA_HIGH() digitalWrite(TWI_SDA, HIGH) #define SCL_LOW() digitalWrite(TWI_SCL, LOW) #define SCL_HIGH() digitalWrite(TWI_SCL, HIGH) #define SDA_READ() digitalRead(TWI_SDA) #define SCL_READ() digitalRead(TWI_SCL) #define i2c_delay() delayMicroseconds(4) void i2c_start(void) { SDA_HIGH(); // i2c start bit sequence i2c_delay(); SCL_HIGH(); i2c_delay(); SDA_LOW(); i2c_delay(); SCL_LOW(); i2c_delay(); } void i2c_stop(void) { SDA_LOW(); // i2c stop bit sequence i2c_delay(); SCL_HIGH(); i2c_delay(); SDA_HIGH(); i2c_delay(); } uint8_t i2c_rx(uint8_t ack) { uint8_t x, d = 0; SDA_HIGH(); for (x = 0; x < 8; x++) { d <<= 1; do { SCL_HIGH(); } while (SCL_IN == 0); // wait for any SCL clock stretching i2c_delay(); if (SDA_READ()) d |= 1; SCL_LOW(); } if (ack) SDA_LOW(); else SDA_HIGH(); SCL_HIGH(); i2c_delay(); // send (N)ACK bit SCL_LOW(); SDA_HIGH(); return d; } uint8_t i2c_tx(unsigned uint8_t d) { uint8_t x; static uint8_t b; for (x = 8; x; x--) { if (d & 0x80) SDA_HIGH(); else SDA_LOW(); SCL_HIGH(); d <<= 1; SCL_LOW(); } SDA_HIGH(); SCL_HIGH(); i2c_delay(); b = SDA_READ(); // possible ACK bit SCL_LOW(); return b; } </source> ;使用示例: The 4 primitive functions above can easily be put together to form complete I2C transactions. Here's and example to start an SRF08 ranging in cm: <source lang=cpp> i2c_start(); // send start sequence i2c_tx(0xE0); // SRF08 I2C address with R/W bit clear i2c_tx(0x00); // SRF08 command register address i2c_tx(0x51); // command to start ranging in cm i2c_stop(); // send stop sequence </source> Now after waiting 65mS for the ranging to complete (I've left that to you) the following example shows how to read the light sensor value from register 1 and the range result from registers 2 & 3. <source lang=cpp> i2c_start(); // send start sequence i2c_tx(0xE0); // SRF08 I2C address with R/W bit clear i2c_tx(0x01); // SRF08 light sensor register address i2c_start(); // send a restart sequence i2c_tx(0xE1); // SRF08 I2C address with R/W bit set lightsensor = i2c_rx(1); // get light sensor and send acknowledge. Internal register address will increment automatically. rangehigh = i2c_rx(1); // get the high byte of the range and send acknowledge. rangelow = i2c_rx(0); // get low byte of the range - note we don't acknowledge the last byte. i2c_stop(); // send stop sequence </source> <br><br>
返回到
I2C 总线精要
。
个人工具
登录
名字空间
页面
讨论
变换
查看
阅读
查看源代码
查看历史
操作
搜索
导航
首页
社区专页
新闻动态
最近更改
随机页面
帮助
工具箱
链入页面
相关更改
特殊页面