极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 32834|回复: 30

Arduino教程 - I2C模块的使用 - 集成DS1307时钟芯片、AT24C32存储芯片、LM75温度侦测

  [复制链接]
发表于 2013-9-4 21:34:41 | 显示全部楼层 |阅读模式
本帖最后由 sbsdys 于 2013-9-4 22:28 编辑

本站内有一篇类似的文章,用的是淘宝上很常见的一个I2C模块,帖子地址:
http://www.geek-workshop.com/thread-207-1-1.html

下面再介绍一个新的I2C模块,区别于刚提到的那个帖子,这个模块使用了新的库,令开发更加简单,并且最新集成了使用I2C总线的LM75温度传感器芯片,而不是使用大家常见的DS18B20。

本帖中所要用到的所有资料(包括库文件、源代码、芯片数据手册等):
I2C模块教程文件.zip (2.36 MB, 下载次数: 2048)
回复

使用道具 举报

发表于 2013-9-4 21:50:38 | 显示全部楼层
谢谢 sbsdys。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-4 21:59:32 | 显示全部楼层
二、外部存储:AT24C32存储芯片的使用

AT24C32提供32768位的串行电可擦写可编程只读存储器,组织形式为4096字×8位字长。AT24C32的级联特性允许在同一I2C总线上挂接8个器件,百万次的复写周期和100年的保存年限,并带有写保护功能。

接线图(和RTC DS1307的接法一样):
arduino I2C-final.jpg

运行Arduino IDE,打开以下文件:
35.png

可以在Arduino IDE中看到以下代码:

  1. #include <Wire.h>
  2. #include <AT24Cxx.h>
  3. #include <RTClib.h>

  4. AT24Cxx AT24C32(0x50);
  5. RTC_DS1307 RTC;

  6. void setup (void){
  7.   //初始化串口
  8.   Serial.begin(9600);
  9.   //初始化I2C
  10.   Wire.begin();
  11.   //初始化RTC
  12.   RTC.begin();

  13. }

  14. void loop() {
  15.   //判断是否有新串口数据
  16.   if (Serial.available() > 0) {
  17.     //读取数据
  18.     int instruct = Serial.read();

  19.     switch (instruct) {
  20.     case 'P':
  21.       {
  22.         //先eeprom 指定地址写入数据
  23.         AT24C32.WriteMem(0, 0x04);
  24.         break;
  25.       }
  26.     case 'G':
  27.       {
  28.         char buffer[3];
  29.         //读取三个字节数据
  30.         AT24C32.ReadMem(0, buffer, 3);
  31.         Serial.print(2000 + buffer[2], DEC);
  32.         Serial.print('/');
  33.         Serial.print(buffer[1], DEC);
  34.         Serial.print('/');
  35.         Serial.print(buffer[0], DEC);
  36.         Serial.println();
  37.         break;
  38.       }
  39.     case 'F':
  40.       {
  41.         //获取当前时间信息
  42.         DateTime now = RTC.now();
  43.         char buffer[3];
  44.         buffer[0] = now.day();
  45.         buffer[1] = now.month();
  46.         buffer[2] = now.year() - 2000;
  47.         //写入时间信息到eeprom
  48.         AT24C32.WriteMem(0, buffer, 3);
  49.         break;
  50.       }
  51.     }
  52.   }
  53. }
复制代码


打开串口监控器,当输入字符“F”时,串口窗口不会有任何反应,但Arduino会把年、月、日信息储存到EEPROM;输入字符“G”,则会把存储的年、月、日信息读取出来。复位Arduino后再次输入字符“G”,仍能把一样的信息读取出来,说明数据没有丢失。
输入字符“P”,再输入字符“G”,可以看到日期被强制设定为4号
36.jpg

下面我们来看一下代码:

#include <Wire.h>#include <AT24Cxx.h>

当设备要使用I2C总线时,必须包含Wire.h 这个文件。而AT24Cxx.h 则是AT24Cxx 系列通用的头文件。

AT24Cxx AT24C32(0x50);

创建一个AT24Cxx 实例,而0x50则是AT24C32的地址,上面介绍AT24C32 时提到这款芯片可以在I2C总线上挂接8个器件,那么我们如何区分开来这八个器件呢? AT24C32又是如何知道哪些数据是发给自己而不是别的总线上的器件呢?
                              
原来,AT24C32上还配备了三个地址选定管脚,A2、A1、A0。而高四位的地址已经固定为1010,A2、A1、A0三个地址脚的连接方式分别决定了后3位的数值。I2C模块上的AT24C32的A2、A1、A0 都接到了地,所以得出的7位地址为101 0000,写成16进制的话为0x50。

char buffer[3];
buffer[0] = now.day();
buffer[1] = now.month();
buffer[2] = now.year() - 2000;
AT24C32.WriteMem(0, buffer, 3);

这几行的代码的意思是把年、月、日信息写到EEPROM上,我们首先看WriteMem 这个方法,它是专门用来写(保存)数据到EEPROM的,它接收三个参数,第一个是地址,EEPROM内部是通过地址来区分数据存储位置的,例如AT24C32,它具有4096字×8位字长的存储能力,则地址范围则是0 - 4096。这里第一个参数设的是“0”,他可以更改为0 - 4096中的任意一个数。第二个参数为需要写到存储器的数据块的开头地址,注意不是数据本身,而是数据的地址,比较容易理解的实现方式是声明一个数组,然后把数组名作为这个参数(数组名则为该数据块的起始地址)。最后一个参数是要写入的字节数,它不能大于数据块的大小(即数组的大小)。

AT24C32.WriteMem(0, 0x04);

这行代码的意思是把一字节的数据(0x04)写到EEPROM的地址为0的空间上,这里大家会发现这个方法的名字跟前面的一模一样,这是面向对象编程中一个叫重载的特性,这项特性允许创建函数名称相同但功能的输入输出类型不同的子程序,当你只要存储一个字节的数据时比较方便。

char buffer[3];AT24C32.ReadMem(0, buffer, 3);

这两行代码的意思是从EEPROM上读取三个字节的数据,并保存到缓冲数组上。ReadMem这个方法是专门把数据从EEPROM上读取出来。它接收三个参数,第一个是地址,第二个是缓冲块的开头地址(数组名),最后一个参数是要读取的字节数,它不能大于缓冲数据块的大小(即数组的大小)。

第二部分到此结束:-)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-4 22:11:45 | 显示全部楼层
三、温度侦测芯片LM75的使用

LM75是一款十分常用的温度侦测器件。它能够提供0.125℃的精度,多种温度范围选择,并提供过温输出接口。它使用I2C总线进行通讯,配合自身的地址选择,可以在同一总线上挂接8个设备。

接线图:
arduino I2C-final-lm75.jpg
这里比之前要多接一根线,用来侦测LM75的温度报警输出。

运行Arduino IDE,打开以下文件:
38.jpg

可以在Arduino IDE中看到以下代码:

  1. #include <Wire.h>
  2. #include <LM75.h>

  3. LM75 sensor(LM75_ADDRESS | 0b000);
  4. const int OSPIN = 6;

  5. void setup (void){
  6.   //设置OS管脚为输入
  7.   pinMode(OSPIN, INPUT);
  8.   //初始化串口
  9.   Serial.begin(9600);
  10.   //初始化I2C
  11.   Wire.begin();
  12.   //设置报警温度
  13.   sensor.tos(47.5);
  14.   //设置迟滞温度
  15.   sensor.thyst(42);

  16. }

  17. void loop() {
  18.   //判断是否有新串口数据
  19.   if (Serial.available() > 0) {
  20.     //读取数据
  21.     int instruct = Serial.read();
  22.     int OSValue = HIGH;
  23.     //读取OS管脚电平
  24.     OSValue = digitalRead(OSPIN);
  25.     //如果OS管脚为低电平
  26.     if (OSValue == LOW)
  27.         //返回报警
  28.         Serial.println("Over heating!");

  29.     switch (instruct) {
  30.     case 'T':
  31.       Serial.print("Current temp: ");
  32.       //返回当前温度
  33.       Serial.print(sensor.temp());
  34.       Serial.println(" C");
  35.       break;
  36.     }
  37.   }
  38. }
复制代码


打开串口监控器,当输入字符“T”时,则会返回当前的环境温度值,当温度超过47.5°时,串口将会返回 "Over heating!" 的警告。
39.jpg

下面我们来看一下代码:

#include <LM75.h>

此为LM75系类通用的库文件。

LM75 sensor(LM75_ADDRESS | 0b000);

与AT24C32 类似,LM75 可以通过设置自身的的A2、A1、A0三个地址管脚来区分总线是否在与自己通讯,而高4 位的地址已经固定,我们的芯片上三个地址脚都接到了GND,所以为0b000。

pinMode(OSPIN,INPUT);

这行代码的意思是把OSPIN管脚(Pin 6),设置成输入,我们在第2章时,把LED管脚设成输出,用的是同样的函数,只是参数不一样,第2章用的是输出,这一章用的是输入,即INPUT。

sensor.tos(47.5);
sensor.thyst(42);

这两行代码的意思是设置报警温度(TOS)和滞回温度(THYST). 通过设置这两个温度,可以设定一个区间,使得当环境温度超过47.5℃时,LM75 的OS管脚将会输出一个低电平,当环境温度降至42℃以下时,这个管脚则会恢复高电平。注意,当温度一旦超过47.5°,则在它降至42°前,管脚是一直维持低电平的。

OSValue = digitalRead(OSPIN);

这行代码的意思是读取OSPIN管脚的电平值。digitalRead 使用来读取管脚电平的函数,它的作用刚好与digitalWrite 相反,后者用来输出电平。digitalRead函数只会返回两种类型的值: HIGH,表示高电平;LOW,表示低电平。


sensor.temp()

这行代码的意思是获取当前的温度。temp() 是sensor实例的一个方法,调用它即可返回当前的摄氏温度值。


到这里,模块上集成的三个功能的使用方法分享完毕,谢谢大家的围观{:soso_e113:}

回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-4 22:30:17 | 显示全部楼层
szpapas 发表于 2013-9-4 21:50
谢谢 sbsdys。

谢谢顶贴
回复 支持 反对

使用道具 举报

发表于 2013-9-5 08:16:26 | 显示全部楼层
怎么感觉 又像广告呢?
回复 支持 反对

使用道具 举报

发表于 2013-9-5 08:35:45 | 显示全部楼层
Cupid 发表于 2013-9-5 08:16
怎么感觉 又像广告呢?

恩,是有点像
但是,可以学到点东西
回复 支持 反对

使用道具 举报

发表于 2013-9-5 08:58:41 | 显示全部楼层
有图有代码有接线,广告也无妨啦
回复 支持 反对

使用道具 举报

发表于 2013-9-5 11:00:44 | 显示全部楼层
{:soso_e113:}技术贴广告还是很欢迎的。。。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-5 11:05:37 | 显示全部楼层
弘毅 发表于 2013-9-5 11:00
技术贴广告还是很欢迎的。。。

谢谢啦,欢迎大家一起交流
回复 支持 反对

使用道具 举报

发表于 2013-9-5 15:56:37 | 显示全部楼层
不错,介绍得很详细,初学者也可以看明白。支持。这个模块有没有购买链接啊?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-5 22:07:00 | 显示全部楼层
philhoo 发表于 2013-9-5 15:56
不错,介绍得很详细,初学者也可以看明白。支持。这个模块有没有购买链接啊?

在淘宝搜索“I2C模块”就可以找到啦,目前只有这个模块集成了使用I2C总线的温度侦测芯片哦。
回复 支持 反对

使用道具 举报

发表于 2013-9-5 23:39:15 | 显示全部楼层
个人赞成这种技术广告贴,起码能学习到一些东西
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-6 10:26:23 | 显示全部楼层
chqiyi 发表于 2013-9-5 23:39
个人赞成这种技术广告贴,起码能学习到一些东西

谢谢顶贴,本帖无意加入广告,欢迎交流:-)
回复 支持 反对

使用道具 举报

发表于 2013-11-11 09:43:00 | 显示全部楼层
请问那个ds1307的库可以提供一下么?
回复 支持 反对

使用道具 举报

高级模式  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2018-10-17 09:14 , Processed in 0.071909 second(s), 8 queries , File On.

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表