第8课:WatchDog定时器和RTC
1:当系统发生紊乱时,自动重启系统
2:普通定时
对于定时狗而言,它使用的是PCLK,和PWM一样有2个分屏器,但是它多了一样复位信号发生器,当看门狗中的CNT递减到0时,复位信号将被发出。作为写一般的程序而言,我们要做的就是不能让看门狗中的计数器CNT到0,要进行“喂狗”。
喂狗:在CNT递减到0之前,重设CNT里的值
原本我们的程序是0.5秒小灯亮,0.5秒小灯暗,现在加入了看门狗,如果发送5秒中内不喂狗的话,就将重启开发板
程序:main.c
功能:初始化计时器,小灯,uart,中断等
#include"s3c2440.h"
#define UART_CLK 50000000
#define UART_BAUD_RATE 115200
#define UART_BRD (int)(UART_CLK/(UART_BAUD_RATE *16))-1
void init_uart()
{
rGPHCON |=0xa0;
rGPHUP = 0x0c;
rULCON0 = 0x3;
rUCON0 = 0x5;
rUFCON0 = 0;
rUMCON0 = 0;
rUBRdiv0 = UART_BRD;
}
void init_led()
{
rGPECON = GPE12_out|GPE13_out;
}
void init_timer0()
{
rTCFG0 = 0x63;
rTCFG1 = 0x1;
rTCNTB0 = 0xFFFF;
rTCON = 0xa;
rTCON = 0x9;
}
void init_irq()
{
rINTMOD = 0;
rINTMSK = ~(1<10);
}
int main()
{
init_uart();
init_led();
init_irq();
init_timer0();
while(1);
}
程序:int.C
功能:中断服务程序中让小灯闪和灭,同时喂狗。
#include"s3c2440.h"
void ISR_Handle()
{
rGPEDAT ^= (3<12);
rWTCNT = 0x1dce; //喂狗
rSRCPND = 1<10;
rINTPND = 1<10;
}
void setwatchdog()
{
rWTCON = 0xff39;
rWTCNT = 0x1dce;
}
看门狗在crt0.s中设置这里从略。
接下来说说RTC模块。
这个模块通常外接电池,在系统断电后负责计时,和断电后闹钟功能。还能做实时系统的内部时钟。
RTC模块内部的寄存器中的数字都是由BCD码编成的。注意转换。
还有RTC内部有闰年发生器。但是由于内部的年只有8位共2个BCD码 只能表示00到99,这里的00指的是2000年。
这里需要指出的就是在读取时间的时候有可能会有1秒偏差,因为秒是最后读的,在读00的时候,之前的年月日有可能还是之前的值,产生偏差,可以采取读到00就再复读一次前面的值的方法解决。
以下设计了一个简单的RTC实时时钟的测试模块。
实现3个功能
1设置内部时间 年月日时分秒
2设置闹钟时间 时分秒
3显示当前时间
通过uart对开发版的内部RTC模块进行设置。
程序:main.c
功能:初始化串口,rtc,中断
#include"s3c2440.h"
#define UART_CLK 50000000
#define UART_BAUD_RATE 115200
#define UART_BRD (int)(UART_CLK/(UART_BAUD_RATE *16))-1
void init_uart()
{
rGPHCON |=0xa0;
rGPHUP = 0x0c;
rULCON0 = 0x3;
rUCON0 = 0x5;
rUFCON0 = 0;
rUMCON0 = 0;
rUBRdiv0 = UART_BRD;
}
void uart_write(char *data)
{
while (*data != \0) {
while (!(rUTRSTAT0 & 0x4));
rUTXH0 = *data;
data++;
}
}
void init_irq()
{
rINTMOD = 0;
rINTMSK = ~(1<28);
rINTSUBMSK = ~1;
rINTMSK &= ~(1<30);
}
void init_rtc()
{
rRTCCON = 0x1;
rTICNT = 0x0;
}
void bcd2uart(char n)
{
char a=0;
a = (n>>4)+0;
rUTXH0 = a;
while (!(rUTRSTAT0 & 0x4));
a = (n&0xf)+0;
rUTXH0 = a;
}
void menu()
{
uart_write("Welcome to RTC Module\r\n");
uart_write("You can select the follow funtion\r\n");
uart_write("1 Set RTC Time\r\n");
uart_write("2 Set Alarm Time\r\n");
uart_write("3 Show RTC Time\r\n");
}
void alarm()
{
rRTCALM = 0x47;
}
int main()
{
init_uart();
init_irq();
init_rtc();
menu();
alarm();
while(1);
}
程序:int.C
功能:通过isr实现3大功能
#include"s3c2440.h"
void fillrtc(char *t,volatile unsigned long *p) //used by set alarm time and set the normal time
{
char a,b,c;
int n=0;
while(*t != ;){
while((*t != :) && (*t != ;)){
if(n == 0){
a = *t++;
n++;
}
else if(n == 1){
b = *t++;
n++;
}
}
if(n == 1)
c = (a - 0);
else if(n == 2)
c = ((a - 0)<4) | (b - 0);
*p-- = c;
if(p == (volatile unsigned long *)0x57000080) //the funtion of this reg is setting the day(like sunday);
p--; //so the date will be set before,this reg can be ignored
n = 0;
if( *t != ; )
t++;
}
}
void settime()
{
char time[30];
char *t = time;
volatile unsigned long *p = &rBCDYEAR;
uart_write("\r\nplease set time in this format YEAR:MONTH:DATA:HOUR:MIN:SEC;\r\n");
do{
while(!(rUTRSTAT0 & 0x1));
*t = rURXH0;
rUTXH0 = *t++;
}
while(*(t-1) != ;);
fillrtc(time,p);
uart_write("\r\nset time over.please check it\r\n");
}
void setalarmtime()
{
uart_write("\r\nset the alarm time like HOUR:MIN:SEC;\r\n");
char time[30];
char *t = time;
volatile unsigned long *p = &rALMHOUR;
do{
while(!(rUTRSTAT0 & 0x1));
*t = rURXH0;
rUTXH0 = *t++;
}
while(*(t-1) != ;);
fillrtc(time,p);
uart_write("\r\nset alarmtime over.\r\n");
}
WatchDog定时器RT 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)