Arduino系列教程十一:I2C

来自丢石头百科
Admin讨论 | 贡献2019年11月18日 (一) 16:23的版本 (本章介绍arduino通过I2C控制温度传感器LM75)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)


前面几章我们介绍了如何操作Arduino的IO端口。这一章我们讲解一下Arduino的I2C接口编程。本章以Accessory Shiled扩展板中LM75温度传感器为例。在这里我不算详细介绍LM75芯片,详细信息请查看LM75数据手册。本章示例程序只是简单读取LM75的寄存器并转换为当前温度显示。 前面几章的程序都是写在一个后缀为.ino的工程文件中,而实际应用中这是不可能的,我们的程序通过采用模块化的结构,一个工程包含很多源文件和头文件。例如本章的工程会包含LM75的驱动程序LM75.h,LM75.c;主程序中会调用驱动程序函数读取LM75当前温度。而Arduino IDE是不能创建h文件,c文件编辑的,这非常的不方便。通常Arduino编程会使用Source Insight软件编辑原代码。从网上下载并安装Source Insigh。界面如图:

224130l6eyx6g6cmtce6y6.jpeg

示例程序:LM75.h

#ifndef LM75_h

#define LM75_h

 

#define LM75_ADDRESS 0x48

 

#define LM75_TEMP_REGISTER 0

#define LM75_CONF_REGISTER 1

#define LM75_THYST_REGISTER 2

#define LM75_TOS_REGISTER 3

 

class LM75 {

  public:

    LM75 (unsigned char addr);

    float temp ();

  private:

unsigned char address;

};

 

#endif

  示例程序:LM75.c

#include "Arduino.h"

#include <Wire.h>

#include "LM75.h"

 

LM75::LM75 (unsigned char addr){

  address = addr;

}

 

float LM75::temp () {

  word regdata;

  Wire.beginTransmission(address);

  Wire.write(LM75_TEMP_REGISTER);

  Wire.endTransmission();

  

  Wire.requestFrom(address, 2);

  regdata = (Wire.read() << 8) | Wire.read();

  return ((float)(regdata >> 5)) * 0.125;

}


  示例程序:LM75.ino

#include <Wire.h>

#include <LM75.h>

 

LM75 sensor(LM75_ADDRESS);

void setup (void){

  Serial.begin(9600);

  Wire.begin();

}

 

void loop() {

  Serial.print("Current temp: ");

  Serial.print(sensor.temp());

  Serial.println(" C");

  delay(1000);

}


  程序分析: LM75.h 头文件中先define宏定义LM75的I2C地址和寄存器地址。然后定义类class LM75,类是C++等面向对象语言的概念。LM75类中包含公有成员和私有成员。public表示公有成员,变量和函数可以被外部访问,例如temp函数在主程序中调用。private表示私有成员,只能被内部访问,例如address是内部变量不能被外部使用,只能是LM75类内部的函数能够使用。 LM75.c 驱动源文件中包含Arduino头文件Arduino.h和I2C库的头文件Wire.h。驱动源文件中包含两个函数LM75::LM75 (unsigned char addr),float LM75::temp ();注意第一个函数是没有返回类型的,而且函数名和类名一样。这是类的初始化函数,当类被示例的时候会调试此函数。如主程序中LM75 sensor(LM75_ADDRESS);实例一个LM75的类为sensor,此时就会调用LM75::LM75 (unsigned char addr)函数。函数前面有LM75::表示这个函数属于LM75类的函数。 Wire.beginTransmission(address); 这个函数表示启动I2C传输,address为要传输的I2C设备地址。 Wire.write(LM75_TEMP_REGISTER); 传输寄存器地址到LM75 Wire.endTransmission(); 结束I2C输传输,发送结束信号,释放I2C总线。 Wire.requestFrom(address, 2); 请求结束两个字节数据 Wire.read(); I2C接收数据函数 LM75.ino 工程主文件中,包含LM75驱动头文件LM75.h和I2C库的头文件Wire.h。程序开始实例一个LM75类名为sensor,此致会调用LM75初始化函数LM75::LM75 (unsigned char addr)。将LM75私有变化address初始化。Setup()函数中调用Serial.begin(9600)初始化串口,波特率为9600,调用Wire.begin()初始化I2C。 sensor.temp() 这个是指实例LM75类sensor调用类LM75的temp函数读取当前温度。   把附加中的文件放在arduino目录的librarys文件中,重启Arduino IDE。选择File->Examples->LM75->LM75打开工程,编译并上传,打开串口监视器。等待一会儿就是每隔一点显示当前温度值。  

224337p819g75jjxaqlxua.jpeg