s5pv210——定时器的知识和代码操作

来源:互联网 发布:农历日期 java代码 编辑:程序博客网 时间:2024/04/28 08:39

以下内容源于朱有鹏《物联网大讲坛》课程的学习,如有侵权,请告知删除。


一、定时器简介

1、定时器是SoC中常见外设

(1)定时器与计数器。

  • 计数器每隔一个固定时间会计一个数;
  • 计数值 * 计数时间周期 = 一段时间。
  • 这个时间段就是我们定的时间。

(2)定时器/计数器作为SoC的外设,主要用来实现定时执行代码的功能。

  • 定时器相对SoC而言,就像闹钟相对于人的意义一样。

2、定时器作用

(1)通过定时器的计时功能,计时结束后,定时器会产生中断提醒CPU。

  • 此时CPU会去处理中断,并执行定时器中断的ISR,从而去执行预先设定好的事件。

(2)定时器就好比CPU的秘书,这个秘书专门用来计时,并到时间后提醒CPU做某件事情。

3、定时器的原理

(1)定时器通过计数来实现定时。

  • 定时器内部有一个计数器。
  • 计数器的时钟,由ARM的APB总线时钟,经过时钟模块内部的分频器的分频得到
  • 每隔一个时钟周期,计数器就计数一次,定时器的时间就是计数器计数值×时钟周期。
  • 定时器内部有1个寄存器TCNT。
  • 计时开始时,把总的计数值放入TCNT寄存器中,然后每隔一个时钟周期TCNT中的值会自动减1(硬件自动完成,不需要CPU软件去干预);
  • 直到TCNT中减为0的时候,TCNT就会触发定时器中断。

(2)由此可知,定时时间是由2个东西共同决定的:一个是TCNT中的计数值,一个是时钟周期。

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

(1)这几个东西都是和时间有关的部件。

(2)看门狗其实就是一个定时器,只不过定时时间到了之后不只是中断,还可以复位CPU

(3)RTC是实时时钟,它和定时器的差别就好象闹钟(定时器)和钟表(RTC)的差别一样。

(4)蜂鸣器是一个发声设备,在ARM里面蜂鸣器是用定时器模块来驱动的。


二、S5PV210中的定时器

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

1、PWM定时器

(1)这种是最常用的,平时所说的定时器一般指的是这个。像简单单片机(譬如51单片机)中的定时器也是这类。

(2)为什么叫PWM定时器?因为一般SoC中产生PWM信号都是靠这类定时器器件的。

2、系统定时器

(1)系统(指的是操作系统)定时器,也是用来产生固定时间间隔(TCNT×时钟周期)信号的,称为systick,这个systick用来给操作系统提供tick信号。

(2)产生systick作为操作系统的时间片(time slice)的。

(3)一般做操作系统移植的时候,这里不会由我们自己来做,一般原厂提供的基础移植部分就已经包含了,所以几乎不需要研究。

3、看门狗定时器

(1)看门狗定时器本质上也是一个定时器,和上面2个没有任何本质区别。

(2)看门狗定时器可以设置在时间到了的时候产生中断,也可以选择发出复位信号复位CPU。

(3)看门狗定时器在实践中应用很多,尤其是工业领域(环境复杂、干扰多)机器容易出问题,而且出问题后后果很严重,此时一般都会用看门狗来进行系统复位。

4、实时时钟RTC(real time clock)

(1)区分时间段和时间点。

  • 时间段是相对的,两个时间点相减就会得到一个时间段;
  • 时间点是绝对的,是绝无仅有的一个时间点。

(2)定时器关注的是时间段,定时器计时从开启定时器的那一刻开始,到定的时间段结束为止产生中断;而RTC中工作用的是时间点(xx年x月x日……)。

(3)RTC和定时器的区别,就相当于是钟表和闹钟的区别。



三、S5PV210的PWM定时器

1、为什么叫PWM定时器?

  • 本质上是定时器;
  • 用来产生PWM波形。

2、PWM定时器介绍

(1)S5PV210有5个PWM定时器。

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

(2)S5PV210的5个PWM定时器的时钟源为PCLK_PSYS

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

3、S5PV210的PWM定时器框图简介

关键点:时钟源、预分频器、分频器、TCMPB&TCNTB、dead zone

(1)预分频器与分频器

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

(2)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波形。

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

(1)定时器工作的时候,一次定时算一个工作循环。

  • 定时器默认是单个循环工作的,也就是说定时一次,计时一次,到期中断一次就完了。下次如果还要再定时中断,需要另外设置。
(2)现实中用定时器来做的时候往往是循环的

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

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

5、什么是PWM?

(1)PWM(pulse wide modulation,脉宽调制)

  • PWM波形是一个周期性波形,周期为T,在每个周期内波形是完全相同的。
  • 每个周期内由一个高电平和一个低电平组成。
(2)PWM波形的2个重要参数

  • 一个是周期T,另一个是占空比duty(占空比就是一个周期内高电平的时间除以周期时间的商)。

(3)PWM波形的用处

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

6、PWM波形的生成原理

(1)早期的简单单片机里(譬如51单片机)没有专用的PWM定时器

  • 需要自己结合GPIO和定时器模块来生产PWM波形;
  • 流程:先将GPIO引脚电平拉高,同时启动定时器定T*duty时间,时间到了在isr中将电平拉低,然后定时T*(1-duty)后再次启动定时器,然后时间到了后在isr中将电平拉高,然后再定时T*duty时间再次启动定时器……

(2)因为定时器经常和PWM的产生有关,所以设计SoC的时候就直接把定时器和一个GPIO引脚内部绑定起来

  • 然后在定时器内部给设置了PWM产生的机制,可以更方便的利用定时器产生PWM波形。
  • 利用PWM定时器来产生PWM波形时,就可以不用中断,而是直接生成PWM。
  • 绑定之后坏处就是GPIO引脚是固定的、死板的、不能随便换的。
(3)在S5PV210中,PWM波形产生有2个寄存器很关键,一个是TCNTB、一个是TCMPB。

  • TCNTB决定PWM波形的周期,TCMPB决定PWM波形的占空比。
  • 最终生成的PWM波形的周期是:TCNTB×时钟周期(PCLK_PSYS经过两极分频后得到的时钟周期)。
  • 最终生成的PWM波形的占空比是:TCMPB/TCNTB

7、输出电平翻转器

(1)PWM定时器可以规定:当TCNT>TCMPB时为高电平,当TCNT<TCMPB时为低电平。也可以规定:当TCNT>TCMPB时为低电平,当TCNT<TCMPB时为高电平。在这两种规定下,计算时TCMP寄存器的值会变化。

(2)基于上面讲的,当duty从30%变到70%时,我们TCMPB寄存器中的值就要改(譬如TCNTB中是300时,TCMPB就要从210变化到90)。这样的改变可以满足需要,但是计算有点麻烦。于是乎210的PWM定时器帮我们提供了一个友好的工具叫做电平翻转器。

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

(4)实战中到底是TCNT和TCMPB谁大谁小时高电平还是低电平,一般不用理论分析,只要写个代码然后用示波器实际看一下出来的波形就知道了;如果反了就直接开启电平翻转器即可。

8、死区生成器

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

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

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

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

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



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

1、蜂鸣器的工作原理

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

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

(3)因为人的耳朵能听见的声音频率有限制(20Hz-20000Hz),我们做实验时一般给个2KHz的频率。

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

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

2、原理图和硬件信息

(1)查阅原理图可知,开发板底板上的蜂鸣器通过GPD0_2(XpwmTOUT2)引脚连接在SoC上。

(2)GPD0_2引脚通过限流电阻接在三极管基极上,引脚有电蜂鸣器就会有电(三极管导通);引脚没电蜂鸣器就会没电(三极管关闭)。这些都是硬件问题,软件工程师不用管,软件工程师只要写程序控制GPD0_2引脚的电平产生PWM波形即可。

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

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

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

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

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

(1)基于uart_stdio项目源码来添加PWM定时器驱动蜂鸣器实验;

(2)PWM定时器来产生PWM波形时是不需要中断干预的。



五、看门狗定时器

1、什么是看门狗、有什么用?

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

(2)系统正常工作的时候当然不希望被重启,但是系统受到干扰、极端环境等可能会产生异常工作或者不工作,这种状态可能会造成不良影响(至少是不工作),此时解决方案就是重启系统。

(3)普通设备重启不是问题,但是有些设备人工重启存在困难。这时候我们希望系统能够自己检验自己是否已经跑飞,并且在意识到自己跑飞的时候,可以很快的(几个ms或者更短)自我重启。这个功能就要靠看门狗定时器来实现。

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

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

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

(1)PCLK_PSYS经过两级分频后生成WDT(watchdog timer)的时钟周期,然后把要定的时间写到WTDAT寄存器中,刷到WTCNT寄存器中去减1,减到0时(定时时间到)产生复位信号或中断信号。

(2)典型应用中是配置为产生复位信号,我们应该在WTCNT寄存器减到0之前给WTDAT寄存器中重新写值以喂狗。

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

WTCON WTDAT WTCNT WTCLRINT

4、看门狗定时器的编程实践

(1)产生中断信号

(2)产生复位信号

六、实时时钟RTC

1、何为实时时钟?

(1)real time clock,真实时间,即xx年x月x日x时x分x秒;

(2)RTC是SoC中一个内部外设,拥有独立的晶振提供RTC时钟源(32.768KHz),内部有一些寄存器用来记录时间(年月日时分秒星期)。

  • 一般情况下为了在系统关机时时间仍然在走,还会给RTC提供一个电池供电。

2、S5PV210实时时钟的结构框图

(1)时间寄存器7个;

(2)闹钟发生器;

3、闹钟发生器

(1)可以定闹钟时间,到时间会产生RTC alarm interrupt,通知系统闹钟定时到了。

(2)闹钟定时是定的时间点,而timer定时是定的时间段。

4、S5PV210实时时钟的主要寄存器

(1)INTP,中断挂起寄存器

(2)RTCCONRTC控制寄存器

(3)RTCALM ALMxxx闹钟功能有关的寄存器

(4)BCDxxx,时间寄存器

5、BCD码

(1)RTC中所有的时间(年月日时分秒星期,包括闹钟)都是用BCD码编码的。

(2)BCD码本质上是对数字的一种编码,用4位二进制数表示1位十进制数字,比如十进制的56被编码成0x56。

(3)BCD码的作用

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

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

(5)需要写2个函数,一个是bcd转十进制,一个是十进制转bcd。

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

七、RTC实战

1、设置时间与读取显示时间

(1)为了安全,默认情况下RTC读写是禁止的,此时读写RTC的时间是不允许的;当我们要更改RTC时间时,应该先打开RTC的读写开关,然后再进行读写操作,操作完了后立即关闭读写开关。

(2)读写RTC寄存器时,一定要注意BCD码和十进制之间的转换。

(3)年的问题。

  • BCDYEAR寄存器存的并不是完整的年数,而是基于2000年的偏移量来存储的;
  • 譬如今年2015年,实际存的就是15(2015-2000);
  • 还有些RTC芯片是以1970年为基点的。

2、闹钟实验