定时器--看门狗和RTC

看门狗

也是通过定时器来实现的,不同之处在于它定时时间到了之后就会发生一个reset signal,然后系统重启。

The difference between WDT and PWM timer is that WDT generates the reset signal

在这里插入图片描述
看门狗的定时器框图还是比较简单的,而且跟定时器的很类似,也是有一个prescaler和mux开关。
注意到WTCON寄存器还是挺厉害的,控制了prescaler,mux开关,中断,还有复位发生。
WTDATWTCNT两个寄存器应该就是负责喂狗和倒计时的。
在这里插入图片描述
看门狗时钟频率计算公式如图所示

在这里插入图片描述
看register map里面还有WTCLRINT寄存器,是用来清中断的。差点漏了。

在这里插入图片描述
小字里面的介绍,关于WTDAT,主要说了在初始化的时候WTDAT的值是不会自动load进去WTCNT的,所以WTCNT里面的初始值是0x8000,最好是自己在初始化的时候也写一个值进去WTCNT里面。WTCNT 里面的小字也是这样讲的。

#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_reset(void)
{
	// 第一步,设置好预分频器和分频器,得到时钟周期是128us
	rWTCON &= ~(0xff<<8);
	rWTCON |= (65<<8);				// 1MHz
	
	rWTCON &= ~(3<<3);
	rWTCON |= (3<<3);				// 1/128 MHz, T = 128us
	
	// 第二步,设置中断和复位信号的使能或禁止
	rWTCON &= ~(1<<2);				// disable wdt interrupt
	rWTCON |= (1<<0);				// enable 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
}


代码是直接复制课程的代码
这部分可以将就着对着数据手册来看
看门狗中断部分的代码就不贴上来了,具体要改的地方是自己要 添加一个isr,然后再main函数里面绑定中断号。
对,记得再isr后面要清中断,之前试过没清导致我的按键都不会响。

RTC

real time clock
在这里插入图片描述

对应的寄存器

继续从RTC的图出发
RTCCON寄存器
看数据手册的读写寄存器
相关的有
BCDSEC
BCDMINi
BCDHOUR
BCDDAYWEEK
BCDDAY
BCDMON
BCDYEAR

具体实现的方法
通过一个结构体的方式,把年月日时分秒都包含在里面,然后读写的时候通过结构体变量的引用方法,把对应的值写入对应的寄存器里面
需要注意的点:
1、要进行16进制和BCD码的相互转换

static unsigned int num_2_bcd(unsigned int num)
{
	// 第一步,把56拆分成5和6 
	// 第二步,把5和6组合成0x56
	return (((num / 10)<<4) | (num % 10));
}

// 函数功能:把bcd码bcd转成十进制,譬如把0x56转成56
static unsigned int bcd_2_num(unsigned int bcd)
{
	// 第一步,把0x56拆分成5和6 
	// 第二步,把5和6组合成56
	return (((bcd & 0xf0)>>4)*10 + (bcd & (0x0f)));
}

2、读写之前都要先通过RTCCON寄存器打开读写开关,读写完之后再关上读写开关

闹钟模式

在register map里面可以看到有年月日时分秒的alarm寄存器
而且还可以设置是否发生中断。
例如:
ALMSEC寄存器是设置发生ALARM的条件的
RTCALM是设置是否允许ALARM以及哪个条件可以触发ALARM
INTP是用于在发生中断之后清除中断的。

最终做了什么出来?

参考课程的代码,然后自己改RTC的时间,读写读出来,
然后再结合看门狗的中断方式,相当于一个定时器,定时一秒之后就打印出当前的时间,每一秒刷新一次时间这样。

过程中还是出现了不少问题的,例如头文件没有包含,在main函数里面没有绑定中断号,没有使能中断,没有吧中断服务程序跟中断号绑定在一起。

在配置看门狗定时器的时候也熟悉了时间的计算,挺好的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值