`

rtc驱动

 
阅读更多

一、PCF8563
摘要:
PCF8563是PLILIPS公司生产的低功耗CMOS实时时钟/日历芯片,文中介绍了PCF8563的结构、功能及工作原理。结合其在8051系统中的应用实例,给出了PCF8563与8051单片机的硬件接口电路和C语言软件编程程序,再结合linux简单讲解一下,先结全51不跑操作系统,让读者对硬件有个好的理解,后面再结合操作系统,让各位对操作系统和整个流程有个清楚的认识。

1 PCF8563简介

PCF8563是PHILIPS公司生产的低功耗CMOS实时时钟/日历芯片,芯片最大总线速度为400kbits/s,每次读写数据后,其内嵌的字地址寄存器器会自动产生增量。PCF8563可广泛应用于移动电话、便携仪器、传真机、电池电源等产品中。

PCF8563的引脚排列如图1所示,各引脚功能说明如表1所列。rtc驱动 - areyoulate - areyoulate的博客

PCF8563有16个8位寄存器,其中包括:可自动增量的地址寄存器、内置32.768kHz的振荡器(带有一个内部集成电容)、分频器(用于给实时时钟RTC提供源时钟)、可编程时钟输出、定时器、报警器、掉电检测器和400kHz的I2C总线接口。

所有16个寄存器设计成可寻址的8位并行寄存器,但不是所有位都有用。当一个RTC寄存器被读时,所有计数器的内容将被锁存,因此,在传送条件下,可以禁止对时钟/日历芯片的错读。

表2、表3所列为各寄存器概况及对应的内存地址和功能,同时列出了它们的BCD格式编码。表中“——”表示无效位,“0”表示此位应置逻辑。表3中的世纪位C=0指定世纪数为20XX,C=1指定世纪数为19XX。当年寄存器中的99变00时,世纪位才会改变。

表1 PCF8563的管脚描述

符 号 管脚号

描 述

OSCI 1 振荡器输入
OSCO 2 振荡器输出
INT 3 终端输出(开漏:低电平有效)
Vss 4
SDA 5 串行数据I/O
SCL 6 串行时钟输入
CLKOUT 7 时钟输出(开漏)
VDD 8 正电源

2 I2C总线

2.1 I2C总线特性

I2C 总线用两条线(SDA和SCL)在芯片和模块间传递信息。SDA为串行数据线,SCL为串行时钟线,这两条线必须用一个上拉电阻与正电源相连,其数据只有在总线不忙时才可传送。I2C总线的系统配置参见图2,产生信号的设备是传送器,接收信号的设备是接收器,控制信号的设备是主设备,受控制信号的设备是从设备。

表2 寄存器概况

地址 寄存器名称 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
00H 控制/状态寄存器1 TEST 0 STOP 0 TESTC 0 0 0
01H 控制/状态寄存器2 0 0 0 TI/TP AF TF AIE TIE
0DH CLKOUT频率寄存器 FE FD1 FD0
0EH 定时器控制寄存器 TE TD1 TD0
0FH 定时器倒计数数值寄存器 定时器倒计数数值

表3 BCD格式寄存器概况

地 址 寄存器名称 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
01H VL 00~59BCD码格式数
03H 分钟 - 00~59BCD码格式数
04H 小时 - - 00~23BCD码格式数
05H - - 01~31BCD码格式数
06H 星期 - - - - - 0~6
07H 月/世纪 C - - 01~12BCD码格式数
08H 00~99BCD码格式数
09H 分钟报警 AE 00~59BCD码格式数
0AH 小时报警 AE - 00~23BCD码格式数
0BH 日报警 AE - 01~31BCD码格式数
0CH 星期报警 AE - - - - 0~6

2.2 启动和停止条件

总线不忙时,数据线和时钟线保持在高电平。数据线(SDA)在下降沿而时钟线(SCL)为高电平时,为起动条件(S);数据线在上升沿而时钟线为高电平时为停止条件(P),参见图3。

2.3 位传送

每个时钟脉冲传送一个数据位,SDA线上的数据在时钟脉冲高电平时应保持稳定,否则将成为控制信号,参见图4。rtc驱动 - areyoulate - areyoulate的博客

2.4 标志位

在起动条件和停止条件之间,传送器传送给接收器的数据数量没有限制。在每个8位字节后加一个标志位,传送器便产生一个高电平的标志位,这时主设备产生一个附加标志位时钟脉冲。

从接受器必须在接收到每个字节后产生一个标志位,主接收器也必须在接收从传送器传送的每个字节后产生一个标志位。在标志位时钟脉冲出现时,SDA线应保持低电平(应考虑起动和保持时间)。传送器应在从设备接收到最后一个字节时变为低电平,而使接收器产生标志位,这时主设备即可产生停止条件。参见图5。

2.5 I2C总线协议

用I2C 总线传递数据前,接收的设备应先标明地址,在I2C总线起动后,这个地址与第一个传送字节一起被传送出去。PCF8563可以作为一个从接收器或从传送器,此时的时钟信号线SCL只能输入信号线,数据信号线SDA则为一条双向信号线。PCF8563的从地址参见图6。

3 应用概述

图7所示为PCF8563的具体应用电路图,对图中石英晶片频率的调整,笔者给出3种可行性方法,供参考:rtc驱动 - areyoulate - areyoulate的博客

方法1:定值OSCI电容。计算所需的电容平均值,用此值的定值电容,通电后在CLKOUT管脚上测出的频率应为32.768kHz,测出的频率值偏差取决于石英晶片本身,电容偏差和器件之间的偏差平均为±5×10 -6。平均偏差可达5分钟/年。

方法2:OSCI微调电容。可通过调整OSCI管脚的微调电容式振荡器的频率来获得更高的精度,此时可测出通电时管脚CLKOUT上的信号频率为32.768kHz。

方法3:OSCI输出。直接测量管脚OSCI的输出。

4 程序范例

以下的C语言源程序是用8051单片机的普通I/O口(如P0.0/P0.4)模拟实现 PCF8563的I2C时钟/日历芯片的操作,有字节写/读两种状态。程序中从地址的读地址为0A3H,写地址为0A2H.所发送的数据字节为9个,发送的初始数据在rom_sed[9]中,rom_sed[9]定义了寄存器中当前发送的值:控制/状态寄存器1为0,控制/状态寄存器2为0,秒寄存器为 0,分钟寄存器55,小时寄存器为23,日寄存器为31,星期寄存器为6,月/世纪寄存器为0x12,年寄存器为0x99(即1999年12月31日23 点55分0秒),当程序运行一段时间(5分钟)后,从地址寄存器 02H开始读数据,数据存放在rom_rec7中,发现变量rom_rec7变为2000年1月1日0点0分。若外转帐电路有显示,则时间可以显示在面板上。

#include<d:.h>

#define byte unsigned char

sbit scl=0x81; //定义串行I/O口

sbit sda=0x80;rtc驱动 - areyoulate - areyoulate的博客

idata byte rom_sed[9];

idata byte rom_rec[7];

idata byte j,k;

bit flag,flag1;

void delay(void) //延时子程序

{data byte i;

for(i=0;i<6;i++);

}

void I_start(void) //发送I2C总线起始条件子程序

{sda=1;

;

scl=1;

delay();

sda=0;

delay();

scl=0;

;

}

void I_stop(void) //I2C总线停止条件子程序

{sda=0;

;rtc驱动 - areyoulate - areyoulate的博客

scl=1;

delay();

sda=1;

delay();

}

bit I_send(byte I_data) //字节数据传送子程序

{data byte i;

for(i=0,i<8;i++)

{sda-(bit)(I_data&0x80);

I_data=I_data<<1;

;

scl=1;

delay();

scl=0;

}

;;

sda=1; ;; //ready for receiving ACK bit

scl=1; ;; //start receiving ack bit

flag=0;

if(sda= =0)flag=0;

else flag=1; //return(~I_clock());

scl=0;rtc驱动 - areyoulate - areyoulate的博客

return(flag);

}

byte I_receive(void) //字节数据接收子程序

{ data byte i;

byte I_data=0;

sda=1;

for(i=0;I<8;i++)

{ I_data*=2;

;

scl=0;

delay();

scl=1; ;;

if(sda= =1)I_data++;

;;

}

scl=0; ;;;

sda=0;

if(flag1= =0){;;scl=1;delay();scl=0;} //not last receic_byte ACK

else{sda=1; ;;scl=1;delay();scl=0;flag1=0;} //the last receive_byte ~ACK

return(I_data);

}

main() //主程序

{data byte i;

rom_sed[0]=0x00; rom_sed[1]=0x00;

rom_sed[2]=0x00; rom_sed[3]=0x55;

rom_sed[4]=0x23; rom_sed[5]=0x31;

rom_sed[6]=0x06; rom_sed[7]=0x92;

rom_sed[8]=0x99;

for(i=0;i<255;i++)delay();

I_start();

if(~I_send(rom_sed[i]));

else;rtc驱动 - areyoulate - areyoulate的博客

}

I_stop();

}

else;

}

else;

start: I_start();

if(~I_send(0xa2)) //pcf_write address

{if(~I_send(0x02)) //pcf_status register address

{I_start();

if(~I_send(0xa3)) //write status register

{for(i=0;i<7;i++)

{if(i= =6)flag1=1;

else flag1=0;

rom_rec[i]=I_receive();

switch(i)

{case 1:rom_rec[i]=rom_rec[i]&0x7f;break;

ease2:

case3:rom_rec[i]=rom_rec[i]&0x3f;break;

case4:rom_rec[i]=rom_rec[i]&0x07;break;

case5:rom_rec[i]=rom_rec[i]&0x9f;brealk;default:break;

}

}

I_stop()

}

}

}

goto start;

}

二、DS12C887

简要介绍了美国 DALLAS 公司的新型时钟日历芯片 DS12C887 的功能特性
和内部控制寄存器参数,给出了 DS12C887 与 8031 单片机的电路连接图,同时给
出了用 C51 编写的初始化程序和获取内部时间的程序。
1 器件特性
DS12C887 实时时钟芯片功能丰富,可
以用来直接代替 IBM PC 上的时钟日历芯片
DS12887,同时,它的管脚也和
MC146818B、DS12887 相兼容。
由于 DS12C887 能够自动产生世纪、
年、月、日、时、分、秒等时间信息,其内
部又增加了世纪寄存器,从而利用硬件电路
解决子“千年”问题;DS12C887 中自带有锂电
池,外部掉电时,其内部时间信息还能够保
持 10 年之久;对于一天内的时间记录,有
12 小时制和 24 小时制两种模式。在 12 小时
制模式中,用 AM 和 PM 区分上午和下午;
时间的表示方法也有两种,一种用二进制数
表示,一种是用 BCD 码表示;DS12C887 中
带有 128 字节 RAM,其中有 11 字节 RAM
用来存储时间信息,4 字节 RAM 用来存储
DS12C887 的控制信息,称为控制寄存器,
113 字节通用 RAM 使用户使用;此外用户还
可对 DS12C887 进行编程以实现多种方波输
出,并可对其内部的三路中断通过软件进行
屏蔽。

2 引脚功能
DS12C887 的引脚排列如图 1 所示,各管脚的功能说明如下:
GND、VCC:直流电源,其中 VCC 接+5V 输入,GND 接地,当 VCC 输入为+5V 时,用
户可以访问 DS12C887 内 RAM 中的数据,并可对其进行读、写操作;当 VCC 的输入小于
+4.25V 时,禁止用户对内部 RAM 进行读、写操作,此时用户不能正确获取芯片内的时间信
息;当 VCC 的输入小于+3V 时,DS12C887 会自动将电源发换到内部自带的锂电池上,以保证
内部的电路能够正常工作。
MOT:模式选择脚,DA12C887 有两种工作模式,即 Motorola 模式和 Intel 模式,当 MOT
接 VCC 时,选用的工作模式是 Motorola 模式,当 MOT 接 GND 时,选用的是 Intel 模式。本
文主要讨论 Intel 模式。
SQW:方波输出脚,当供电电压 VCC 大于 4.25V 时,SQW 脚可进行方波输出,此时用
户可以通过对控制寄存器编程来得到 13 种方波信号的输出。
AD0~AD7:复用地址数据总线,该总线采用时分复用技术,在总线周期的前半部分,出
现在 AD0~AD7 上的是地址信息,可用以选通 DS12C887 内的 RAM,总线周期的后半部分出
现在 AD0~AD7 上的数据信息。
AS:地址选通输入脚,在进行读写操作时,AS 的上升沿将 AD0~AD7 上出现的地址信
息锁存到 DS12C887 上,而下一个下降沿清除 AD0~AD7 上的地址信息,不论是否有效,
DS12C887 都将执行该操作。
DS/RD:数据选择或读输入脚,该引脚有两种工作模式,当 MOT 接 VCC 时,选用
Motorola 工作模式,在这种工作模式中,每个总线周期的后一部分的 DS 为高电平,被称为数
据选通。在读操作中,DS 的上升沿使 DS12C887 将内部数据送往总线 AD0~AD7 上,以供外
部读取。在写操作中,DS 的下降沿将使总线 AD0~AD7 上的数据锁存在 DS12C887 中;当
MOT 接 GND 时,选用 Intel 工作模式,在该模式中,该引脚是读允许输入脚,即 Read
Enable。
R/W:读/写输入端,该管脚也有 2 种工作模式,当 MOT 接 VCC 时,R/W 工作在
Motorola 模式。此时,该引脚的作用是区分进行的是读操作还是写操作,当 R/W 为高电平时
为读操作,R/W 为低电平时为写操作;当 MOT 接 GND 时,该脚工作在 Intle 模式,此时该作
为写允许输入,即 Write Enable。
CS:片选输入,低电平有效。
IRQ:中断请求输入,低电平有效,该脚有效对 DS12C887 内的时钟、日历和 RAM 中的
内容没有任何影响,仅对内部的控制寄存器有影响,在典型的应用中,RESET 可以直接接
VCC,这样可以保证 DS12C887 在掉电时,其内部控制寄存器不受影响。
在 DS12C887 内有 11 字节 RAM 用来存储时间信息,4 字节用来存储控制信息,其具体垢
地址及取值如表 1 所列。
由表 1 可以看出:DS12C887 内部有控制寄存器的 A-B 等 4 个控制寄存器,用户都可以在
任何时候对其进行访问以对 DS12C887 进行控制操作。
表 1 DS12C887 的存储功能
取值范围
地 址 功 能 取值范围十进制数
二进制 BCD 码

0 0~59 00~3B 00~59
秒闹铃
1 0~59 00~3B 00~59

2 059 00~3B 00~59
分闹铃
3 0~59 00~3B 00~59
01~0C AM, 01~12AM,
12 小时模式 0~12
81~8C PM 81~92PM
4
24 小时模式 0~23 00~17 00~23
01~0C AM, 01~12AM,
时闹铃,12 小时制 1~12
81~8C PM 81~92PM
5
时闹铃,24 小时制 0~23 00~17 00~23
星期几(星期天=1)
6 1~7 01~07 01~07

7 1~31 01~1F 01~31

8 1~12 01~0C 01~12

9 0~99 00~63 00~99
控制寄存器 A
10
控制寄存器 B
11
控制寄存器 C
12
控制寄存器 D
13
世纪
50 NA
0~99 19,20
3 应用
在各种设备、家电、仪器、工业控制系统中,可以很容易地用 DS12C887 来组成时间获取
单元,以实现各种时间的获取。图 2 是用 8031 单片机和 DS12C887 构成的时间获取电路图,
其中 DS12C887 的基地址为 7F00H,相应的程序采用 C51 语言编写(以 Intel 工作模式为
例)。
由 8031 单片机和 DS12C887 构
成的时间获取电路的初始化程序如
下:
XBYTE[0x7F00+0x0B]=0x82;
XBYTE[0x7F00+0x0A]=0xA0;
XBYTE[0x7F00+0x0A]=0x20;
XBYTE[0x7F00+0x0B]=0x02;
/*所有的中断禁止,24 小时制,
BCD 码模式*/
以下均获取时间程序:
unsigned char data t-century;
unsigned char data t-year;
unsigned char data t-month;
unsigned char data t-date;
unsigned char data t-week;
unsigned char data t-hour;
unsigned char data t-minute;
unsigned char data t-second;
if((XBYTE[7F00+0x0A]&0x80)!=0){
t-century=XBYTE[0x7F00+0x32];/*读取世纪*/
t-year=XBYTE[Ox7F00+0x09];/*读取年份*/
t-month=XBYTE[Ox7F00+0x08];/*读取月份*/
t-date=XBYTE[Ox7F00+0x07];/*读取日期*/
t-week=XBYTE[Ox7F00+0x06];/*读取星期几*/
t-hour=XBYTE[Ox7F00+0x04];/*读取小时*/
t-minute=XBYTE[DS12887+0x02];/*读取分钟*/
t-second=XBYTE[Ox7F00+0x00];}/*读取秒*/

三、linux下的驱动

module_init(pcf8563_init);

354 static int __init pcf8563_init(void)
355 {
356 return i2c_add_driver(&pcf8563_driver);
357 }
265 static struct i2c_driver pcf8563_driver = {
266 .driver = {
267 .name = "pcf8563",
268 },
269 .id = I2C_DRIVERID_PCF8563,
270 .attach_adapter = &pcf8563_attach,
271 .detach_client = &pcf8563_detach,
272 };
260 static int pcf8563_attach(struct i2c_adapter *adapter)
261 {
262 return i2c_probe(adapter, &addr_data, pcf8563_probe);
263 }
245 static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
246 {
247 return pcf8563_get_datetime(to_i2c_client(dev), tm);
248 }
249
250 static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
251 {
252 return pcf8563_set_datetime(to_i2c_client(dev), tm);
253 }
254
255 static const struct rtc_class_ops pcf8563_rtc_ops = {
256 .read_time = pcf8563_rtc_read_time,
257 .set_time = pcf8563_rtc_set_time,
258 };
259

分享到:
评论

相关推荐

    s3c2410的rtc驱动的实现.doc

    《深入解析s3c2410的RTC驱动实现》 在嵌入式Linux系统中,RTC(Real Time Clock)实时时钟驱动是至关重要的组件,它为系统提供了精确的时间同步和计时功能。s3c2410是一款基于ARM920T内核的微处理器,广泛应用于...

    2.6.23_rtc驱动解读

    在Linux内核版本2.6.23中,RTC驱动进行了诸多改进和优化,使得它更加稳定和高效。本文将深入探讨2.6.23 RTC驱动的设计原理、功能特性以及相关的编程接口。 RTC驱动的主要职责是与系统硬件时钟进行通信,获取当前...

    linux RTC驱动资料

    RTC驱动在Linux内核中扮演着至关重要的角色,因为它涉及到系统的定时器、日历功能以及各种时间相关的服务。本资料包将深入探讨Linux RTC驱动的原理、结构和开发。 一、RTC驱动基础 1. RTC设备模型:在Linux内核中,...

    LINUX RTC 驱动相关资料

    在Linux系统中,RTC驱动是连接硬件RTC芯片与操作系统内核的桥梁,确保系统即使在关闭电源后仍能保持准确的时间。这份资料主要涵盖了Linux RTC驱动的相关知识,包括基本概念、工作原理、API接口以及开发与调试技巧。 ...

    LPC2146上的 RTC驱动程序(DS1339) Word文档

    LPC2146上的 RTC驱动程序(DS1339) 本文档将详细介绍LPC2146上的RTC驱动程序的实现,具体来说是基于NXP LPC2146单片机上,通过I/O口模拟IIC通讯,实现对RTC DS1339的驱动。 1. DS1339 RTC驱动程序简介 DS1339是...

    Linux RTC 驱动框架

    Linux RTC驱动框架是用于在Linux内核中提供对实时时钟(Real Time Clock,简称RTC)设备支持的一种机制。RTC设备通常用于保持系统时间,即使在计算机电源关闭的情况下也能继续运行。Linux内核中的RTC驱动框架允许...

    pcf8563_i2c1_r8_ruoge_ov2640通过给RTC驱动增加设备节点读取秒钟成功+直接读取I2C1获取秒钟值20160626_2201.7z

    pcf8563_i2c1_r8_ruoge_ov2640通过给RTC驱动增加设备节点读取秒钟成功+直接读取I2C1获取秒钟值20160626_2201.7z http://blog.csdn.net/21cnbao/article/details/7919055 在Android源码树中添加userspace I2C读写...

    LPC23xx rtc驱动程序, 包含测试程序

    在开发基于LPC23xx的嵌入式系统时,编写和理解RTC驱动程序至关重要,因为它涉及到系统的定时和计时任务,例如闹钟、日历功能以及系统时间的保持。 RTC驱动程序主要分为以下几个部分: 1. 初始化:在系统启动或RTC...

    linux系统下rtc驱动

    在本话题中,我们将深入探讨如何在Linux环境下针对DS1338芯片实现RTC驱动,以及它所涉及的核心功能,如修改时间、读取时间、修改日期和读取日期。 DS1338是一款低功耗、高性能的实时时钟/日历芯片,广泛应用于...

    PCF8563 rtc 芯片驱动程序.zip

    描述中提到的"rtc_i2c.h"和"rtc_i2c.c"是I²C总线协议的RTC驱动头文件和源文件,它们包含了实现与PCF8563通讯所需的功能函数和定义。例如,初始化RTC、设置时间和日期、读取RTC数据等操作。这些函数通常会处理I²C的...

    8.4 RTC驱动层代码实现.rar

    RTC驱动层是软件与硬件RTC模块交互的桥梁,它负责管理系统的时钟,提供日期和时间功能,广泛应用于各种应用场景,如定时任务、日志记录、系统唤醒等。 首先,我们需要了解GD32F303系列芯片。GD32F303是由GigaDevice...

    基于linux操作系统下rtc驱动开发学位论文.doc

    RTC 驱动开发与 Linux 操作系统下的移植实现 本文档主要介绍了基于 Linux 操作系统下的 RTC 驱动开发和移植实现。RTC 驱动是指 Real-Time Clock 的驱动程序,用于控制和管理实时时钟芯片的工作。下面将从 Linux ...

    rtc驱动 stm32 C语言

    7. **调试与测试**:编写完RTC驱动后,可以通过串口或LCD等设备显示时间信息,以验证RTC驱动的正确性。同时,可以通过模拟电源断电和恢复,检查RTC在掉电后是否能正确保存和恢复时间。 总之,RTC驱动的开发需要理解...

    RTC驱动[参考].pdf

    在Linux中,RTC驱动被设计为平台驱动,因为不同硬件平台上的RTC实现可能有所不同。以下是RTC驱动的一些关键知识点: 1. **驱动程序结构**: - `rtc_init` 和 `rtc_exit` 是RTC驱动的初始化和退出函数,分别在模块...

    你了解linux RTC 驱动模型?.docx

    RTC驱动模型的设计使得驱动开发者可以专注于实现与硬件交互的部分,而不用关心高级功能的实现,这些由RTC核心来处理。 在Linux系统中,RTC的主要功能是提供持久的时间存储,即使在系统断电后,由于RTC由电池供电,...

    NXP i.MX RT1052实现RTC驱动【支持RT105X系列控制器_库函数驱动】.zip

    在这个项目中,我们将深入探讨如何为NXP i.MX RT1052实现RTC驱动,并支持RT105X系列控制器。 RTC驱动的主要任务是管理硬件RTC模块,该模块通常包括设置和读取当前时间、设置闹钟以及处理中断等功能。在NXP i.MX RT...

    linux 下 hym8563、bm8563 RTC驱动

    在allwinner平台下调通的 linux下hym8563、bm8563 RTC驱动、8563 datesheet资料 ,。

    基于Linux操作系统下RTC驱动开发.doc

    在Linux环境下,RTC驱动是操作系统与硬件RTC芯片之间的桥梁,允许内核与外部RTC设备进行通信。 首先,让我们回顾一下Linux的基础知识。Linux操作系统自1991年由林纳斯·托瓦兹创建以来,已经发展成为一个全球开源...

    基于linux操作系统下rtc驱动开发本科学位论文.doc

    RTC驱动是操作系统与硬件之间的重要接口,它允许系统保持时间的精确记录,即使在系统关闭时也能保存时间信息。以下将详细介绍Linux操作系统、Tiny210开发板、RTC芯片以及RTC驱动的开发过程。 第1章介绍了Linux操作...

    NXP2148的RTC实时时钟驱动程序

    RTC驱动程序是操作系统与硬件之间的桥梁,它使得软件可以方便地访问和管理RTC的功能。以下是对NXP2148 RTC实时时钟驱动程序的详细解释: 1. **RTC模块功能**:RTC模块通常包括年、月、日、时、分、秒等时间单位的...

Global site tag (gtag.js) - Google Analytics