第8课:WatchDog定时器和RTC

发布者:RainbowJoy最新更新时间:2016-08-06 来源: eefocus关键字:WatchDog  定时器  RTC 手机看文章 扫描二维码
随时随地手机看文章
首先来讲看门狗定时器:它有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 |=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");
}

 
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 引用地址:第8课:WatchDog定时器和RTC

上一篇:第7课:DMA
下一篇:MDK (Keil For ARM) 与 Proteus 联调 的设置方法

推荐阅读最新更新时间:2024-03-16 15:03

STM32F103的普通定时器中断问题
问题: 存在开机后初始化,在TIM3_Int_Init()里面,一打开允许中断函数TIM_ITConfig(),定时器立刻进入中断函数一次。只进一次。 初始化函数最后已经关闭定时器: TIM_Cmd(TIM3, DISABLE); //暂关闭TIMx外设。将这个函数提到初始化最前面也没用。 解决方法: 总结:应该是TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);产生了更新事件,只要将 TIM_ClearFlag(TIM5, TIM_FLAG_Update); TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE); 放在TIM_TimeBaseInit
[单片机]
STM32F4XX 定时器笔记
1 定时器的三个基本单元:计数器(Counter)、预分频器(Prescaler)、自动装载寄存器(Auto-Reload)。 2 The new prescaler ratio is taken into account at the next update event. 3 计数与更新源、更新事件、跟新中断之间的关系。 4 In addition, if the URS bit (update request selection) in TIMx_CR1 register is set, setting the UG bit generates an update event UEV but without sett
[单片机]
STM32F4XX <font color='red'>定时器</font>笔记
stm32之滴答定时器(2):滴答定时器地址与stm32结构体
上一篇讲了滴答定时器在内核什么位置,这篇讲讲滴答定时器结构体和地址的联系 不知道大家搜滴答定时地址的时候有没有注意到,SysTick_BASE的下面就是SysTick的定义 #define SysTick ((SysTick_Type *) SysTick_BASE) 这个东西第一次接触还是感觉挺绕的(初学者强烈推荐一本入门书《C和指针》(*^__^*) ),这句什么意思呢,通俗地讲,就是把SysTick定义为了指向SysTick_Type结构体的指针,而这个指针的地址呢,是个固定值, SysTick_BASE,也就是上一篇写的0xE000E010。 这个SysTick_Type结构体是什么,同样
[单片机]
stm32之滴答<font color='red'>定时器</font>(2):滴答<font color='red'>定时器</font>地址与stm32结构体
AVR单片机定时器T0的基本中断使用ICCAVR
#include iom128v.h void main(void) { TCNT0=0x83; TCCR0=0x07; TIMSK=0x01; SEI(); DDRC=0xff; PORTC=0; OCR0=0X00; while(1); } #pragma interrupt_handler Timer0:iv_TIMER0_OVF void Timer0() { TCNT0=0x83; PORTC=~PORTC; } 得出一个结论:别指望巧合。
[单片机]
高压看门狗定时器提高车载系统安全性
汽车设计中,越来越多的电子系统正在逐步替代机械功能——从引擎定时控制到刹车、方向盘控制,而电子系统相对容易发生故障,这就需要谨慎考虑系统的安全性,确保系统具备较高的故障容限。不应该在发生单点故障时将司机或乘客至于危险处境,至少能够使汽车“跛行”到大路以外或最近的维修站。当电子设备发生故障时,为确保汽车的安全行驶需要利用监控电路开启备份电路,安全地接管系统操作。 在纯机械系统的汽车时代,引擎依照机械方式产生的信号点燃空气燃料混合器。机械分配器则选择适当的火花塞,沿线传递信号。刹车系统则将作用在踏板上的压力通过刹车轴、刹车总泵、液压管传送到制动钳。离合器和油门只是简单地受控于连接在踏板上的一条钢缆。方向盘通过一个金属舵轮、转向轴、转向
[嵌入式]
STM32 关于定时器相关问题的探讨(二)
4.硬件设计 4.1LED驱动电路 利用单片机产生得PWM驱动电路直接驱动LED电路来验证,当输出PWM宽度变化时可以看到此时LED亮度变化,此时只需要将LED上拉就可以实现验证。当输入为低电平时,LED灯发光 4.2 SPWM滤波方案 利用高级定时器,我们能产生一系列PWM脉宽随时间变化的PWM波形,通过简单的RC滤波就可以将SPWM滤波成正弦波 5.软件设计过程 5.1 四路pwm输出配置 5.1.1 GPIO初始化 初始化引脚(PA6、PA7,PB0、PB1),这里拿出初始化PA6例子 GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RC
[单片机]
STM32 关于<font color='red'>定时器</font>相关问题的探讨(二)
剖析STM32-定时器2
4. 常用库函数 定时器参数初始化: void TIM_TimeBaseInit(TIM_TypeDef* TIMx,TIM_TimeBaseInitTypeDef*TIM_TimeBaseInitStruct); 结构体内部成员: typedef struct { uint16_t TIM_Prescaler; uint16_t TIM_CounterMode; uint16_t TIM_Period; uint16_t TIM_ClockDivision; uint8_t TIM_RepetitionCounter; } TIM_TimeBaseInitTypeDef; 声明方式(一般
[单片机]
Atmega16的定时器0使用
//经验正以下程序是正确的,可以实现LED 1s亮 1s灭 #include avr/io.h #include avr/interrupt.h #define uchar unsigned char #define uint unsigned int uint count; void init() { DDRB|=_BV(PB4)|_BV(PB5)|_BV(PB6)|_BV(PB7); PORTB&=~(_BV(PB4)|_BV(PB5)|_BV(PB6)|_BV(PB7)); TCNT0=155;//初值为55,即记数到255-155=100次溢出并进入定时器0中断函数 TIMSK|=_BV(TOIE0);//溢出中
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved