×
单片机 > 单片机程序设计 > 详情

第8课:WatchDog定时器和RTC

发布时间:2020-06-19 发布时间:
|
首先来讲看门狗定时器:它有2个功能

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 |=0;
        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 |=0;
        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");
}

 
void showtime()                                                                        //ignore one second devition
{
 uart_write("\r\nNow,the RTC time is:\r\nYear:20");
        char a;
        a = (char)rBCDYEAR;
        bcd2uart(a);
        uart_write(" Month:");
        a = (char)rBCDMON;
        bcd2uart(a);
        uart_write(" Date:");
        a = (char)rBCDDATE;
        bcd2uart(a);
        uart_write(" Hour:");
        a = (char)rBCDHOUR;
        bcd2uart(a);
        uart_write(" Min:");
        a = (char)rBCDMIN;
        bcd2uart(a);
        uart_write(" Sec:");
        a = (char)rBCDSEC;
        bcd2uart(a);
 uart_write("\r\n");
}
void ISR_Handle()
{
 int n;
 char select,a;
 n = rINTOFFSET;
 switch(n){
  case 28:        //take a choice by int
   if(rSUBSRCPND = 0){
    while(!(rUTRSTAT0 & 0x1)); 
   select = rURXH0;
    rUTXH0 = select;
    switch(select){
     case '1':settime();break;
     case '2':setalarmtime();break;
     case '3':showtime();break;
     default:uart_write("please input in 1 to 3\r\n");
    }
   }
   break;
  case 30:                                                                     //when alarm clock reach,int_rtc will actived
   uart_write("\r\nAlarm!!!");
   uart_write(":");
          a = (char)rBCDHOUR;
          bcd2uart(a);
          uart_write(":");
          a = (char)rBCDMIN;
          bcd2uart(a);
          uart_write(":");
          a = (char)rBCDSEC;
          bcd2uart(a);
          uart_write("\r\n");
   break;
  default:uart_write("undefined interrupt\r\n");
 }       
 rSUBSRCPND = 1;
 rSRCPND = 5<<28;
 rINTPND = 5<<28;
}

关键字:WatchDog  定时器  RTC 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
8051单片机的函数发生器的设计