1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

How to set a alarm for my real tiime clock?

Discussion in 'Microcontrollers' started by IsaacChuah90, Oct 3, 2011.

  1. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    Hey guys, I'm new here. Nice to meet you all. Can I know how to set a alarm for my real time clock? Any coding can I refer to? Seeking for helps guys! Thanks....:)
     
  2. Rusttree

    Rusttree Member

    Joined:
    May 28, 2006
    Messages:
    276
    Likes:
    2
    Location:
    Phoenix, AZ
    Hi Isaac, welcome to the forum.

    You need to provide a little more information. Which microcontroller are you using? Is this your first project? What do you mean by an alarm? Do you want to program a speaker to make a sound after a certain amount of time has expired?

    Provide as much detail as you can and you'll increase your change of someone helping you out.
     
  3. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    Hi, Rusttree. Ya. This is my first project and it also is my final year project. I'm using PIC16F877A interface with DS1307 real time clock chip. I'm using mplab High-Tech C Compiler.The clock I'm doing now can run already, so now I want to add an alarm for this clock to become an alarm clock. I'm plan to using a passive infrared sensor and a buzzer for the alarm. For instance, when the buzzer is on, then I use the passive infrared sensor as the switch to switch off the alarm. Just like the normal clock we using now. Hope you guys can get what I mean. So I'm here to ask for any code can I use or refer to make the clock to become an alarm clock. Just like if the current time is equal to the alarm time, then the buzzer on. Hope can get the replies from you guys soon. Thanks!!:)
     
    Last edited: Oct 3, 2011
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Rusttree

    Rusttree Member

    Joined:
    May 28, 2006
    Messages:
    276
    Likes:
    2
    Location:
    Phoenix, AZ

    I don't know if anyone will provide you with code for that specific application. But we're happy to help you develop your own code.

    Sounds like you already have a pretty good idea of how you need to do this. Can you show what you've tried so far? Are there any particular concepts you're having trouble with?
     
  6. rmain1972

    rmain1972 Member

    Joined:
    Apr 13, 2011
    Messages:
    103
    Likes:
    2
    Location:
    Oklahoma City, OK USA
    It looks like the DS1307 doesn't have an internal alarm, so your going to have to write the alarm code from scratch. Are you just making an alarm that compares the time, or are you wanting to go into date, etc. It's simpler if you are just doing time. Read the hours, minutes, and seconds from the RTC, which it seems you are already doing because you say the clock is running, and compare it to your alarm time. Let me know if you need more help.
     
  7. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    Rusttree, now the LCD can show the time and date, I have done until that. Just don't have the idea how to write a code for the clock to make it become alarm clock. I know the code something like if the current time is equal to alarm time, then the buzzer is on. But I don't know how to define the current time and alarm time.


    rmain1972,ya. It does not have an internal alarm. So I would like to write the alarm code for it. But I'm don't have any idea how to write it. So hope can get helps from you guys. My idea is hope can store multiple alarm time in the RTC. But now I need deal with single alarm time first. Hope can get helps from you.

    Thanks a lot guys.:)
     
  8. Rusttree

    Rusttree Member

    Joined:
    May 28, 2006
    Messages:
    276
    Likes:
    2
    Location:
    Phoenix, AZ
    I'm a little confused. How are you displaying the current time and date on the LCD if you don't know how to access the current time in your code? Don't you need to access that data to display it to the screen?
     
  9. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    Rusttree, sorry for making you confused. Ya, I have done until show the current time and date on the LCD. I mean the coding how to let the PIC know what is current time and alarm time so that the buzzer will on will the alarm time is equal to the current time. Thanks for the helps. :)
     
  10. Rusttree

    Rusttree Member

    Joined:
    May 28, 2006
    Messages:
    276
    Likes:
    2
    Location:
    Phoenix, AZ
    Right, and my question is, how can you display the current time on the LCD screen if you don't know how to access the variable(s) corresponding to the current time? That seems contradictory.
     
  11. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    Sorry Rusttree. I still not very clear what you mean. What you mean by access the variable(s) corresponding to the current time?I'm poor in writing coding.Hope you don't mind.:) I get the source code from other website and I compiled it to my PIC so my LCD can show the current time and the rtc can keep running.Now I'm trying to write a code for adding an alarm into it. Hope can get helps from you guys. Appreciate the replies from you guys.
    Thanks!:)
     
    Last edited: Oct 4, 2011
  12. Rusttree

    Rusttree Member

    Joined:
    May 28, 2006
    Messages:
    276
    Likes:
    2
    Location:
    Phoenix, AZ
    Ah, you didn't write the original code. That clears up my confusion.

    With any kind of project like this, there's a million different ways to make it work. Therefore, even if someone were to give you example code that does what you want, as you originally asked, there's basically no chance it'll be compatible with your current project. So using someone else's code is useless to you in this circumstance.

    Instead, you can post the code you have here and we can help you through it to figure out how to modify what you have to add an alarm. Again, there's no one way to do it, so we'd have to see what you're starting with the suggest how you can move forward.
     
  13. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    Ok Rusttree.The coding I get is included 3 C files and 2 header files.The code is shown below.Thanks for the helps Rusttree. I really don't have the idea how to write the coding to add an alarm unless there is an example for me to refer. I will post it in 3 parts as it has 3 C files. It is quite long.Hope you guys can help me.Appreciate a lot guys.

    #include <htc.h>
    #include "i2c.h"



    /*******************************************************************************
    * PRIVATE GLOBAL VARIABLES *
    *******************************************************************************/

    // The flag to indicate whether an I2C error has occured.
    unsigned char b_i2c_error_flag = 0;



    /*******************************************************************************
    * PUBLIC FUNCTION: i2c_initialize
    *
    * PARAMETERS:
    * ~ void
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * Initialize the I2C module.
    *
    *******************************************************************************/
    void i2c_initialize(void)
    {
    // Set the SCL and SDA pin as input.
    TRISC3 = 1;
    TRISC4 = 1;

    // Set the I2C clock frequency.
    // 400kHz, SSPADD = (FOSC / (4 * F_I2C) ) - 1
    SSPADD = 12;

    // Select I2C master mode, clock = FOSC / (4 * (SSPADD+1) ).
    SSPM3 = 1;
    SSPM2 = 0;
    SSPM1 = 0;
    SSPM0 = 0;

    // Clear the Write Collision Detect bit.
    WCOL = 0;

    // Clear the Receive Overflow Indicator bit.
    SSPOV = 0;

    // Enable the MSSP module.
    SSPEN = 1;
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: b_i2c_check_error_flag
    *
    * PARAMETERS:
    * ~ void
    *
    * RETURN:
    * ~ The error flag of the previous I2C operation.
    * ~ Return 0 if no error. Return 1 otherwise.
    *
    * DESCRIPTIONS:
    * This function will check the error flag of the previous I2C operation.
    *
    *******************************************************************************/
    unsigned char b_i2c_check_error_flag(void)
    {
    return b_i2c_error_flag;
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: uc_i2c_read
    *
    * PARAMETERS:
    * ~ uc_slave_address - The I2C slave address.
    * ~ uc_register - The register that we want to read.
    *
    * RETURN:
    * ~ The data that we read from the I2C.
    *
    * DESCRIPTIONS:
    * This function will read a single byte of data using the I2C.
    *
    *******************************************************************************/
    unsigned char uc_i2c_read(unsigned char uc_slave_address, unsigned char uc_register)
    {
    // Buffer for the received byte.
    unsigned char uc_received_byte;

    // Clear the error flag before we start a new I2C operation.
    b_i2c_error_flag = 0;

    // Send start bit.
    SEN = 1;
    while (SEN == 1);

    // Send slave address and indicate to write.
    SSPBUF = (uc_slave_address << 1) & 0xfe;

    // Wait for slave to acknowledge.
    while (RW == 1);

    // If slave does not acknowledge...
    if (ACKSTAT == 1) {
    // Send stop bit.
    PEN = 1;
    while (PEN == 1);

    // Set the error flag and exit.
    b_i2c_error_flag = 1;
    return 0;
    }

    // Send the register address that we want to read.
    SSPBUF = uc_register;

    // Wait for slave to acknowledge.
    while (RW == 1);

    // If slave does not acknowledge...
    if (ACKSTAT == 1) {
    // Send stop bit.
    PEN = 1;
    while (PEN == 1);

    // Set the error flag and exit.
    b_i2c_error_flag = 1;
    return 0;
    }



    // Send repeated start bit.
    RSEN = 1;
    while (RSEN == 1);

    // Send slave address and indicate to read.
    SSPBUF = (uc_slave_address << 1) | 0x01;

    // Wait for slave to acknowledge.
    while (RW == 1);

    // If slave does not acknowledge...
    if (ACKSTAT == 1) {
    // Send stop bit.
    PEN = 1;
    while (PEN == 1);

    // Set the error flag and exit.
    b_i2c_error_flag = 1;
    return 0;
    }

    // Enable receive.
    RCEN = 1;

    // Wait until the data is received.
    unsigned long count = 10000L;
    while (BF == 0) {

    // If timeout...
    if (--count == 0) {
    // Send stop bit.
    PEN = 1;
    while (PEN == 1);

    // Set the error flag and exit.
    b_i2c_error_flag = 1;
    return 0;
    }
    }

    // Read the received data.
    uc_received_byte = SSPBUF;

    // Send Not Acknowledge.
    ACKDT = 1;
    ACKEN = 1;
    while (ACKEN == 1);

    // Send stop bit
    PEN = 1;
    while (PEN == 1);

    // Clear the error flag and return the received data.
    b_i2c_error_flag = 0;
    return uc_received_byte;
    }



    /*******************************************************************************
    * PRIVATE FUNCTION: uc_i2c_write
    *
    * PARAMETERS:
    * ~ uc_slave_address - The I2C slave address.
    * ~ uc_register - The register that we want to write.
    * ~ uc_data - The data that we want to write.
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * This function will write a single byte of data using the I2C.
    *
    *******************************************************************************/
    void uc_i2c_write(unsigned char uc_slave_address, unsigned char uc_register, unsigned char uc_data)
    {
    // Clear the error flag before we start a new I2C operation.
    b_i2c_error_flag = 0;

    // Send start bit.
    SEN = 1;
    while (SEN == 1);

    // Send slave address and indicate to write.
    SSPBUF = (uc_slave_address << 1) & 0xfe;

    // Wait for slave to acknowledge.
    while (RW == 1);

    // If slave does not acknowledge...
    if (ACKSTAT == 1) {
    // Send stop bit.
    PEN = 1;
    while (PEN == 1);

    // Set the error flag and exit.
    b_i2c_error_flag = 1;
    return;
    }

    // Send the register address that we want to write.
    SSPBUF = uc_register;

    // Wait for slave to acknowledge.
    while (RW == 1);

    // If slave does not acknowledge...
    if (ACKSTAT == 1) {
    // Send stop bit.
    PEN = 1;
    while (PEN == 1);

    // Set the error flag and exit.
    b_i2c_error_flag = 1;
    return;
    }

    // Send the data.
    SSPBUF = uc_data;

    // Wait for slave to acknowledge.
    while (RW == 1);

    // If slave does not acknowledge...
    if (ACKSTAT == 1) {
    // Send stop bit.
    PEN = 1;
    while (PEN == 1);

    // Set the error flag and exit.
    b_i2c_error_flag = 1;
    return;
    }

    // Send stop bit
    PEN = 1;
    while (PEN == 1);

    // Clear the error flag.
    b_i2c_error_flag = 0;
    }
     
  14. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    #include <htc.h>
    #include "i2c.h"
    #include "i2c_rtc.h"


    /*******************************************************************************
    * PRIVATE CONSTANTS *
    *******************************************************************************/

    // I2C Slave Address for the DS1307 RTC.
    #define RTC_ADDRESS 0b01101000

    // Oscillator Frequency.
    #define _XTAL_FREQ 20000000

    // UART baud rate
    #define UART_BAUD 9600


    /*******************************************************************************
    * PUBLIC FUNCTION: i2c_rtc_initialize
    *
    * PARAMETERS:
    * ~ void
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * Initialize the DS1307 RTC.
    *
    *******************************************************************************/
    void i2c_rtc_initialize(void)
    {
    unsigned int i;



    // The current value of the DS1307 RTC register.
    unsigned char uc_current_register_value;

    // Read back the current value of register "Seconds".
    uc_current_register_value = uc_i2c_read(RTC_ADDRESS, 0x00);

    // If the CH bit is set, clear it to enable the oscillator.
    if ((uc_current_register_value & 0x80) != 0) {
    uc_i2c_write(RTC_ADDRESS, 0x00, uc_current_register_value & 0x7f);

    // We need delay for the oscillator to start up.
    for (i = 0; i < 500; i++) {
    __delay_ms(1);
    }
    }

    // Read back the current value of register "Hours".
    uc_current_register_value = uc_i2c_read(RTC_ADDRESS, 0x02);

    // If it's in 12-hour mode, change it to 24-hour mode.
    if ((uc_current_register_value & 0x40) != 0) {
    uc_i2c_write(RTC_ADDRESS, 0x02, uc_current_register_value & 0xbf);
    }
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: uc_i2c_rtc_get_seconds
    *
    * PARAMETERS:
    * ~ void
    *
    * RETURN:
    * ~ The value for seconds.
    *
    * DESCRIPTIONS:
    * Get the value for seconds.
    *
    *******************************************************************************/
    unsigned char uc_i2c_rtc_get_seconds(void)
    {
    unsigned char uc_i2c_data;

    // Read the value of register "Seconds".
    uc_i2c_data = uc_i2c_read(RTC_ADDRESS, 0x00);

    // Convert the BCD to binary and return the value.
    return (uc_i2c_data & 0x0f) + (((uc_i2c_data >> 4) & 0x07) * 10);
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: i2c_rtc_set_seconds
    *
    * PARAMETERS:
    * ~ uc_value - The value for seconds.
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * Set the value for seconds.
    *
    *******************************************************************************/
    void i2c_rtc_set_seconds(unsigned char uc_value)
    {
    // The current value of the DS1307 RTC register.
    unsigned char uc_current_register_value;

    // Make sure the value is < 60 seconds.
    if (uc_value < 60) {

    // Change the value into BCD.
    uc_value = ((uc_value / 10) << 4) + (uc_value % 10);

    // Read back the current value of register "Seconds".
    uc_current_register_value = uc_i2c_read(RTC_ADDRESS, 0x00);

    // We only interested in the CH bit, mask out the others.
    uc_current_register_value &= 0x80;

    // Write to the I2C RTC.
    uc_i2c_write(RTC_ADDRESS, 0x00, uc_current_register_value | uc_value);
    }
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: uc_i2c_rtc_get_minutes
    *
    * PARAMETERS:
    * ~ void
    *
    * RETURN:
    * ~ The value for minutes.
    *
    * DESCRIPTIONS:
    * Get the value for minutes.
    *
    *******************************************************************************/
    unsigned char uc_i2c_rtc_get_minutes(void)
    {
    unsigned char uc_i2c_data;

    // Read the value of register "Minutes".
    uc_i2c_data = uc_i2c_read(RTC_ADDRESS, 0x01);

    // Convert the BCD to binary and return the value.
    return (uc_i2c_data & 0x0f) + ((uc_i2c_data >> 4) * 10);
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: i2c_rtc_set_minutes
    *
    * PARAMETERS:
    * ~ uc_value - The value for minutes.
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * Set the value for minutes.
    *
    *******************************************************************************/
    void i2c_rtc_set_minutes(unsigned char uc_value)
    {
    // Make sure the value is < 60 minutes.
    if (uc_value < 60) {

    // Change the value into BCD.
    uc_value = ((uc_value / 10) << 4) + (uc_value % 10);

    // Write to the I2C RTC.
    uc_i2c_write(RTC_ADDRESS, 0x01, uc_value);
    }
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: uc_i2c_rtc_get_hours
    *
    * PARAMETERS:
    * ~ void
    *
    * RETURN:
    * ~ The value for hours.
    *
    * DESCRIPTIONS:
    * Get the value for hours.
    *
    *******************************************************************************/
    unsigned char uc_i2c_rtc_get_hours(void)
    {
    unsigned char uc_i2c_data;

    // Read the value of register "Hours".
    uc_i2c_data = uc_i2c_read(RTC_ADDRESS, 0x02);

    // Convert the BCD to binary and return the value.
    return (uc_i2c_data & 0x0f) + (((uc_i2c_data >> 4) & 0x03) * 10);
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: i2c_rtc_set_hours
    *
    * PARAMETERS:
    * ~ uc_value - The value for hours.
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * Set the value for hours.
    *
    *******************************************************************************/
    void i2c_rtc_set_hours(unsigned char uc_value)
    {
    // The current value of the DS1307 RTC register.
    unsigned char uc_current_register_value;



    // Make sure the value is < 24 hours.
    if (uc_value < 24) {

    // Change the value into BCD.
    uc_value = ((uc_value / 10) << 4) + (uc_value % 10);

    // Read back the current value of register "Hours".
    uc_current_register_value = uc_i2c_read(RTC_ADDRESS, 0x02);

    // We only interested in the 12-hour/24-hour mode bit, mask out the others.
    uc_current_register_value &= 0x40;

    // Write to the I2C RTC.
    uc_i2c_write(RTC_ADDRESS, 0x02, uc_current_register_value | uc_value);
    }
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: uc_i2c_rtc_get_day
    *
    * PARAMETERS:
    * ~ void
    *
    * RETURN:
    * ~ The value for day.
    *
    * DESCRIPTIONS:
    * Get the value for day.
    *
    *******************************************************************************/
    unsigned char uc_i2c_rtc_get_day(void)
    {
    // Read and return the value of register "Day".
    return uc_i2c_read(RTC_ADDRESS, 0x03);
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: i2c_rtc_set_day
    *
    * PARAMETERS:
    * ~ uc_value - The value for day.
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * Set the value for day.
    *
    *******************************************************************************/
    void i2c_rtc_set_day(unsigned char uc_value)
    {
    // Make sure the value is within 1 - 7.
    if (uc_value > 0 && uc_value <= 7) {
    // Write to the I2C RTC.
    uc_i2c_write(RTC_ADDRESS, 0x03, uc_value);
    }
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: uc_i2c_rtc_get_date
    *
    * PARAMETERS:
    * ~ void
    *
    * RETURN:
    * ~ The value for date.
    *
    * DESCRIPTIONS:
    * Get the value for date.
    *
    *******************************************************************************/
    unsigned char uc_i2c_rtc_get_date(void)
    {
    unsigned char uc_i2c_data;

    // Read the value of register "Date".
    uc_i2c_data = uc_i2c_read(RTC_ADDRESS, 0x04);

    // Convert the BCD to binary and return the value.
    return (uc_i2c_data & 0x0f) + ((uc_i2c_data >> 4) * 10);
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: i2c_rtc_set_date
    *
    * PARAMETERS:
    * ~ uc_value - The value for date.
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * Set the value for date.
    *
    *******************************************************************************/
    void i2c_rtc_set_date(unsigned char uc_value)
    {
    // Make sure the value is within 1 - 31.
    if (uc_value > 0 && uc_value <= 31) {

    // Change the value into BCD.
    uc_value = ((uc_value / 10) << 4) + (uc_value % 10);

    // Write to the I2C RTC.
    uc_i2c_write(RTC_ADDRESS, 0x04, uc_value);
    }
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: uc_i2c_rtc_get_month
    *
    * PARAMETERS:
    * ~ void
    *
    * RETURN:
    * ~ The value for month.
    *
    * DESCRIPTIONS:
    * Get the value for month.
    *
    *******************************************************************************/
    unsigned char uc_i2c_rtc_get_month(void)
    {
    unsigned char uc_i2c_data;

    // Read the value of register "Month".
    uc_i2c_data = uc_i2c_read(RTC_ADDRESS, 0x05);

    // Convert the BCD to binary and return the value.
    return (uc_i2c_data & 0x0f) + ((uc_i2c_data >> 4) * 10);
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: i2c_rtc_set_month
    *
    * PARAMETERS:
    * ~ uc_value - The value for month.
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * Set the value for month.
    *
    *******************************************************************************/
    void i2c_rtc_set_month(unsigned char uc_value)
    {
    // Make sure the value is within 1 - 12.
    if (uc_value > 0 && uc_value <= 12) {

    // Change the value into BCD.
    uc_value = ((uc_value / 10) << 4) + (uc_value % 10);

    // Write to the I2C RTC.
    uc_i2c_write(RTC_ADDRESS, 0x05, uc_value);
    }
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: uc_i2c_rtc_get_year
    *
    * PARAMETERS:
    * ~ void
    *
    * RETURN:
    * ~ The value for year.
    *
    * DESCRIPTIONS:
    * Get the value for year.
    *
    *******************************************************************************/
    unsigned char uc_i2c_rtc_get_year(void)
    {
    unsigned char uc_i2c_data;

    // Read the value of register "Year".
    uc_i2c_data = uc_i2c_read(RTC_ADDRESS, 0x06);

    // Convert the BCD to binary and return the value.
    return (uc_i2c_data & 0x0f) + ((uc_i2c_data >> 4) * 10);
    }



    /*******************************************************************************
    * PUBLIC FUNCTION: i2c_rtc_set_year
    *
    * PARAMETERS:
    * ~ uc_value - The value for year.
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * Set the value for year.
    *
    *******************************************************************************/
    void i2c_rtc_set_year(unsigned char uc_value)
    {
    // Make sure the value is < 100.
    if (uc_value < 100) {

    // Change the value into BCD.
    uc_value = ((uc_value / 10) << 4) + (uc_value % 10);

    // Write to the I2C RTC.
    uc_i2c_write(RTC_ADDRESS, 0x06, uc_value);
    }
    }
     
  15. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    #include <pic.h>
    #include "i2c.h"
    #include "i2c_rtc.h"

    //==========================================================================================
    // configuration
    //=========================================================================================
    __CONFIG ( 0x3F32 );

    //==========================================================================================
    // define
    //==========================================================================================
    #define sw0 RC0
    #define sw1 RC1
    #define sw2 RC2
    #define rs RA0
    #define e RA1
    #define led_yellow RA2
    #define led_white RA3
    #define lcd_data PORTB
    #define sdata RC4 // SDA
    #define tclk RC3 // SCL



    //===========================================================================================
    // global variable
    //===========================================================================================
    unsigned char step=0;
    unsigned char store=0;
    unsigned char clksec=0;
    unsigned char clkmin=0;
    unsigned char clkhrs=0;
    unsigned char day=0;
    unsigned char date=0;
    unsigned char month=0;
    unsigned char year=0;

    unsigned char secondh=0;
    unsigned char secondl=0;
    unsigned char minutesh=0;
    unsigned char minutesl=0;
    unsigned char hourh=0;
    unsigned char hourl=0;
    unsigned char dateh=0;
    unsigned char datel=0;
    unsigned char monthh=0;
    unsigned char monthl=0;
    unsigned char yearh=0;
    unsigned char yearl=0;

    //==============================================================================================
    // function prototype
    //==============================================================================================
    void delay(unsigned long data);
    void send_config(unsigned char data);
    void send_char(unsigned char data);
    void e_pulse(void);
    void lcd_goto(unsigned char data);
    void lcd_clr(void);
    void send_string(const char *s);
    void send_dec(unsigned long data,unsigned char num_dig);
    void writertc(void);
    void readrtc(void); // Read RTC

    //============================================================================================
    // main function
    //============================================================================================
    void main(void)
    {
    i2c_initialize();
    i2c_rtc_initialize();
    unsigned char i;

    ADCON1 = 0b00000110; //set all portA as digital I/O
    TRISA = 0b00000000; //set all PORTA pin as OUTPUT
    TRISB = 0b00000000; //set all PORTB pin as output
    TRISC = 0b00011111; //set all PORTC pin as output

    led_white=0; //led white off
    led_yellow=0; //led yellow off

    send_config(0b00000001); //clear display at lcd
    send_config(0b00000010); //Lcd Return to home
    send_config(0b00000110); //entry mode-cursor increase 1
    send_config(0b00001100); //diplay on, cursor off and cursor blink off
    send_config(0b00111000); //function

    readrtc();
    }
    //================================================================================================
    // Write to RTC function
    //================================================================================================

    void writertc(void)
    {
    led_yellow=0; //led yellow off
    led_white=1; //led white on


    while(sw0==0)continue; //waiting sw0 to depress

    // SET HOUR ===========================================================

    while(sw0==1) //infinity loop if switch0 is not pressed
    {
    if(sw1==1) //if switch 1 is not pressed
    {
    lcd_goto(0); //maintain current hour value on LCD and make it blinking
    send_dec(clkhrs,2);
    delay(10000);
    lcd_goto(1);
    send_char(' ');
    lcd_goto(0);
    send_char(' ');
    delay(10000);
    }
    if(sw1==0) //if switch 1 is pressed
    {
    while(sw1==0)continue; //wait switch1 to depress

    if(clkhrs<=22)clkhrs++;
    else clkhrs=0;
    }
    }

    lcd_goto(0); //overwrite changed hour value on LCD
    send_dec(clkhrs,2);
    while(sw0==0)continue; //wait switch 0 to be depressed


    // SET MINUTES ====================================================================

    while(sw0==1) //infinity loop if switch0 is not pressed
    {
    if(sw1==1) //if switch 1 is not pressed
    {
    lcd_goto(3); //maintain current minute value on LCD and make it blinking
    send_dec(clkmin,2);
    delay(10000);
    lcd_goto(4);
    send_char(' ');
    lcd_goto(3);
    send_char(' ');
    delay(10000);
    }
    if(sw1==0) //if switch 1 is pressed
    {
    while(sw1==0)continue; //wait switch1 to depress

    if(clkmin<=58) clkmin++;
    else clkmin=0;
    }
    }

    lcd_goto(3); //overwrite changed minute value on LCD
    send_dec(clkmin,2);
    while(sw0==0)continue; //wait switch 0 to be depressed


    // SET SECONDS ===============================================================

    while(sw0==1) //infinity loop if switch0 is not pressed
    {

    if(sw1==1) //if switch 1 is not pressed
    {
    lcd_goto(6); //maintain current minute value on LCD and make it blinking
    send_dec(clksec,2);
    delay(10000);
    lcd_goto(7);
    send_char(' ');
    lcd_goto(6);
    send_char(' ');
    delay(10000);
    }
    if(sw1==0) //if switch 1 is pressed
    {
    while(sw1==0)continue; //wait switch1 to depress

    if(clksec<=58) clksec++;
    else clksec=0;
    }
    }

    lcd_goto(6); //overwrite changed second value on LCD
    send_dec(clksec,2);
    while(sw0==0)continue; //wait switch 0 to be depressed



    // SET DATE =========================================

    while(sw0==1) //infinity loop if switch0 is not pressed
    {

    if(sw1==1) //if switch 1 is not pressed
    {
    lcd_goto(20); //maintain current date value on LCD and make it blinking
    send_dec(date,2);
    delay(10000);
    lcd_goto(21);
    send_char(' ');
    lcd_goto(20);
    send_char(' ');
    delay(10000);
    }
    if(sw1==0) //if switch 1 is pressed
    {
    while(sw1==0)continue; //wait switch1 to depress

    if(date<=30) date++;
    else date=1;
    }
    }

    lcd_goto(20); //overwrite changed date value on LCD
    send_dec(date,2);
    while(sw0==0)continue; //wait switch 0 to be depressed

    // SET MONTH ==========================================

    while(sw0==1) //infinity loop if switch0 is not pressed
    {

    if(sw1==1) //if switch 1 is not pressed
    {
    lcd_goto(23); //maintain current month value on LCD and make it blinking
    send_dec(month,2);
    delay(10000);
    lcd_goto(24);
    send_char(' ');
    lcd_goto(23);
    send_char(' ');
    delay(10000);
    }
    if(sw1==0) //if switch 1 is pressed
    {
    while(sw1==0)continue; //wait switch1 to depress

    if(month<=11) month++;
    else month=1;
    }
    }

    lcd_goto(23); //overwrite changed month value on LCD
    send_dec(month,2);
    while(sw0==0)continue; //wait switch 0 to be depressed


    // SET YEAR =======================================================================================

    while(sw0==1) //infinity loop if switch0 is not pressed
    {

    if(sw1==1) //if switch 1 is not pressed
    {
    lcd_goto(26); //maintain current month value on LCD and make it blinking
    send_dec(year,2);
    delay(10000);
    lcd_goto(27);
    send_char(' ');
    lcd_goto(26);
    send_char(' ');
    delay(10000);
    }
    if(sw1==0) //if switch 1 is pressed
    {
    while(sw1==0)continue; //wait switch1 to depress

    if(year<=99) year++;
    else year=0;
    }
    }

    lcd_goto(26); //overwrite changed year value on LCD
    send_dec(year,2);
    while(sw0==0)continue; //wait switch 0 to be depressed


    // SET DAY ====================================================================================

    while(sw0==1) //infinity loop if switch0 is not pressed
    {
    if(sw1==1) //if switch 1 is not pressed
    {
    if(day==7) //maintain current day value on LCD and make it blinking
    {
    lcd_goto(31);
    send_string("SUN");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==1)
    {
    lcd_goto(31);
    send_string("MON");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==2)
    {
    lcd_goto(31);
    send_string("TUE");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==3)
    {
    lcd_goto(31);
    send_string("WED");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==4)
    {
    lcd_goto(31);
    send_string("THU");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==5)
    {
    lcd_goto(31);
    send_string("FRI");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==6)
    {
    lcd_goto(31);
    send_string("SAT");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    }
    else //if switch 1 is pressed
    {
    while(sw1==0)continue; //wait switch1 to depress
    if(day>6) //if day value greater than 11
    {
    day=1; //change setday variable to 1
    }
    else
    {
    day+=1; //increse day value by 1
    }
    }
    }
    if(sw1==0)
    {
    if(day==7) //overwrite changed day value on LCD
    {
    lcd_goto(31);
    send_string("SUN");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==1)
    {
    lcd_goto(31);
    send_string("MON");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==2)
    {
    lcd_goto(31);
    send_string("TUE");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==3)
    {
    lcd_goto(31);
    send_string("WED");
    }
    else if(day==4)
    {
    lcd_goto(31);
    send_string("THU");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==5)
    {
    lcd_goto(31);
    send_string("FRI");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    else if(day==6)
    {
    lcd_goto(31);
    send_string("SAT");
    delay(10000);
    lcd_goto(31);
    send_char(' ');
    send_char(' ');
    send_char(' ');
    delay(10000);
    }
    }
    while(sw0==0)continue; //wait switch 0 to be depressed

    i2c_rtc_set_seconds(clksec); //send changed second
    i2c_rtc_set_minutes(clkmin); //send changed minute
    i2c_rtc_set_hours(clkhrs); //send changed hour
    i2c_rtc_set_day(day); //send changed day
    i2c_rtc_set_date(date); //send changed date
    i2c_rtc_set_month(month); //send changed month
    i2c_rtc_set_year(year); //send changed year

    }

    //===================================================================================
    // Read RTC function
    //===================================================================================

    void readrtc(void)
    {
    while(1)
    {
    led_yellow=1;
    led_white=0;
    if(sw0==0) //reset button
    {
    writertc(); //goto write mode
    }
    else
    {
    clksec=uc_i2c_rtc_get_seconds(); //read 1 byte seconds
    clkmin= uc_i2c_rtc_get_minutes(); //read 1 byte min
    clkhrs=uc_i2c_rtc_get_hours(); //read 1 byte hrs
    day=uc_i2c_rtc_get_day(); //read 1 byte day
    date=uc_i2c_rtc_get_date(); //read 1 byte date
    month=uc_i2c_rtc_get_month(); //read 1 byte month
    year=uc_i2c_rtc_get_year(); //read 1 byte year

    lcd_goto(0);
    send_dec(clkhrs,2);

    lcd_goto(2); //display ':'
    send_char(0x3A);

    lcd_goto(3);
    send_dec(clkmin,2);

    lcd_goto(5); //display ':'
    send_char(0x3A);

    lcd_goto(6);
    send_dec(clksec,2);

    if(day==7) // display day
    {
    lcd_goto(31);
    send_string("SUN");
    }
    else if(day==1)
    {
    lcd_goto(31);
    send_string("MON");
    }
    else if(day==2)
    {
    lcd_goto(31);
    send_string("TUE");
    }
    else if(day==3)
    {
    lcd_goto(31);
    send_string("WED");
    }
    else if(day==4)
    {
    lcd_goto(31);
    send_string("THU");
    }
    else if(day==5)
    {
    lcd_goto(31);
    send_string("FRI");
    }
    else if(day==6)
    {
    lcd_goto(31);
    send_string("SAT");
    }

    lcd_goto(20); // display date
    send_dec(date,2);

    lcd_goto(22); //display '/'
    send_char(0x2F);


    lcd_goto(23); // display month
    send_dec(month,2);

    lcd_goto(25); // display '/'
    send_char(0x2F);

    lcd_goto(26); // display year
    send_dec(year,2);

    }
    }
    }

    //==========================================================================
    // LCD functions
    //==========================================================================
    void delay(unsigned long data)
    {
    for( ;data>0;data-=1);
    }
    void send_config(unsigned char data)
    {
    rs=0; //clear rs into config mode
    lcd_data=data;
    delay(300);
    e_pulse();
    }
    void send_char(unsigned char data)
    {
    rs=1; //set rs into write mode
    lcd_data=data;
    delay(300);
    e_pulse();
    }
    void e_pulse(void)
    {
    e=1;
    delay(300);
    e=0;
    delay(300);
    }
    void lcd_goto(unsigned char data)
    {
    if(data<16)
    {
    send_config(0x80+data);
    }
    else
    {
    data=data-20;
    send_config(0xc0+data);
    }
    }
    void lcd_clr(void)
    {
    send_config(0x01);
    delay(350);
    }
    void send_string(const char *s)
    {
    unsigned char i=0;
    while (s && *s)send_char (*s++);
    }
    void send_dec(unsigned long data,unsigned char num_dig)
    {

    if(num_dig>=10)
    {
    data=data%10000000000;
    send_char(data/1000000000+0x30);
    }
    if(num_dig>=9)
    {
    data=data%1000000000;
    send_char(data/100000000+0x30);
    }
    if(num_dig>=8)
    {
    data=data%100000000;
    send_char(data/10000000+0x30);
    }
    if(num_dig>=7)
    {
    data=data%10000000;
    send_char(data/1000000+0x30);
    }
    if(num_dig>=6)
    {
    data=data%1000000;
    send_char(data/100000+0x30);
    }
    if(num_dig>=5)
    {
    data=data%100000;
    send_char(data/10000+0x30);
    }
    if(num_dig>=4)
    {
    data=data%10000;
    send_char(data/1000+0x30);
    }
    if(num_dig>=3)
    {
    data=data%1000;
    send_char(data/100+0x30);
    }
    if(num_dig>=2)
    {
    data=data%100;
    send_char(data/10+0x30);
    }
    if(num_dig>=1)
    {
    data=data%10;
    send_char(data+0x30);
    }
    }
     
  16. Rusttree

    Rusttree Member

    Joined:
    May 28, 2006
    Messages:
    276
    Likes:
    2
    Location:
    Phoenix, AZ
    In the future, please attach the files rather than copy-pasting the text into the post. As it is now, you have to scroll up and down several pages to get past the code you pasted, which is obnoxious. If you simply attach the files, it's much easier for everyone involved.

    This code is exceptionally well written, so whoever wrote it deserves credit. Best of all, they left it very easy to implement your alarm clock. In the last file you posted, there is a section labelled "Read RTC function". A few lines below that are several variables that are read from the real-time clock:

    Code (text):

    clksec=uc_i2c_rtc_get_seconds(); //read 1 byte seconds
    clkmin= uc_i2c_rtc_get_minutes(); //read 1 byte min
    clkhrs=uc_i2c_rtc_get_hours(); //read 1 byte hrs
     
    Those are the seconds, minutes, and hours of the current time. You probably only care about minutes and hours for your alarm. So all you need to do is create 2 new variables for minutes and hours for your alarm. Let's call them alarmMin and alarmHrs. In each pass, you just need to compare clkmin and clkhrs to alarmMin and alarmHrs, respectively. If they both match, turn on the alarm.

    Code (text):

    ...
    clkmin= uc_i2c_rtc_get_minutes(); //read 1 byte min
    clkhrs=uc_i2c_rtc_get_hours(); //read 1 byte hrs
    ...
    if ( (clkmin == alarmMin) && (clkhrs == alarmHrs) )
    {
        activateAlarm();
    }
     
    Of course, alarmMin and alarmHrs will have been defined as two set values earlier in your code.

    That make sense?
     
    Last edited: Oct 5, 2011
  17. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    Ya.Sorry Rusttree,In the future I will attach the file instead of copy and past the text into the post.Hope you don't mind.So can I know how to define the 2 set values of alarmMin and alarmHrs?Is it almost like the code for clkmin and clkhrs?Thanks for the helps Rusttree.Hope to see your reply soon.:)
     
    Last edited: Oct 6, 2011
  18. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,642
    Likes:
    109
    Location:
    Michigan, USA
    Is this an existing project somewhere on the web? If so, do you have a link, please?
     
  19. Rusttree

    Rusttree Member

    Joined:
    May 28, 2006
    Messages:
    276
    Likes:
    2
    Location:
    Phoenix, AZ
    Yes, it's just like the code for clkmin and clkhrs. Under the section "global variable" you'll see how all the variables are instantiated and defined. That's a good place to add your two new variables. Just copy the same syntax. And instead of setting them equal to zero, you can set them equal to the values you want your alarm to go off.

    Give it a try and then post what you did here. We'll critique and tell you how it looks.

    P.S. If it's a short chunk of code, you can copy-paste it rather than attach it. Use your judgement.
     
    Last edited: Oct 6, 2011
  20. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    I think so.I found it long times ago.Don't worry,I will find it out.Once I find it for sure I will post it and share it out.:)
     
    Last edited: Oct 6, 2011
  21. IsaacChuah90

    IsaacChuah90 New Member

    Joined:
    Oct 3, 2011
    Messages:
    66
    Likes:
    0
    Rusttree,now I'm writing the coding for the alarm you told me in previous post.
    Code (text):
    unsigned_char alarmMin=0;
    unsigned_char alarmHrs=0;
    But I feel a bit confused,you said that I can set the alarmMin and alarmHrs to the values I want?I can't get what you mean.Besides,the coding for comparing the time is it write under Read RTC_function?
    Code (text):
    clksec=uc_i2c_rtc_get_seconds();    //read 1 byte seconds
    clkmin=uc_i2c_rtc_get_minutes();    //read 1 byte min
    clkhrs=uc_i2c_rtc_get_hours();      //read 1 byte hrs
    alarmMin=uc_i2c_rtc_get_minutes();
    alarmHrs=uc_i2c_rtc_get_hours();
    After that then write the if else statement for comparing the time?If I'm wrong please correct me.Thank you.:)
     
    Last edited: Oct 7, 2011

Share This Page