ARM 裸机之定时器、看门狗和RTC

这里记录了定时器、计数器、看门狗、RTC、蜂鸣器等的概念和基本工作原理

这里记录了定时器、计数器、看门狗、RTC、蜂鸣器等的概念和基本工作原理

PWM 脉宽调制

脉宽调制定时器概述

S5PV210有5个32位脉宽调制(PWM:Pulse Width Modulation)定时器。这些定时器为ARM子系统产生内部中断。此外,定时器0、1、2和3还包括一个PWM功能,可以驱动外部I/O信号。

定时器0中的PWM具有可选的死区发生器功能,可支持大电流器件。定时器4为内部定时器,没有输出引脚。

定时器使用APB-PCLK作为源时钟。定时器0和1共用一个可编程的8位预分器,为PCLK提供第一级分频。定时器2、3和4共用一个不同的8位预分器。每个定时器都有自己的私有时钟分频器,提供第二级时钟分频(预分器除以2、4、8或16)。另外,定时器还可以从CMU中选择一个时钟源。定时器0、1、2、3和4选择SCLK_PWM。

每个定时器都有自己的32位下行计数器,由定时器时钟驱动。下降计数器最初从定时器计数缓冲寄存器(TCNTBn:Timer Count Buffer register)中加载。如果下行计数器达到零,则产生定时器中断请求,通知CPU定时器操作完成。如果定时器的下行计数器达到零,则相应的TCNTBn的值自动重新加载到下行计数器中,开始下一个循环。但是,如果在定时器运行模式下,定时器通过清除TCONn的定时器使能位而停止,则TCNTBn的值不会被重新加载到计数器中。

PWM功能使用TCMPBn寄存器的值。如果下行计数器的值与定时器控制逻辑中的比较寄存器的值相匹配,定时器控制逻辑就会改变输出电平。因此,比较寄存器决定了PWM输出的开启时间(或关断时间)。

pmw

PWM循环中的步骤。

  • 初始化TCNTBn寄存器为159(50+109),TCMPBn为109。

  • 启动定时器:设置启动位,并将该位手动更新为off。

    将TCNTBn值159加载到下行计数器中,然后将输出TOUTn设为低电平。

  • 如果下行计数器将TCNTBn的值减到TCMPBn寄存器中的值109,则输出由低位变为高位。

  • 如果下行计数器达到0,则会产生一个中断请求。

  • 下行计数器会自动重新加载TCNTBn。这将重新启动循环。

PWM有两种工作模式,即自动加载和一击脉冲:

  • 自动加载模式

    在此模式下,根据设定的占空比和极性产生连续的PWM脉冲。

  • 单次脉冲模式

    在此模式下,根据编程的占空比和极性,只产生一个PWM脉冲。

    为了控制PWM的功能,提供了18个特殊功能寄存器。PWM是一个可编程输出、双时钟输入的AMBA从属模块,并连接到高级外设总线(APB)。PWM内的这18个特殊功能寄存器通过APB事务访问。

基本的定时器操作

timer_operations

定时器(除定时器通道4外)由四个寄存器组成,即TCNTBn、TCNTn、TCMPBn和TCMPn。如果定时器达到0,则TCNTBn和TCMPBn寄存器被加载到TCNTn和TCMPn中。如果中断被启用,TCNTn达到0则发生中断请求,(TCNTn和TCMPn是内部寄存器的名称。TCNTn寄存器从TCNTOn寄存器中读取)。

如图所示,要在XpwmTOUTn的3个周期间隔产生中断,需要设置TCNTBn、TCMPBn和TCON寄存器

产生中断的步骤:

  1. 设置TCNTBn=3,TCMPBn=1。

  2. 设置 auto-reload=1和 manual update=1

    如果手动更新(manual update)位为1,则TCNTBn和TCMPBn值被加载到TCNTn和TCMPn。

  3. 为下一次操作设置TCNTBn=2,TCMPBn=0

  4. 设置 auto-reload=1,manual update=0,此时如果设置 manual update=1,TCNTn改为2,TCMP改为0。因此,中断的产生时间间隔为2周期,而不是3周期。因此你必须为下一次操作设置 auto-reload=1。

  5. 设置 start=1 启动操作。TCNTn 开始向下计数

    如果 TCNTn = 0,则产生中断;如果启用自动重载(auto-reload),则TCNTn被加载为2(TCNTBn值),TCMPn被加载为0(TCMPn值)。

  6. TCNTn停止前,TCNTn向下计数

自动重载和双重缓冲

PWM定时器包括双缓冲功能,在不停止当前定时器操作的情况下,改变下一个定时器操作的重载值。

定时器的值被写入TCNTBn(定时器计数缓冲寄存器),并从TCNTOn(定时器计数观察寄存器)中读取定时器的当前计数器值。如果读到TCNTBn,则读出的值不反映计数器的当前状态,而是反映下一个定时器持续时间的重载值。

自动重载是将TCNTBn复制到TCNTn中,如果TCNTn达到0,自动重载是将写到TCNTBn的值复制到TCNTn中,如果TCNTn达到0,自动重载启用,则将写到TCNTBn中的值加载到TCNTn中。如果TCNTn为0,自动加载位为0,则TCNTn不继续工作。

初始化定时器(设置 MANUAL-UP 数据和反向器 inverter)

用户必须定义TCNTn的起始值,因为当下降计数器达到0时,定时器会发生自动加载操作,这种情况下,必须通过手动更新位(manual update bit)来加载起始值。定时器的启动顺序如下:

  1. 将初始值写入TCNTBn和TCMPBn。

  2. 设置手动更新位,只清除相应定时器的手动更新位。

    注意:建议设置反向器(inverter)的开/关位(无论是否使用反向器)。

  3. 设置相应的定时器的启动位,以启动定时器。

脉宽调制(pwm)

pwm_exp

使用TCMPBn来实现PWM功能。PWM频率由TCMPBn决定。PWM值由TCMPBn决定

对于较高的PWM值,降低TCMPBn值。对于较低的PWM值,增加TCMPBn值。如果输出反向器启用,增减值可以相反。

由于双缓冲功能,下一个PWM周期的TCMPBn,在当前PWM周期的任意一点由ISR写入

I/O 描述

信号 I/O 描述 焊盘 类型
TOUT_0 Output PWMTIMER TOUT[0] XpwmTOUT[0] 复用
TOUT_1 Output PWMTIMER TOUT[1] XpwmTOUT[1] 复用
TOUT_2 Output PWMTIMER TOUT[2] XpwmTOUT[2] 复用
TOUT_3 Output PWMTIMER TOUT[3] XpwmTOUT[3] 复用

寄存器描述

寄存器表

寄存器 地址 R/W 说明 初始值
TCFG0 0xE250_0000 R/W 指定用于配置两个8位预分频器死区长度的定时器配置寄存器0。 0x0000_0101
TCFG1 0xE250_0004 R/W 指定控制5个MUX选择位的定时器配置寄存器1。 0x0000_0000
TCON 0xE250_0008 R/W 定时器控制寄存器 0x0000_0000
TCNTB0 0xE250_000C R/W 定时器0计数缓冲寄存器 0x0000_0000
TCMPB0 0xE250_0010 R/W 定时器0比较缓冲区寄存器 0x0000_0000
TCNTO0 0xE250_0014 R 定时器0计数观察寄存器 0x0000_0000
TINT_CSTAT 0xE250_0044 R/W 定时器中断控制状态寄存器 0x0000_0000

ARM 裸机之定时器、看门狗和 RTC

什么是定时器(timer)

定时器是SoC中常见外设

  • 定时器与计数器

    计数器是用来计数的(每隔一个固定时间会计一个数);因为计数器的计数时间周期是固定的,因此到了一定时间只要用计数值×计数时间周期,就能得到一个时间段,这个时间段就是我们定的时间(这就是定时器了)。

  • 定时器/计数器作为SoC的外设,主要用来实现定时执行代码的功能。定时器相对于SoC来说,就好象闹钟相对于人来说意义一样

定时器有什么用

  • 定时器可以让SoC在执行主程序的同时,可以(通过定时器)具有计时功能,到了一定时间(计时结束)后,定时器会产生中断提醒CPU,CPU会去处理中断并执行定时器中断的ISR。从而去执行预先设定好的事件。
  • 所以CPU有了定时器之后,只需预先把自己xx时间之后必须要做的事情绑定到定时器中断ISR即可,到了时间之后定时器就会以中断的方式提醒CPU来处理这个事情。

定时器的原理

  • 定时器计时其实是通过计数来实现的

    定时器内部有一个计数器,这个计数器根据一个时钟(这个时钟源来自于ARM的APB总线,然后经过时钟模块内部的分频器来分频得到)来工作。每隔一个时钟周期,计数器就计数一次,定时器的时间就是计数器计数值×时钟周期。

    定时器内部有1个寄存器TCNT,计时开始时我们会把一个总的计数值(譬如说300)放入TCNT寄存器中,然后每隔一个时钟周期(假设为1ms)TCNT中的值会自动减1(硬件自动完成,不需要CPU软件去干预),直到TCNT中减为0的时候,TCNT就会触发定时器中断。

  • 定时时间是由2个东西共同决定的

    • 一个是TCNT中的计数值
    • 一个是时钟周期
    • 譬如上例中,定时周期就为300×1ms = 300ms。

定时器和看门狗、RTC、蜂鸣器的关系

  • 看门狗其实就是一个定时器,只不过定时时间到了之后不只是中断,还可以复位CPU
  • RTC是实时时钟,它和定时器的差别就好象闹钟(定时器)和钟表(RTC)的差别一样。
  • 蜂鸣器是一个发声设备,在ARM里面蜂鸣器是用定时器模块来驱动的。

S5PV210中的定时器

在S5PV210内部,一共有4类定时器件。这4类定时器件的功能、特征是不同的

  • PWM定时器
    • 这种是最常用的,平时所说的定时器一般指的是这个。像简单单片机(譬如51单片机)中的定时器也是这类。
    • 为什么叫PWM定时器,因为一般SoC中产生PWM信号都是靠这个定时器模块的
  • 系统定时器
    • 系统(指的是操作系统)定时器,系统定时器也是用来产生固定时间间隔(TCNT×时钟周期)信号的,称为systick,这个systick用来给操作系统提供tick信号。
    • 产生systick作为操作系统的时间片(time slice)
    • 一般做操作系统移植的时候,这里不会由我们自己来做,一般原厂提供的基础移植部分就已经包含了
  • 看门狗定时器
    • 看门狗定时器本质上也是一个定时器,和上面2个没有任何本质区别
    • 可以设置在时间到了的时候产生中断,也可以选择发出复位信号复位CPU
    • 看门狗定时器在实践中应用很多,尤其是工业领域(环境复杂、干扰多)机器容易出问题,而且出问题后后果很严重,此时一般都会用看门狗来进行系统复位
  • 实时时钟RTC(real time clock)
    • 定时器关注的是时间段(而不是时间点),定时器计时从开启定时器的那一刻开始,到定的时间段结束为止产生中断;RTC中工作用的是时间点(xx年x月x日x时x分x秒星期x)
    • RTC和定时器的区别,就相当于是钟表和闹钟的区别

S5PV210的PWM定时器

为什么叫PWM定时器

因为这个定时器天然是用来产生PWM波形的。

S5PV210有5个PWM定时器。其中0、1、2、3各自对应一个外部GPIO,可以通过这些对应的GPIO产生PWM波形信号并输出;timer4没有对应的外部GPIO(因此不是为了生成PWM波形而是为了产生内部定时器中断而生的)

S5PV210的5个PWM定时器的时钟源为PCLK_PSYS,timer0和timer1共同使用一个预分频器、timer2、3、4共同使用一个预分频器;每个timer有一个专用的独立的分频器预分频器分频器构成了2级分频系统,将PCLK_PSYS两级分频后生成的时钟供给timer模块作为时钟周期。

clock_diagram

预分频器与分频器

  1. 两级分频是串联(级联)的,所以两级分频的分频数是相乘的
  2. 两级分频的分频系数分别在TCFG0TCFG1两个寄存器中设置
  3. 预分频器有2个
    • prescaler0为timer0&timer1共用;
    • prescaler1为timer2、3、4共用;
    • 两个prescaler都是8个bit位,因此prescaler value范围为0~255;所以预分频器的分频值范围为1~256(注意实际分频值为prescaler value + 1)
  4. 分频器实质上是一个MUX开关,多选一开关决定了走哪个分频系数路线。
    • 可以选择的有1/1,1/2,1/4,1/8,1/16等。
  5. 在PCLK_PSYS为66MHz的情况下(默认时钟设置就是66MHz的),此时两级分频后的时钟周期范围为0.03us到62.061us;再结合TCNTB的值的设置(范围为1~2的32次方),可知能定出来的时间最长为266548.27s(折合74小时多,远远够用了)

TCNT&TCMP、TCNTB&TCMPB、TCNTO

  • TCNT和TCNTB是相对应的,TCNTB是有地址的寄存器,供程序员操作;TCNT在内部和TCNTB相对应,它没有寄存器地址,程序员不能编程访问这个寄存器。
  • TCNT寄存器功能就是用来减1的,它是内部的不能读写;我们向TCNT中写要通过TCNTB往进写;读取TCNT寄存器中的值要通过读取相对应的TCNTO寄存器
  • 工作流程:
    • 事先算好TCNT寄存器中开始减的那个数(譬如300),然后将之写入TCNTB寄存器中
    • 在启动timer前,将TCNTB中的值刷到TCNT寄存器中(有一位寄存器专门用来操作刷数据过去的),
    • 刷过去后就可以启动定时器开始计时
    • 在计时过程中如果想知道TCNT寄存器中的值减到多少了,可以读取相应的TCNTO寄存器来得知
  • 定时功能只需要TCNT、TCNTB两个即可;TCNTO寄存器用来做一些捕获计时;TCMPB用来生成PWM波形

自动重载和双缓冲(auto-reload and double buffering)

定时器工作的时候,一次定时算一个工作循环。定时器默认是单个循环工作的,也就是说定时一次,计时一次,到期中断一次就完了。下次如果还要再定时中断,需要另外设置。

但是现实中用定时器来做的时候往往是循环的,最简单最笨的方法就是写代码反复重置定时器寄存器的值(在每次中断处理的isr中再次给TCNTB中赋值,再次刷到TCNT中再次启动定时器),早期的单片机定时器就是这样的;但是现在的高级SoC中的定时器已经默认内置了这种循环定时工作模式,就叫自动装载(auto-reload)机制。

自动装载机制就是当定时器初始化好开始计时后再不用管了,他一个周期到了后会自己从TCNTB中再次装载值到TCNT中,再次启动定时器开始下个循环

什么是PWM

PWM(pulse wide modulation 脉宽调制),PWM波形是一个周期性波形,周期为T,在每个周期内波形是完全相同的。每个周期内由一个高电平和一个低电平组成。

  • PWM波形有2个重要参数:
    • 一个是周期T,
  • 另一个是占空比duty(占空比就是一个周期内高电平的时间除以周期时间的商)

对于一个PWM波形,知道了周期T和占空比duty,就可以算出这个波形的所有细节。譬如高电平时间为T x duty,低电平时间为T x (1-duty)

  • PWM波形有很多用处
    • 通信上用PWM来进行脉宽调制对基波进行载波调制
    • 在发光二极管LED照明领域可以用PWM波形来调制电流进行调光
    • 用来驱动蜂鸣器等设备。

PWM波形的生成原理

PWM波形其实就是用时间来控制电平高低。

在S5PV210中,PWM波形产生有2个寄存器很关键,一个是TCNTB、一个是TCMPB。其中,TCNTB决定了PWM波形的周期TCMPB决定了PWM波形的占空比。最终生成的PWM波形的周期是:TCNTB×时钟周期(PCLK_PSYS经过两极分频后得到的时钟周期)。注意这个周期是PWM中高电平+低电平的总时间,不是其中之一。

最终生成的PWM波形的占空比是:TCMPB/TCNTB

输出电平翻转器

电平翻转器在电路上的实质就是一个电平取反的部件,在编程上反映为一个寄存器位。写0就关闭输出电平反转,写1就开启输出电平反转。开启后和开启前输出电平刚好高低反转。(输出电平一反转30%的duty就变成70%了)

死区生成器

PWM有一个应用就是用在功率电路中用来对交流电压进行整流。整流时2路整流分别在正电平和负电平时导通工作,不能同时导通(同时导通会直接短路,瞬间的同时导通都会导致电路烧毁)。大功率的开关电源、逆变器等设备广泛使用了整流技术。特别是逆变器,用SoC的GPIO输出的PWM波形来分别驱动2路整流的IGBT。

PWM波形用来做整理时要求不能同时高或低,因为会短路。但是实际电路是不理想的,不可能同时上升/下降沿,所以比较安全的做法是留死区。

死区这东西离不了也多不了。死区少了容易短路,死区多了控制精度低了不利于产品性能的提升。

S5PV210给大家提供了自带的死区生成器,只要开启死区生成器,生产出来的PWM波形就自带了死区控制功能,用户不用再自己去操心死区问题。

大部分人工作是用不到这个的,直接关掉死区生成器即可。

蜂鸣器和PWM定时器编程实践

蜂鸣器的工作原理

蜂鸣器里面有2个金属片,离的很紧但没挨着;没电的时候两个片在弹簧本身张力作用下分开彼此平行;有电的时候两边分别充电,在异性电荷的吸力作用下两个片挨着;

我们只要以快速的频率给蜂鸣器的正负极:供电、断电。进行这样的循环,蜂鸣器的两个弹簧片就会挨着分开挨着分开···形成敲击,发出声音。

因为人的耳朵能听见的声音频率有限制(20Hz-20000Hz),我们做实验时一般给个2KHz的频率,大部分人都能听到(听不到的就就近医院处理)。

频率高低会影响声音的音频,一般是音频越低声音听起来越低沉、音频越高听起来越尖锐。

根据以上的分析,可以看出,只要用PWM波形的电压信号来驱动蜂鸣器,把PWM波形的周期T设置为要发出的声音信号的1/频率即可;PWM的占空比只要确保能驱动蜂鸣器即可(驱动能力问题,一般引脚驱动能力都不够,所以蜂鸣器会额外用三极管来放大流来供电)。

原理图和硬件信息

  • 开发板底板上的蜂鸣器通过GPD0_2(XpwmTOUT2)引脚连接在SoC上

    fmq

  • 查SP5V210数据手册的 P100 页(Pin Mux Description)可知,XpwmTOUT2 是由 GPD0[2] 引出的

    Pin Name GPIO Func0 Default
    XpwmTOUT[2] GPD0[2] TOUT_2 GPI
  • GPD0_2引脚通过限流电阻接在三极管基极上,引脚有电蜂鸣器就会有电(三极管导通);引脚没电蜂鸣器就会没电(三极管关闭)。只要写程序控制GPD0_2引脚的电平产生PWM波形即可

  • GPD0 控制寄存器 0xE02000A0

    GPD0CON Bit Description Initial State
    GPD0CON[3] [15:12] 0000 = Input 0000
    GPD0CON[2] [11:8] 0010 = TOUT_2 0000
    GPD0CON[1] [7:4] 0000 = Input 0000
    GPD0CON[0] [3:0] 0000 = Input
    0001 = Output
    0010 = TOUT_3
    0011 ~ 1110 = Reserved
    1111 = GPD0_INT[3]
    0000

    GPD0CON(0xE02000A0),要把bit8~bit11设置为0b0010(功能选择为TOUT_2,就是把这个引脚设置为PWM输出功能)

  • 从GPD0_2引脚可以反推出使用的是timer2这个PWM定时器

PWM定时器的主要寄存器详解

相关的寄存器有TCFG0、TCFG1、CON、TCNTB2、TCMPB2、TCNTO2

寄存器 地址 R/W 说明 初始值
TCFG0 0xE250_0000 R/W 指定用于配置两个8位预分频器死区长度的定时器配置寄存器0。 0x0000_0101
TCFG1 0xE250_0004 R/W 指定控制5个MUX选择位的定时器配置寄存器1。 0x0000_0000
TCON 0xE250_0008 R/W 定时器控制寄存器 0x0000_0000
TCNTB2 0xE250_0024 R/W 定时器2计数缓冲寄存器 0x0000_0000
TCMPB2 0xE250_0028 R/W 定时器2比较缓冲区寄存器 0x0000_0000
TCNTO2 0xE250_002C R 定时器2计数观察寄存器 0x0000_0000
TINT_CSTAT 0xE250_0044 R/W 定时器中断控制状态寄存器 0x0000_0000

定时器配置寄存器 TCFG0、TCFG1

TCFG0 Bit 说明 初始值
保留 [31:24] 保留位 0x0
死区长度 [23:16] 死区长度 0x00
预分频器 1 [15:8] 定时器 2, 3, 4 预分频器 1 的值 0x1
预分频器 0 [7:0] 定时器 0, 1 预分频器 0 的值 0x0

如果将死区长度设置为’n’,则实际死区长度为’n+1’(n=0~254)。

定时器的输入时钟频率 = PCLK / ({预分频值 + 1}) / (分频值)

预分频值:1~255

分频值:1, 2, 4, 8, 16

TCFG1 Bit 说明 初始值
保留 [31:20] 保留位 0x0
分频器 MUX4 [19:16] 选择PWM定时器4的复用输入 0x00
Divider MUX3 [15:12] 选择PWM定时器3的复用输入 0x0
Divider MUX2 [11:8] 选择PWM定时器2的复用输入 0x0
Divider MUX1 [7:4] 选择PWM定时器1的复用输入 0x0
Divider MUX0 [3:0] 选择PWM定时器0的复用输入
0000 = 1/1
0001 = 1/2
0010 = 1/4
0011 = 1/8
0100 = 1/16
0101 = SCLK_PWM
0x0

定时器控制寄存器 CON

TCON Bit 说明 初始值
其他 [31:16] 其他定时器设置 0x0
Timer 2 Auto Reload on/off [15] 0 = One-Shot
1 = Interval Mode(Auto-Reload)
0x00
Timer 2 Output Inverter on/off [14] 0 = Inverter Off
1 = TOUT_2 Inverter-On
0x0
Timer 2 Manual Update [13] 0 = No Operation
1 = 更新 TCNTB2,TCMPB2
0x0
Timer 2 Start/StopAuto Reload on/off [12] 0 = 停止
1 = 启动定时器 2
0x0
Dead Zone Enable/Disable [4] 使能/禁用死区发送器 0x0

定时器计数、比较、观测寄存器 (TCNTB2, TCMPB2, TCNTO2)

寄存器 Bit 说明 初始值
Timer 2 Count Buffer(TCNTB2) [31:0] Timer 2 Count Buffer Register 0x0
Timer 2 Compare Buffer(TCMPB2) [31:0] Timer 2 Compare Buffer Register 0x00
Timer 2 Count Observation(TCNTO2) [31:0] Timer 2 Count Observation Register 0x0

中断控制与状态寄存器 TINT_CSTAT

TINT_CSTAT Bit 说明 初始值
保留 [31:10] 保留位 0x0
定时器2的中断状态位 [7] 定时器2的中断状态位,写1清除 0x0
定时器2中断使能位 [2] 1 = 使能;0 = 禁止 0x0

看门狗定时器

什么是看门狗、有什么用

看门狗定时器和普通的定时器并无本质区别。定时器可以设定一个时间,在这个时间完成之前定时器不断计时,时间到的时候定时器会复位CPU(重启系统)

系统正常工作的时候当然不希望被重启,但是系统受到干扰、极端环境等可能会产生异常工作或者不工作,这种状态可能会造成不良影响(至少是不工作),此时解决方案就是重启系统。普通设备重启不是问题,但是有些设备人工重启存在困难。这时候我们希望系统能够自己检验自己是否已经跑飞,并且在意识到自己跑飞的时候,可以很快的(几个ms或者更短)自我重启。这个功能就要靠看门狗定时器来实现。

典型应用的情景是:我们在应用程序中打开看门狗设备,初始化好给它一个时间,然后应用程序使用一个线程来喂狗,这个线程的执行时间安全短于看门狗的复位时间。当系统(或者应用程序)异常后,喂狗线程自然就不工作了,然后到时候看门狗就会复位。

实际中有时候为了绝对的可靠,我们并不会用SoC中自带的看门狗,而是使用专门的外置的看门狗芯片来实现看门狗。

S5PV210看门狗定时器的结构框图

wdt

预分频器值和分频系数在看门狗定时器控制(WTCON)寄存器中指定。有效的预分频器值范围为 0 ~ (2^8)-1。分频系数可以选择16、32、64或128。

使用下面的公式计算看门狗定时器时钟频率和每个定时器时钟周期的持续时间:

t_watchdog = 1/( PCLK / (预分频器值 + 1) / 分频系数 )

  • PCLK_PSYS经过两级分频后生成WDT(watchdog timer)的时钟周期,然后把要定的时间写到WTDAT寄存器中,刷到WTCNT寄存器中去减1,减到0时(定时时间到)产生复位信号或中断信号。
  • 典型应用中是配置为产生复位信号,我们应该在WTCNT寄存器减到0之前给WTDAT寄存器中重新写值以喂狗

一旦看门狗定时器被启用,看门狗定时器数据(WTDAT)寄存器的值就不能自动重新加载到定时器计数器(WTCNT)中。因此,在看门狗定时器启动之前,必须将一个初始值写入看门狗定时器计数器(WTCNT)寄存器中。

看门狗定时器的主要寄存器

寄存器 地址 R/W 说明 初始值
WTCON 0xE270_0000 R/W 看门狗控制寄存器 0x00008021
WTDAT 0xE270_0004 R/W 看门狗数据寄存器 0x00008000
WTCNT 0xE270_0008 R/W 看门狗计数器 0x00008000
WTCLRINT 0xE270_000C W 看门狗中断清除寄存器 -

看门狗控制寄存器 WTCON

WTCON 寄存器允许用户

  • 启用/禁用看门狗定时器
  • 选择来自四个不同源的时钟信号
  • 启用/禁用中断
  • 以及启用/禁用看门狗定时器输出

看门狗定时器用于重启S5PV210,以从故障中恢复;如果不需要控制器重启,则应禁用看门狗定时器。 如果您想使用看门狗定时器提供的正常定时器,请启用中断禁用看门狗定时器

寄存器 Bit 说明 初始值
保留 [31:16] 保留 0x0
预分频值 [15:8] 预分频值,0 ~ 255 0x80
保留 [7:6] 必须是00 0x00
看门狗定时器 [5] 启用(1)/禁用(0)看门狗定时器 0x1
时钟选择 [4:3] 时钟分频系数
00 = 16
01 = 32
10 = 64
11 = 128
00
中断发生 [2] 启用(1)/禁用(0)中断 0
保留 [1] 必须是 0 0
启用/禁用复位 [0] 输出复位信号
1 = 在看门狗超时时时,S5PV210的复位信号亮起。
0 = 禁用看门狗定时器的复位功能。
1

看门狗数据寄存器 WTDAT

WTDAT寄存器指定了超时时间。WTDAT的内容不能在初始看门狗定时器操作时自动加载到定时器计数器中。但是,使用0x8000(初始值)会驱动第一次超时。

WTDAT Bit 说明 初始值
保留 [31:16] 保留 0x0
计数重载值 [15:0] 计数重载值 0x8000

看门狗计数器 WTCNT

WTCNT寄存器包含正常工作时看门狗定时器的当前计数值。注意,如果看门狗定时器初始启用,WTDAT寄存器的内容不能自动加载到定时器计数寄存器中,因此在启用前必须将WTCNT寄存器设置为初始值。

WTCNT Bit 说明 初始值
保留 [31:16] 保留 0x0
计数值 [15:0] 看门狗定时器的当前计数值 0x8000

看门狗中断清除寄存器 WTCLRINT

WTCLRINT Bit 说明 初始值
中断清除 [31:0] 写入任意值清除中断 -

实时时钟RTC

何为实时时钟

  • real time clock,真实时间,就是所谓的xx年x月x日x时x分x秒星期x
  • RTC是SoC中一个内部外设,RTC有自己独立的晶振提供RTC时钟源(32.768KHz),内部有一些寄存器用来记录时间(年月日时分秒星期)。一般情况下为了在系统关机时时间仍然在走,还会给RTC提供一个电池供电

S5PV210实时时钟的结构框图

rt

  • 时间寄存器7个
  • 闹钟发生器
    • 可以定闹钟时间,到时间会产生RTC alarm interrupt,通知系统闹钟定时到了
    • 闹钟定时是定的时间点,而timer定时是定的时间段

S5PV210实时时钟的主要寄存器

(1)INTP 中断挂起寄存器 (2)RTCCON RTC控制寄存器 (3)RTCALM ALMxxx 闹钟功能有关的寄存器 (4)BCDxxx 时间寄存器

BCD码

RTC中所有的时间(年月日时分秒星期,包括闹钟)都是用BCD码编码的。BCD码本质上是对数字的一种编码。用来解决这种问题:由56得到0x56(或者反过来)。也就是说我们希望十进制的56可以被编码成56(这里的56不是十进制56,而是两个数字5和6)

BCD码的作用在于可以将十进制数拆成组成这个十进制数的各个数字的编码,变成编码后就没有位数的限制了。譬如我有一个很大的数123456789123456789,如果这个数纯粹当数字肯定超出了int的范围,计算机无法直接处理。要想让计算机处理这个数,计算机首先得能表达这个数,表达的方式就是先把这个数转成对应的BCD码(123456789123456789)

BCD码在计算机中可以用十六进制的形式来表示。也就是说十进制的56转成BCD码后是56,在计算机中用0x56来表达(暂时存储与运算)

需要写2个函数,一个是bcd转十进制,一个是十进制转bcd。当我们要设置时间时(譬如要设置为23分),我们需要将这个23转成0x23然后再赋值给相应的寄存器BCDMIN;当我们从寄存器BCDMIN中读取一个时间时(譬如读取到的是0x59),需要将之当作BCD码转成十进制再去显示(0x59当作BCD码就是59,转成十进制就是59,所以显示就是59分)

RTC编程实战

设置时间与读取显示时间

  • 为了安全,默认情况下RTC读写是禁止的,此时读写RTC的时间是不允许的;当我们要更改RTC时间时,应该先打开RTC的读写开关,然后再进行读写操作,操作完了后立即关闭读写开关。
  • 读写RTC寄存器时,一定要注意BCD码和十进制之间的转换。
  • 年的问题。S5PV210中做了个设定,BCDYEAR寄存器存的并不是完整的年数(譬如今年2015年),而是基于2000年的偏移量来存储的,譬如今年2015年实际存的就是15(2015-2000).还有些RTC芯片是以1970年(貌似)为基点来记录的。

闹钟实验