由于之前Arduino UNO(ATmega328P)板子的SDA和SCL的错位,才导致了这篇文章的出现。
原理图在此:
| 实际 | SDA | SCL | --> | 我的 | SDA | SCL |
|---|---|---|---|---|---|---|
| - | A4(PC4) | A5(PC5) | --> | - | A3(PC3) | A4(PC4) |
画原理图的时候没注意,一不留神就错位了,导致现在不得不使用软件I2C来与DS3231来通信。
不过还好,国外已有大神写好了软件I2C的库在这里


但是DS3231的库使用的是硬件I2C,需要移植一下,好在Bernhard的软件I2C很好的适配了原硬件I2C的Wire库,移植只需做上图的前三个步骤便可以了,很是方便。
需要注意的是:
1.他的软件I2C库中的函数全部写在了.h头文件中,这样直接移植(只做以上三步)会导致文件被重复包含,从而导致函数重复被定义的错误,需要对SoftI2CMaster.h进行适当的修改即可。
2.在SoftI2CMaster.h文件中的函数定义前加上 inline 关键字即可解决重复定义的问题,也可以新建一个SoftI2CMaster.c文件,将SoftI2CMaster.h中的函数写到SoftI2CMaster.c中去,这样也可以解决。
3.DS3231库函数的修改,这部分改动也较小。建议先把DS3231整个库文件复制出来,方便修改。
在DS3231.h头文件中,替换#include<Wire.h>为#include<SoftWire.h>,
在头文件之前,先加入SCL_PIN,SDA_PIN,SCL_PORTX,SDA_PORTX相关的宏定义,不能在头文件之后加入,否则可能会报错,修改后的DS3231.h头文件部分如下:
#define SCL_PIN 4 //correspond with arduino IO instead of the avr chip pin.
#define SCL_PORT PORTC //the port of the pin
#define SDA_PIN 3
#define SDA_PORT PORTC
#include <SoftWire.h>
//#include <Wire.h>
4.接着需要在DS3231.c文件中实例化一个 SoftWire类,如下:
SoftWire Wire = SoftWire();
这样移植工作就做完了。
但需要注意的是,在编写Arduino的.ino文件时,需要对I2C初始化,这时候需要对SoftWire实例化的类进行申明,如下:
extern SoftWire Wire;
至此,整个软件I2C移植过程就完成了。
已经修改好了的文件可从下面地址下载:
1.修改后的软件I2C文件下载地址:SoftI2CMaster_Add_inline
2.修改后的DS3231文件下载地址:DS3231WithSoftI2C
注:
1.原SoftI2CMaster库制作者在此:SoftI2CMaster
2.原DS3231库文件是从Arduino IDE中下载的。