I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。通过串行数据(SDA)线和串行时钟(SCL)在连接到总线的器件间传递信息。每个器件都有一个唯一的地址识别(无论是微控制器——MCU、LCD 驱动器、存储器或键盘接口),而且都可以作为一个发送器或接收器(由器件的功能决定)。LCD 驱动器只能作为接收器,而存储器则既可以接收又可以发送数据。除了发送器和接收器外,器件在执行数据传输时也可以被看作是主机或从机。主机是初始化总线的数据传输并产生允许传输的时钟信号的器件。此时,任何被寻址的器件都被认为是从机。
对于电子爱好者而言,常见的I2C器件中,以LCD液晶屏和存储类器件居多。如0.96英寸的OLED、93C46,24系列存储芯片等。
合宙Air001本身也设计有I2C设备,使用PF1(SCL)和PF0(SDA)两个通用GPIO口的复用功能。如下图所示:
在本次Arduino实验中我们就以0.96英寸的OLED这款常用器件作为从设备测试Air001的I2C设备。为此需要按照以下连线方式搭建电路:
OLED液晶屏 Air001开发板
----------------------------------------------------------------
Vcc 3.3V
Gnd Gnd
SCL PF1
SDA PF0
这里要注意的是OLED的电源,如果你的OLED电源是支持3.3V的,就可以直接接到Air001开发板的3.3V引脚上。这个电源来自计算机的USB的5V输出电压的3.3V转换,因为OLED的功耗低,USB的输出电源足够支撑。电源和地的引脚千万不要接错了,以免烧毁器件。
接下来把开发板接入DapLink下载器以及电脑。启动ArduinoIDE,建立测试工程。在ArduinoIDE中选择Air001对应的开发板和连接端口,在代码区输入以下代码:
#include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // 定义 SCREEN_WIDTH(OLED显示宽度),以像素为单位。 #define SCREEN_HEIGHT 64 // 定义 SCREEN_HEIGHT(OLED显示高度),以像素为单位。 #define OLED_RESET 4 // // 初始化了一个SSD1306型号的显示器,使该显示器具SCREEN_WIDTH和SCREEN_HEIGHT指定的宽度和高度。 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { // 初始化串口波特率 Serial.begin(115200); // 初始化OLED设备 if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 如果连接失败,输出日志 Serial.println("OLED init failed"); // 进入等待状态 while(1); } // 清除OLED显示屏 display.clearDisplay(); // 显示指定的文字 ShowText("Hello!"); } void loop() { static int count = 0; char str[64]; while (1) { delay(2000); // 将整型数据变换为字符串,10进制方式 itoa(count, str, 10); // 串口输出数据 Serial.print("num="); Serial.println(count, DEC); // 显示数据 ShowText(str); // 数据加1 count++; } } // 显示字符串 void ShowText(char *text) { //清空屏幕信息 display.clearDisplay(); //设置文本字体大小为2 display.setTextSize(2); //设置屏幕颜色为白色 display.setTextColor(SSD1306_WHITE); //设置打印的起始坐标10,16 display.setCursor(10, 16); //设置显示的文本信息 display.println(F(text)); //将屏幕缓冲区数据刷到屏幕上,显示出来 display.display(); }
代码检查无误,编译下载,看测试结果:
代码中使用了关联的库,所以代码量很少。如果我们使用GPIO模拟I2C方式,需要处理很多协议上对通讯口线的要求。现在使用了专用的库函数处理,使得I2C的测试变得很轻松。如果希望深入了解I2C的通讯协议,建议找专门的资料学习学习。