S3C2440上RTC时钟驱动开发实例分析

发布者:电子科技爱好者最新更新时间:2024-06-06 来源: elecfans关键字:S3C2440  RTC时钟  驱动开发 手机看文章 扫描二维码
随时随地手机看文章

一、开发环境


主 机:VMWare--Fedora 9


开发板:Mini2440--64MB Nand, Kernel:2.6.30.4


编译器:arm-linux-gcc-4.3.2


二、相关概念


1、平台设备:

通常在Linux中,把SoC系统中集成的独立外设单元(如:I2C、IIS、RTC、看门狗等)都被当作平台设备来处理。在Linux中用platform_device结构体来描述一个平台设备,在2.6.30.4内核中定义在:include/linux/platform_device.h中,如下:


struct platform_device {

const char * name; //设备名称

int id;

struct device dev;

u32 num_resources; //设备使用各类资源的数量

struct resource * resource; //设备使用的资源


struct platform_device_id *id_entry;

};


现在你不必深入理解这个结构体,只要知道在Linux中是用这个结构体来定义一些平台设备的。比如在:arch/arm/plat-s3c24xx/devs.c中就定义了很多平台设备,下面我就只贴出RTC这一种的:


* RTC */

static struct resource s3c_rtc_resource[] = { //定义了RTC平台设备使用的资源,这些资源在驱动中都会用到

[0] = { //IO端口资源范围

.start = S3C24XX_PA_RTC,

.end = S3C24XX_PA_RTC + 0xff,

.flags = IORESOURCE_MEM,

},

[1] = { //RTC报警中断资源

.start = IRQ_RTC,

.end = IRQ_RTC,

.flags = IORESOURCE_IRQ,

},

[2] = { //TICK节拍时间中断资源

.start = IRQ_TICK,

.end = IRQ_TICK,

.flags = IORESOURCE_IRQ

}

};


struct platform_device s3c_device_rtc = { //定义了RTC平台设备

.name = 's3c2410-rtc', //设备名称

.id = -1,

.num_resources = ARRAY_SIZE(s3c_rtc_resource), //资源数量

.resource = s3c_rtc_resource, //引用上面定义的资源

};


EXPORT_SYMBOL(s3c_device_rtc);


好了,定义了平台设备,那系统是怎么来使用他的呢?我们打开:arch/arm/mach-s3c2440/mach-smdk2440.c这个ARM 2440平台的系统入口文件,可以看到在系统初始化函数smdk2440_machine_init中是使用platform_add_devices这个函数将一些平台设备添加到系统中的,如下:(至于系统是如何实现添加平台设备的,这里我们不必研究,这些Linux系统都已经做好了的,我们要研究的是后面平台设备的驱动是如何实现的)


static struct platform_device *smdk2440_devices[] __initdata = {

&s3c_device_usb,

&s3c_device_lcd,

&s3c_device_wdt,

&s3c_device_i2c0,

&s3c_device_iis,DE>


&s3c_device_rtc, //这里我们添加上RTC平台设备,默认是没添加的

}; //平台设备列表,也就是说我们要使用一个新的平台设备要先在上面定义,然后加到这个列表中,最后到驱动层去实现该设备的驱动


static void __init smdk2440_machine_init(void)

{

s3c24xx_fb_set_platdata(&smdk2440_fb_info);

s3c_i2c0_set_platdata(NULL);

//将上面列表中的平台设备添加到系统总线

platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));

smdk_machine_init();

}


2、平台设备驱动:

这里所讲的平台设备驱动是指具体的某种平台设备的驱动,比如上面讲的RTC平台设备,这里就是指RTC平台设备驱动。在Linux中,系统还为平台设备定义了平台驱动结构体platform_driver,就好比系统为字符设备定义了file_operations一样,但不要把平台设备跟字符设备、块设备、网络设备搞成了并列的概念,因平台设备也可以是字符设备等其他设备。注意:在被定义为平台设备的字符设备的驱动中,除了要实现字符设备驱动中file_operations的open、release、read、write等接口函数外,还要实现平台设备驱动中platform_driver的probe、remove、suspend、resume等接口函数。好了,在我们搞明白上面这些后,下面我们就来具体详细分析讲解RTC平台设备的驱动现实。




三、实例讲解


1、RTC在Linux中的整体结构:

就个人理解,RTC在Linux中整体结构分为两个部分。第一个是部分就是上面所讲的作为平台设备被挂接到系统总线中,这里我把他叫做设备层(呵呵,可能不是很准确的叫法);第二部分就是驱动部分,这里叫做驱动层。在Linux中要使一个驱动在不同的平台中都能够使用似乎是不可能的,所以我们先看2.6.30.4内核驱动中的RTC部分是单独的一个文件夹,在文件夹中包含了很多不同体系结构的RTC驱动,当然也有S3C2440的RTC驱动,然而在这些驱动中他们都使用了一组文件里面的方法,那么这组文件就是RTC的核心(注意这里的核心不是指对RTC硬件的操作,指的是对RTC操作的方法。对硬件寄存器的操作还是在具体的驱动中)。好了,我们还是用图来说明这种关系吧!!


2、RTC硬件原理图分析:以下是S3C2440AL内部集成的RTC模块结构图和一个外部的晶振接口图


我们从S3C2440内部RTC模块结构图和数据手册得知,RTC在Linux中主要实现两种功能,分别是系统掉电后的时间日期维持和时间日期报警(类似定时器功能)。


①、时间日期维持功能:

主要是由RTC实时时钟控制寄存器RTCCON进行功能的使能控制,由节拍时间计数寄存器TICNT来产生节拍时间中断来实现实时操作系统功能相关的时间和实时同步。其中对时间日期的操作实际上是对BCD码操作,而BCD码则是由一系列的寄存器组成(BCD秒寄存器BCDSEC、BCD分寄存器BCDMIN、BCD小时寄存器BCDHOUR、BCD日期寄存器BCDDATE、BCD日寄存器BCDDAY、BCD月寄存器BCDMON、BCD年寄存器BCDYEAR)。


②、报警功能:

主要由RTC报警控制寄存器RTCALM进行功能使能控制,并产生报警中断。报警时间日期的设置也是对一系列的寄存器进行操作(报警秒数据寄存器ALMSEC、报警分钟数据寄存器ALMMIN、报警小时数据寄存器ALMHOUR、报警日期数据寄存器ALMDATE、报警月数据寄存器ALMMON、报警年数据寄存器ALMYEAR)。


3、RTC驱动实现步骤(建立驱动文件my2440_rtc.c):


注意:在每步中,为了让代码逻辑更加有条理和容易理解,就没有考虑代码的顺序,比如函数要先定义后调用。如果要编译此代码,请严格按照C语言的规范来调整代码的顺序。


①、依然是驱动程序的最基本结构:RTC驱动的初始化和退出部分及其他,如下:


#include

#include

#include

#include

#include


/*RTC平台驱动结构体,平台驱动结构体定义在platform_device.h中,该结构体内的接口函数在第②、④步中实现*/

static struct platform_driver rtc_driver =

{

.probe = rtc_probe, /*RTC探测函数,在第②步中实现*/

.remove = __devexit_p(rtc_remove),/*RTC移除函数,在第④步实现,为何使用__devexit_p,在该函数实现的地方再讲*/

.suspend = rtc_suspend, /*RTC挂起函数,在第④步中实现*/

.resume = rtc_resume, /*RTC恢复函数,在第④步中实现*/

.driver =

{

/*注意这里的名称一定要和系统中定义平台设备的地方一致,这样才能把平台设备与该平台设备的驱动关联起来*/

.name = 's3c2410-rtc',

.owner = THIS_MODULE,

},

};


static int __init rtc_init(void)

{

/*将RTC注册成平台设备驱动*/

return platform_driver_register(&rtc_driver);

}


static void __exit rtc_exit(void)

{

/*注销RTC平台设备驱动*/

platform_driver_unregister(&rtc_driver);

}


module_init(rtc_init);

module_exit(rtc_exit);


MODULE_LICENSE('GPL');

MODULE_AUTHOR('Huang Gang');

MODULE_DESCRIPTION('My2440 RTC driver');


②、RTC平台驱动结构中探测函数rtc_probe的实现。探测就意味着在系统总线中去检测设备的存在,然后获取设备有用的相关资源信息,以便我们使用这些信息。代码如下:


#include

#include

#include

#include

#include


/*定义了一个用来保存RTC的IO端口占用的IO空间和经过虚拟映射后的内存地址*/

static struct resource *rtc_mem;

static void __iomem *rtc_base;


/*定义了两个变量来保存RTC报警中断号和TICK节拍时间中断号,NO_IRQ宏定义在irq.h中*/

static int rtc_alarmno = NO_IRQ;

static int rtc_tickno = NO_IRQ;


/*申明并初始化一个自旋锁rtc_pie_lock,对RTC资源进行互斥访问*/

static DEFINE_SPINLOCK(rtc_pie_lock);


/*RTC平台驱动探测函数,注意这里为什么要使用一个__devinit,也到rtc_remove实现的地方一起讲*/

static int __devinit rtc_probe(struct platform_device *pdev)

{

int ret;

struct rtc_device *rtc; /*定义一个RTC设备类,rtc_device定义在rtc.h中*/

struct resource *res; /*定义一个资源,用来保存获取的RTC的资源*/


/*在系统定义的RTC平台设备中获取RTC报警中断号

platform_get_irq定义在platform_device.h中*/

rtc_alarmno = platform_get_irq(pdev, 0);

if (rtc_alarmno < 0)

{

/*获取RTC报警中断号不成功错误处理

dev_err定义在device.h中,在platform_device.h中已经引用,所以这里就不需再引用了*/

dev_err(&pdev->dev, 'no irq for alarmn');

return -ENOENT;

}


//在系统定义的RTC平台设备中获取TICK节拍时间中断号

rtc_tickno = platform_get_irq(pdev, 1);

if (rtc_tickno < 0)

{

/*获取TICK节拍时间中断号不成功错误处理*/

dev_err(&pdev->dev, 'no irq for rtc tickn');

return -ENOENT;

}


/*获取RTC平台设备所使用的IO端口资源,注意这个IORESOURCE_MEM标志和RTC平台设备定义中的一致*/

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

if (res == NULL)

{

/*错误处理*/

dev_err(&pdev->dev, 'failed to get memory region resourcen');

return -ENOENT;

}


/*申请RTC的IO端口资源所占用的IO空间(要注意理解IO空间和内存空间的区别),

request_mem_region定义在ioport.h中*/

rtc_mem = request_mem_region(res->start, res->end - res->start + 1, pdev->name);

if (rtc_mem == NULL)

{

/*错误处理*/

dev_err(&pdev->dev, 'failed to reserve memory regionn');

ret = -ENOENT;

goto err_nores;

}


/*将RTC的IO端口占用的这段IO空间映射到内存的虚拟地址,ioremap定义在io.h中。

注意:IO空间要映射后才能使用,以后对虚拟地址的操作就是对IO空间的操作,*/

rtc_base = ioremap(res->start, res->end - res->start + 1);

if (rtc_base == NULL)

{

/*错误处理*/

dev_err(&pdev->dev, 'failed ioremap()n');

ret = -EINVAL;

goto err_nomap;

}


/*好了,通过上面的步骤已经将RTC的资源都准备好了,下面就开始使用啦*/


/*这两个函数开始对RTC寄存器操作,定义都在下面*/

rtc_enable(pdev, 1); /*对RTC的实时时钟控制寄存器RTCCON进行操作(功能是初始化或者使能RTC)*/

rtc_setfreq(&pdev->dev, 1);/*对RTC的节拍时间计数寄存器TICNT的0-6位进行操作,即:节拍时间计数值的设定*/


/*device_init_wakeup该函数定义在pm_wakeup.h中,定义如下:

static inline void device_init_wakeup(struct device *dev, int val){

dev->power.can_wakeup = dev->power.should_wakeup = !!val;

}

显然这个函数是让驱动支持电源管理的,这里只要知道,can_wakeup为1时表明这个设备可以被唤醒,设备驱动为了支持

Linux中的电源管理,有责任调用device_init_wakeup()来初始化can_wakeup,而should_wakeup则是在设备的电源状态

发生变化的时候被device_may_wakeup()用来测试,测试它该不该变化,因此can_wakeup表明的是一种能力,

而should_wakeup表明的是有了这种能力以后去不去做某件事。好了,我们没有必要深入研究电源管理的内容了,

要不就扯远了,电源管理以后再讲*/

device_init_wakeup(&pdev->dev, 1);


/*将RTC注册为RTC设备类,RTC设备类在RTC驱动核心部分中由系统定义好的,

注意rtcops这个参数���一个结构体,该结构体的作用和里面的接口函数实现在第③步中。

rtc_device_register函数在rtc.h中定义,在drivers/rtc/class.c中实现*/

rtc = rtc_device_register('my2440', &pdev->dev, &rtcops, THIS_MODULE);

if (IS_ERR(rtc))

{

/*错误处理*/

dev_err(&pdev->dev, 'cannot attach rtcn');

ret = PTR_ERR(rtc);

goto err_nortc;

}


/*设置RTC节拍时间计数寄存器TICNT的节拍时间计数值的用户最大相对值,

这里你可能不理解这句,没关系,等你看到rtc_setfreq函数实现后自然就明白了*/

rtc->max_user_freq = 128;


/*将RTC设备类的数据传递给系统平台设备。

platform_set_drvdata是定义在platform_device.h的宏,如下:

#define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data))

而dev_set_drvdata又被定义在include/linux/device.h中,如下:

static inline void dev_set_drvdata (struct device *dev, void *data){

dev->driver_data = data;

}*/

platform_set_drvdata(pdev, rtc);


return 0;


//以下是上面错误处理的跳转点

err_nortc:

rtc_enable(pdev, 0);

iounmap(rtc_base);


err_nomap:

release_resource(rtc_mem);


err_nores:

return ret;

}


/*该函数主要是初始化或者使能RTC,

以下RTC的各种寄存器的宏定义在arch/arm/plat-s3c/include/plat/regs-rtc.h中,

各寄存器的用途和设置请参考S3C2440数据手册的第十七章实时时钟部分*/

static void rtc_enable(struct platform_device *pdev, int flag)

{

unsigned int tmp;


/*RTC的实时时钟控制寄存器RTCCON共有4个位,各位的初始值均为0,根据数据手册介绍第0位(即:RCTEN位)

可以控制CPU和RTC之间的所有接口(即RTC使能功能),所以在系统复位后应该将RTCCON寄存器的第0为置为1;

在关闭电源前,又应该将该位清零,以避免无意的写RTC寄存器*/

if (!flag)

{

/*当flag=0时(即属于关闭电源前的情况),RTCCON寄存器清零第一位*/

tmp = readb(rtc_base + S3C2410_RTCCON); /*读取RTCCON寄存器的值*/

/* tmp & ~S3C2410_RTCCON_RTCEN = 0 即屏蔽RTC使能*/

writeb(tmp & ~S3C2410_RTCCON_RTCEN, rtc_base + S3C2410_RTCCON);


tmp = readb(rtc_base + S3C2410_TICNT); /*读取TICNT寄存器的值*/

/* tmp & ~S3C2410_TICNT_ENABLE后第7位为0,即屏蔽节拍时间中断使能*/

writeb(tmp & ~S3C2410_TICNT_ENABLE, rtc_base + S3C2410_TICNT);

}

else

{

/*当flag!=0时(即属于系统复位后的情况),使能RTC*/

if ((readb(rtc_base + S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0)

{

dev_info(&pdev->dev, 'rtc disabled, re-enablingn');

tmp = readb(rtc_base + S3C2410_RTCCON);

writeb(tmp | S3C2410_RTCCON_RTCEN, rtc_base + S3C2410_RTCCON);

}


if ((readb(rtc_base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL))

{

dev_info(&pdev->dev, 'removing RTCCON_CNTSELn');

tmp = readb(rtc_base + S3C2410_RTCCON);

writeb(tmp & ~S3C2410_RTCCON_CNTSEL, rtc_base + S3C2410_RTCCON);

}


if ((readb(rtc_base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST))

{

dev_info(&pdev->dev, 'removing RTCCON_CLKRSTn');

tmp = readb(rtc_base + S3C2410_RTCCON);

writeb(tmp & ~S3C2410_RTCCON_CLKRST, rtc_base + S3C2410_RTCCON);

}

}

}


/*该函数主要是对RTC的节拍时间计数寄存器TICNT的0-6位进行操作,即:节拍时间计数值的设定*/

static int rtc_setfreq(struct device *dev, int freq)

{

unsigned int tmp;


if (!is_power_of_2(freq)) /*对freq的值进行检查*/

return -EINVAL;


spin_lock_irq(&rtc_pie_lock); /*获取自旋锁保护临界区资源*/


/*读取节拍时间计数寄存器TICNT的值*/

tmp = readb(rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE;


/*看数据手册得知,节拍时间计数值的范围是1-127,

还记得在rtc_enable函数中设置的rtc->max_user_freq=128吗?所以这里要减1*/

tmp |= (128 / freq) - 1;


/*将经运算后值写入节拍时间计数寄存器TICNT中,这里主要是改变TICNT的第0-6位的值*/

writeb(tmp, rtc_base + S3C2410_TICNT);


spin_unlock_irq(&rtc_pie_lock);/*释放自旋锁,即解锁*/


return 0;

}


③、RTC设备类的操作。在这一步中,才是对RTC硬件的各种寄存器进行操作,代码如下:


#include

#include


/*rtc_class_ops是RTC设备类在RTC驱动核心部分中定义的对RTC设备类进行操作的结构体,

类似字符设备在驱动中的file_operations对字符设备进行操作的意思。该结构体被定义

在rtc.h中,对RTC的操作主要有打开、关闭、设置或获取时间、设置或获取报警、设置节拍时间计数值等等,

该结构体内接口函数的实现都在下面*/

static const struct rtc_class_ops rtcops = {

[1] [2] [3]
关键字:S3C2440  RTC时钟  驱动开发 引用地址:S3C2440上RTC时钟驱动开发实例分析

上一篇:S3C2440时钟频率
下一篇:s3c2440的UART功能测试

推荐阅读最新更新时间:2026-03-23 13:47

RTC时钟与触摸功能详解(下)
58.5 电阻式触摸控制器——XPT2046 为了方便测量触摸屏的坐标,芯片厂商设计了专门的触摸屏控制芯片,实现触摸点电压测量与转换功能。本文采用的XPT2046是一款4导线制触摸屏控制器,内含12位分辨率 125KHz 转换速率逐次逼近型A/D转换器。XPT2046通过执行两次A/D转换便可以计算出触摸点位置,该芯片兼容 ADS7843 触摸芯片,其电路原理图和引脚图如图8-6和表8-1、表8-2所示。 XPT2046的 电源 VCC的范围为2.7V~5.5V。A/D转换所需的参考电压可以选择通过 VR EF输入,范围是1V~VCC;也可以采用内部内部 2.5V参考电压,采用内部参考电压时VREF引脚应悬空。XPT2
[单片机]
<font color='red'>RTC</font><font color='red'>时钟</font>与触摸功能详解(下)
STM32单片机RTC时钟的使用方法及步骤
STM32RTC使用步骤: 打开PWR时钟和Backup区数据访问 若使用外部低速时钟(LSE),打开LSE并等待起振 选择和打开RTC时钟,等待时钟同步 配置时间格式,分频系数等 根据需要配置时钟,日期,闹钟,唤醒,输出,时间戳,备份寄存器等模块 根据需要配置和打开中断,其中 RTC Alarm ——EXTI line 17 RTC tamper and Timestamps——EXTI line 19 RTC wakeup——EXTI line 20 下面的代码配置日期,时间,当前时间设置为 15年05月31日,星期日(7),15:50:40,打开闹钟A和唤醒中断,每一秒钟来一次中断,15:50:45秒产生闹钟中断,用串
[单片机]
STM32单片机<font color='red'>RTC</font><font color='red'>时钟</font>的使用方法及步骤
STM32的实时时钟RTC编程详解
在STM32里,一个CPU已经足够,不需要像DS1302这样的实时时钟芯片。实际上,RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器。因为它掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据。 STM32的RTC模块 RTC模块之所以具有实时时钟功能,是因为它内部维持了一个独立的定时器,通过配置,可以让它准确地每秒钟中断一次。 1.1 RTC的组成 RTC由两个部分组成:APB1接口部分以及RTC核心部分。 STM32所有的外设默认时钟无效,使用某个外设时,再开启时钟,用这样的方式来降低功耗。 这里的RTC,APB1 接口由APB1总线时钟来驱动。为
[单片机]
STM32学习笔记之RTC实时时钟2
5. 程序实现 5.1 初始化 u8 RTC_Init(void){ u8 temp=0; RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟 PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问 if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎 { BKP_DeInit(); //复位备份区域
[单片机]
STM32学习笔记之<font color='red'>RTC</font>实时<font color='red'>时钟</font>2
STM32CubeMX系列 | RTC实时时钟
1. RTC实时时钟简介 STM32的实时时钟RTC是一个独立的定时器,RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能,修改计数器的值可以重新设置系统当前的时间和日期 RTC模块和时钟配置系统(RCC_BDCR寄存器)是在后背区域,即在系统复位或从待机模式唤醒后RTC的设置和事件维持不变。但是在系统复位后,会自动禁止访问后备寄存器和RTC,以防止对后备区域(BKP)的意外操作。所以在要设置时间之前,要先取消备份区域写保护。RTC的简化框图如下所示: RTC由两个主要部分组成:第一部分(APB1接口)用来和APB1总线相连,此单元还包含一组16位寄存器,可通过APB1总线对其进行读写操作;另一部分(R
[单片机]
浅谈智能座舱中RTC时钟应用
随着科技发展,越来越多的车载电子设备不断涌现,为了满足驾乘者更好的体验,智能座舱应运而生。 汽车座舱更新迭代: 第一代较为简易,有车载收音机、磁带播放器,为用户提供电台、音乐等简单娱乐功能。 第二代增加了更多电子产品,包括中控屏、车机系统,导航系统为用户出行提供了方便。 第三代引入了智能技术,包括更大的中控屏、液晶仪表盘、HUD(抬头显示)、流媒体后视镜等,以及车内音响、座椅、灯光、显示等设备,为用户提供了人机交互、视觉感知、更丰富的娱乐等功能。 智能座舱主要组成: 智能座舱由三大部分组成:硬件(仪表盘、流媒体后视镜、HUD、中控屏幕、后座娱乐系统、空调、座椅、音响等)、软件、人机交互(语音、人脸、触摸、手势、生物等识别
[嵌入式]
浅谈智能座舱中<font color='red'>RTC</font><font color='red'>时钟</font>应用
【STM32】HAL库-RTC实时时钟
简介 实时时钟是一个独立的定时器 RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC的设置和时间维持不变 系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问: 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。 时钟源 通过设置备份域控制寄存器(RCC_BDCR)里的RTCSEL 位,RTCCLK时钟源可以由HSE/128、LSE或LSI时钟提供。 除非备份域复位,此选择不能被改变。
[单片机]
【STM32】HAL库-<font color='red'>RTC</font>实时<font color='red'>时钟</font>
Exynos4412裸机开发 —— RTC 实时时钟单元
RTC(Real-Time Clock) 实时时钟。RTC是集成电路,通常称为时钟芯片。在一个嵌入式系统中,通常采用RTC来提供可靠的系统时间,包括时分秒和年月日等,而且要求在系统处于关机状态下它也能正常工作(通常采用后备电池供电)。它的外围也不需要太多的辅助电路,典型的就是只需要一个高精度的32.768kHz 晶体和电阻电容等。 一、RTC 控制器 实时时钟(RTC)单元可以通过备用电池供电,因此,即使系统电源关闭,它也可以继续工作。RTC可以通过STRB/LDRB 指令将8位BCD码数据送至CPU。这些BCD数据包括秒、分、时、日期、星期、月和年。RTC单元通过一个外部的32.768kHz 晶振提供时钟。RTC具有定时报警
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved