ARM技术论坛
直播中

ss

7年用户 8762经验值
擅长:电源/新能源 制造/封装 RF/无线
私信 关注
[经验]

ARM裸机之S5PV210中的定时器有哪些

1.什么是定时器(timer)
定时器/计数器作为SoC的外设,主要用来实现定时执行代码的功能。
定时器可以让SoC在执行主程序的同时,可以(通过定时器)具有计时功能,到了一定时间(计时结束)后,定时器会产生中断提醒CPU,CPU会去处理中断并执行定时器中断的ISR。从而去执行预先设定好的事件。
定时时间是由2个东西共同决定的:一个是TCNT中的计数值,一个是时钟周期。
定时器内部有1个寄存器TCNT,计时开始时我们会把一个总的计数值(譬如说300)放入TCNT寄存器中,然后每隔一个时钟周期(假设为1ms)TCNT中的值会自动减1(硬件自动完成,不需要CPU软件去干预),直到TCNT中减为0的时候,TCNT就会触发定时器中断。
2.S5PV210中的定时器
PWM定时器:
这种是最常用的,像简单单片机(譬如51单片机)中的定时器也是这类,一般SoC中产生PWM信号都是靠这个定时器模块的。
系统定时器:
系统定时器称为systick,系统定时器也是用来产生固定时间间隔(TCNT×时钟周期)信号的。
一般做操作系统移植的时候,这里不会由我们自己来做,一般原厂提供的基础移植部分就已经包含了。
看门狗定时器:
看门狗定时器可以选择发出复位信号复位CPU,在实践中应用很多,尤其是工业领域(环境复杂、干扰多)机器容易出问题,此时一般都会用看门狗来进行系统复位。
实时时钟RTC(real time clock):
定时器关注的是时间段(而不是时间点),定时器计时从开启定时器的那一刻开始,到定的时间段结束为止产生中断;RTC中工作用的是时间点(xx年x月x日x时x分x秒星期x)。
RTC和定时器的区别,就相当于是钟表和闹钟的区别。
3.看门狗定时器
结构框图:

几个主要寄存器:
WTCON :

WTDAT :

WTCNT:

WTCLRINT:

4.代码实现
#define    WTCON    (0xE2700000)
#define    WTDAT    (0xE2700004)
#define    WTCNT    (0xE2700008)
#define   WTCLRINT  (0xE270000C)
#define   rWTCON    (*(volatile unsigned int *)WTCON)
#define   rWTDAT    (*(volatile unsigned int *)WTDAT)
#define   rWTCNT    (*(volatile unsigned int *)WTCNT)
#define   rWTCLRINT  (*(volatile unsigned int *)WTCLRINT)
// 初始化WDT使之可以产生中断
void wdt_init_interrupt(void)
{
  // 第一步,设置好预分频器和分频器,得到时钟周期是128us
  rWTCON &= ~(0xff<<8);
  rWTCON |= (65<<8);        // 1MHz
  rWTCON &= ~(3<<3);
  rWTCON |= (3<<3);        // 1/128 MHz, T = 128us
  // 第二步,设置中断和复位信号的使能或禁止
  rWTCON |= (1<<2);        // enable wdt interrupt
  rWTCON &= ~(1<<0);        // disable wdt reset
  // 第三步,设置定时时间
  // WDT定时计数个数,最终定时时间为这里的值×时钟周期
  //rWTDAT = 10000;          // 定时1.28s
  //rWTCNT = 10000;          // 定时1.28s
  // 其实WTDAT中的值不会自动刷到WTCNT中去,如果不显式设置WTCON中的值,它的值就是
  // 默认值,然后以这个默认值开始计数,所以这个时间比较久。如果我们自己显式的
  // 设置了WTCNT和WTDAT一样的值,则第一次的定时值就和后面的一样了。
  rWTDAT = 1000;          // 定时0.128s
  //rWTCNT = 1000;          // 定时0.128s
  // 第四步,先把所有寄存器都设置好之后,再去开看门狗
  rWTCON |= (1<<5);        // enable wdt
}
// wdt的中断处理程序
void isr_wdt(void)
{
  static int i = 0;
  // 看门狗定时器时间到了时候应该做的有意义的事情
  printf("wdt interrupt, i = %d...", i++);
  // 清中断
  intc_clearvectaddr();
  rWTCLRINT = 1;
}

原作者:学习&笔记

更多回帖

发帖
×
20
完善资料,
赚取积分