树莓派系列教程16:RTC

树莓派本身没有RTC功能,若树莓派不联网则无法从网络获取正确时间,Pioneer 600扩展板上面带有高精度RTC时钟DS3231芯片,可解决这个问题。

一、配置RTC

1、 修改配置文件

1sudo vi /boot/config.txt

添加RTC设备ds3231

1dtoverlay=i2c-rtc,ds3231

重启树莓派生效设置,开机后可以运行lsmod命令查看时候有rtc-1307模块。

(注:ds3231i2c控制,故应打开树莓派I2C功能)

2、 读取RTC时钟,

1sudo hwclock –r

读取系统时间

1date

3、 设置RTC时间

1sudo hwclock –set –date=”2015/08/12 18:00:00”

4、 更新RTC时间到系统

1sudo hwclock -s

5、 读取RTC时间及系统时间

1sudo hwclock –r;date


二、编程控制

我们也可以通过I2C编程读写RTC时间,运行i2cdetect y 1命令我们可以看到下图,我们发现ds3231i2c地址0x68的位置显示UU,此时ds3231作为树莓派的硬件时钟,不能通过i2c编程控制,必须将刚才配置文件中的设置注释掉才能用。

1sudo vi /boot/config.txt

找到刚才的设置,在前面加#注释掉

1#dtoverlay=i2c-rtc,ds3231

重启后再运行i2cdetect y 1此时发现ds3231可以通过i2c编程控制

1、bcm2835

01#include <bcm2835.h>
02#include <stdio.h>
03#include <unistd.h>
04 
05//regaddr,seconds,minutes,hours,weekdays,days,months,yeas
06char  buf[]={0x00,0x00,0x00,0x18,0x04,0x12,0x08,0x15};
07char  *str[]  ={"SUN","Mon","Tues","Wed","Thur","Fri","Sat"};
08void pcf8563SetTime()
09{
10    bcm2835_i2c_write(buf,8);
11}
12 
13void pcf8563ReadTime()
14{  
15    buf[0] = 0x00; 
16    bcm2835_i2c_write_read_rs(buf ,1, buf,7); 
17}
18 
19int main(int argc, char **argv) 
20
21    if (!bcm2835_init())return 1; 
22    bcm2835_i2c_begin(); 
23    bcm2835_i2c_setSlaveAddress(0x68); 
24    bcm2835_i2c_set_baudrate(10000); 
25    printf("start..........\n");
26     
27    pcf8563SetTime();
28    while(1) 
29    {  
30        pcf8563ReadTime();
31        buf[0] = buf[0]&0x7F; //sec
32        buf[1] = buf[1]&0x7F; //min
33        buf[2] = buf[2]&0x3F; //hour
34        buf[3] = buf[3]&0x07; //week
35        buf[4] = buf[4]&0x3F; //day
36        buf[5] = buf[5]&0x1F; //mouth
37        //year/month/day
38        printf("20%02x/%02x/%02x  ",buf[6],buf[5],buf[4]);
39        //hour:minute/second
40        printf("%02x:%02x:%02x  ",buf[2],buf[1],buf[0]);
41        //weekday
42        printf("%s\n",str[(unsigned char)buf[3]-1]);
43        bcm2835_delay(1000);
44    }
45 
46    bcm2835_i2c_end();
47    bcm2835_close();
48 
49    return 0;
50}

编译并执行

1gcc –Wall ds3231.c –o ds3231 –lbcm2835
2sudo ./ds3231



2、python

01#!/usr/bin/python
02# -*- coding: utf-8 -*-
03import smbus
04import time
05 
06address = 0x68
07register = 0x00
08#sec min hour week day mout year
09NowTime = [0x00,0x00,0x18,0x04,0x12,0x08,0x15]
10w  = ["SUN","Mon","Tues","Wed","Thur","Fri","Sat"];
11#/dev/i2c-1
12bus = smbus.SMBus(1)
13def ds3231SetTime():
14    bus.write_i2c_block_data(address,register,NowTime)
15 
16def ds3231ReadTime():
17    return bus.read_i2c_block_data(address,register,7);
18 
19ds3231SetTime()
20while 1:
21    t = ds3231ReadTime()
22    t[0] = t[0]&0x7F  #sec
23    t[1] = t[1]&0x7F  #min
24    t[2] = t[2]&0x3F  #hour
25    t[3] = t[3]&0x07  #week
26    t[4] = t[4]&0x3F  #day
27    t[5] = t[5]&0x1F  #mouth
28    print("20%x/%x/%x %x:%x:%x  %s" %(t[6],t[5],t[4],t[2],t[1],t[0],w[t[3]-1]))
29time.sleep(1)

执行程序

1sudo python ds3231.py