如果光看AT24C02的文档,很抽象,难弄懂。结合程序和实际通讯波形;来描述。
- 购买回来默认是接GND的,所以安装上AT24C02芯片后地址就是:0xA0
#includeIIC通讯讲解 要想硬件之间建立通讯,需要知道对方的地址。// 使用Wire库,需要包含头文件 const int16_t I2C_ADDR = 0x50; // AT24C02的IIC器件地址0x50,这个地址可以通过I2C扫描程序搜索到。 #define button 7 bool buttonState = true; uint8_t at24c02_write(char data_wr, uint8_t WriteAddr) { Wire.beginTransmission(I2C_ADDR); Wire.write(WriteAddr); Wire.write(data_wr); return Wire.endTransmission(); } uint8_t at24c02_read(char *data_wr, uint8_t ReadAddr) { uint8_t t = 200; uint8_t ret = 0; Wire.beginTransmission(I2C_ADDR); Wire.write(ReadAddr); ret = Wire.endTransmission(false); Wire.requestFrom(I2C_ADDR, 1); while (!Wire.available()) { t--; delay(1); if(t == 0) { return 1; } } *data_wr= Wire.read(); // receive a byte as character return ret; } void setup() { Serial.begin(115200); digitalWrite(LED_BUILTIN, LOW);//板子led,作为观察数据发射状态 pinMode(button,INPUT); digitalWrite(button,HIGH); Wire.begin(); } void loop() { buttonState = digitalRead(button); if(buttonState == LOW){ delay(250); if(buttonState == LOW){ char str0 = 'H'; uint8_t Write = at24c02_write(str0, 0); Serial.println("Trigger!!!"); Serial.println(Write); digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); delay(2000); // char*str2; // uint8_t Read = at24c02_read(str2,0); // Serial.println(*str2);Serial.println(Read); } } }
就像打电话,打电话前,你必须知道对方的电话号码才行。
- 确定访问AT24C02的硬件地址(AT24C02手册)
代码上面定义AT24C02的硬件信息填写:
const int16_t I2C_ADDR = 0x50;// AT24C02的IIC器件地址0x50,这个地址可以通过
为什么是0x50的16进制这个地址而不是1010 0000的16进制0xA0呢?
解析:如果CPU读设备,那么读设备地址 = 设备地址 <<1.所以,0x50左移移位就变成了0xA01
- 源码函数
C:UsersAdministratorAppDataLocalArduino15packagesarduinohardwareavr1.8.3librariesWiresrcutility
void twi_setAddress(uint8_t address) { // set twi slave address (skip over TWGCE bit) TWAR = address << 1; }
- 原理图1,将A2,A1,A0都接GND,那么自定义的地址位就都是000,加上第八位确定读写位,如果是读就是1,写就是0,本实例演示的是写数据,那就是确定要写,那么就是0,所以地址就是1010 0000,转换为16进制就是0xA0
- 示波器捕获到单片机和AT24C02通讯时的波形,紫色代表SDA,黄色代表SCL
对应代码:
Wire.beginTransmission(I2C_ADDR);
- 如果你想挂载8个AT24C02器件,可以根据以下来连接,各器件IIC地址:0x50 - 0x57
下面的AT24C02的地址,只适用于Arduino 平台开发时使用,才对应的上,移位底层函数在封装的时候,会将这个地址左移移一位,具体看上面的原函数,这一点刚刚开始也让我很困惑,当查看原函数的时候,才发现原因。
- 根据A2,A1,A0,不同的组合,我们可以确定一条总线上可以挂载多少个AT24C02,从而不会导致地址重复或者冲突。最多挂载8个:
有道翻译:
设备/页地址(A2、A1和A0): A2、A1和A0引脚是设备地址输入 它们是AT24C02的硬线。8个2K设备可以在一个总线系统上寻址 (设备寻址将在设备寻址部分详细讨论)。 AT24C04使用A2和A1输入进行硬线寻址,总共有4个4K设备 在一个单一的总线系统上被处理。A0引脚是无连接的,可以连接到GND。 AT24C08只使用A2输入进行硬线寻址,总共有两个8K设备 在一个单一的总线系统上寻址。A0和A1引脚没有连接,可以连接 GND。 AT24C16不使用设备地址引脚,这限制了总线上单个设备的数量 。A0、A1和A2引脚没有连接,可以连接到地。第二阶段,写数据地址位。
就比如送快递,将物品送入到某个小区单元还不够,你还要知道具体到,某个单元里的某一栋的门牌号,也就是具体到存储的地址位。
Wire.write(WriteAddr);第三阶段,将具体的数据写入到地址位中去,才算完成。
Wire.write(data_wr);
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)