Wiblocks --- NB1A RTC Alarms

NB1A RTC Alarms

This program initializes the DS1337 real-time clock (RTC) to output a time and date string every second to the serial port. Whenever the value of the seconds count gets to twenty the DS1337 will interrupt the ATmega328 and output the string *** ALARM ***

NB1A RTC Alarms

#include <avr/interrupt.h>    
#include <avr/io.h>  

#include <LED_debug.h>
#include <TWI.h>
#include <RTC.h>

#define ON  HIGH
#define OFF LOW

#define int_enable   PCICR  |=  (1 << PCIE2)
#define int_disable  PCICR  &= ~(1 << PCIE2)

#define RTC_ALARM1_OUTPUT 6 // PD6
#define RTC_ALARM1_INT    PCINT22

#define RTC_ALARM2_OUTPUT 5 // PD5
#define RTC_ALARM2_INT    PCINT21

// PCI2 triggers for PCINT23..16
// PCI1 triggers for PCINT14..8
// PCI0 triggers for PCINT7..0 

LED_debug led;
RTC       rtc;

unsigned char alarm_flag = 0;
unsigned char intdata = 0;

void setup() {

  // Compensating for the 12MHz XTAL
  // 12800 = (16/12) * 9600
  // 25600 = (16/12) * 19200

  Serial.begin(12800);

  // setup the TWI 

  TWBR = TWI_TWBR;             // Set bit rate register (Baudrate). Defined in TWI.h  
  TWDR = 0xFF;                 // Default content = SDA released.
  TWCR = (1<<TWEN)|            // Enable TWI-interface and release TWI pins.
         (0<<TWIE)|(0<<TWINT)| // Disable Interupt.
         (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|  // No Signal requests.
         (0<<TWWC);


  // enable pullup on alarm1 output

  pinMode(RTC_ALARM1_OUTPUT, INPUT);
  digitalWrite(RTC_ALARM1_OUTPUT, HIGH);

  // initialize the date
  // rtc.set_date(2009, 8, 25);

  // intialize the clock
  // rtc.set_time(15, 0, 0);


  // Initialize the control register for a 32768Hz square wave
  // and disable the square wave output

  // RTC_RS2 | RTC_RS1 ..... Rate Select, square wave output = 32768Hz
  // RTC_INTCN ............. Interrupt Control (=1 interrupts activated,
  //                         no square wave on INTB

  rtc.write_reg(RTC_REG_CONTROL, RTC_RS2 | RTC_RS1 | RTC_INTCN);

  // Setup ALARM1 to alarm when the seconds count equals 20
  // and then enable the ALARM1

  // RTC_ALARM1_MODE2 ..... Alarm when seconds match
  // dow .................. 0
  // hours ................ 0
  // minutes .............. 0
  // seconds .............. 20
  
  rtc.set_alarm1(RTC_ALARM1_MODE2, 0, 0, 0, 20);
  rtc.enable_alarm1();

  // Initialize the pin change interrupt mask for the
  //  pin that is connected to the RTC /INTA output. 

  PCMSK2 |= (1 << RTC_ALARM1_INT);

  // Enable the pin change interrupts

  int_enable;

}

void loop() {
  char timestr[22];
  while(1) {
    rtc.read_regs();
    rtc.localtime(timestr);
    Serial.print(timestr);
    Serial.print("\n");
    led.blink(1); 
    delay(1000);

    // If there was an alarm then print the alarm
    // message, clear the alarms and re-enable the
    // interrupts.

    if (alarm_flag) {
      int_disable;
      Serial.print("*** ALARM ***\n");
      alarm_flag = 0;
      rtc.clear_alarm1();
      delay(1000);
      PCMSK2 |= (1 << RTC_ALARM1_INT);
      int_enable;
    }
  }
}


// Both RTC alarms call this routine.  When this 
// routine is called the alarm flag is set and 
// the pin change mask is cleared. 

// interrupt flag. The interrupt flags are read and 
// reset in the main loop.

ISR( PCINT2_vect )
{
  if (digitalRead(RTC_ALARM1_OUTPUT) == 0) {
    alarm_flag |= (1<<RTC_ALARM1_OUTPUT);
    PCMSK2 &= ~(1<<RTC_ALARM1_OUTPUT);
  }
}