hi,
In software side, it is multiplex, xc8 comp to disp HH:MM:SEC, mcu reading from rtc readng at 24hrs format and then in software it is converted to 12hrs farmat.
H/W, 7seg CC, RTC1307.
All are working correctly , now I want to add a feature that is, when the time reach at 2:30 (at night)the disp will be turned OFF and after 2:32 (at night) the disp will turn ON. The code attched here is working all the said time(ie, as every 2.30 start OFF and evert 2.32 start ON), whereas i need only at night, so if 1st time is turned ON and OFF then for 2nd time(which is day time) no need and vice-versa, and 3rd. time what was in 1st time.
As per code attached here, Once turned OFF at said time at 2.30 & it ON at 2.32, when it ON then i set the time by BUTTON once to keep ON the disp for this 2nd. time but it going OFF again.
S, is the code ok or what should i modify either at BUTTON rour or Main routine.
Code is at Main()
// TIME FORMAT 24>>12 HRS
if (hour <= 12)
{
hour = hour;
PowerSave = 1;
}
else
{
PowerSave = 0;
hour = (hour - 12);
}
// For particular time display to be TURNED OFF and Again ON
if (PowerSave == 1)
{
if ((hour == 2 && min >= 30) && (hour == 2 && min <= 31))
{
INTCONbits.T0IE = 0;
}
else
INTCONbits.T0IE = 1;
}
Sub routine for BUTTON
uint8_t edit(uint8_t parameter)
{
while(debounce()); // call debounce function (wait for B1 to be released)
while(1)
{
while(!BUTTON2) // if button B2 is pressed
{
parameter++;
__delay_ms(300); //this delay for prevent several count on one press
if (i == 0 && parameter <= 12)
PowerSave &= 0x01;
if(i == 0 && parameter > 12) // if hours > 23 ==> hours = 0
parameter = 1;
if(i == 1 && parameter > 59) // if minutes > 59 ==> minutes = 0
parameter = 0;
if (i == 0)
{
hour_1 = (parameter % 10);
hour_10 = (parameter / 10);
__delay_ms(10);
}
if (i == 1)
{
min_1 = (parameter % 10);
min_10 = (parameter / 10);
__delay_ms(10); //delay from 200 to 10 minimize to prevent blink on when update time
}
}
if(!BUTTON1) // if button B1 is pressed
if(debounce()) // call debounce function (make sure if B1 is pressed)
{
i++; // increment 'i' for the next parameter
return parameter; // return parameter value and exit
}
}
}
TNX
put in the main function and while checking the condition check the value of flag change. If you want more to help you then post complete code i will try to place the bool wherever necessary according to the application
Hi Pandit,
Pl looks the code in .TXT format here.
What is happening::
1) Button is used to set the time(2:29) nearer to predefined OFF stage, some times it is going OFF and ON (at 2:31), and once OFF/ON completed for the first time
2) Then it should be keep ON( that means the time is DAY 2:30AM, i set the time nearer to predefined by button)
3) Again after set at nearer to predefined time (that means the time is 2:30 PM) - the it should be OFF at this stage. and continue continuously those all three stage one after another.
I have modified under //edit(), and while() at main() function to get this result but irregularity is noticed that means once point 1 is comes then it is coming after some stage latter not interval of one stage.
#include <xc.h> #include <stdint.h> // set configuration words #pragma config CONFIG1 = 0x2CD4 #pragma config CONFIG2 = 0x0700 //----------------------------------------------------------------------------- // Function Prototypes //----------------------------------------------------------------------------- //END_Function Prototypes ----------------------------------------------------- #define _XTAL_FREQ 8000000 #define TRUE 1 #define FALSE 0 #define HOURS_TENS 0 #define HOURS_ONES 1 #define MINUTES_TENS 2 #define MINUTES_ONES 3 #define SECONDS_TENS 4 #define SECONDS_ONES 5 #define DIGIT_ANODE_MASK 0xC0; #define HRTEN 0b00000001 // control pin A0 #define HRONE 0b00000010 // A1 #define MNTEN 0b00000100 // A2 #define MNONE 0b00001000 #define SCTEN 0b00010000 #define SCONE 0b00100000 //A5 // button definitions #define BUTTON1 RB0 // button B1 is connected to RB0 pin #define BUTTON2 RB1 // button B2 is connected to RB1 pin static uint8_t g_current_digit = 0; static bit colons; static bit ampm; const unsigned char SEGMENT_MAP[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; uint8_t i, sec, min, hour, m_day, month, year; uint8_t sec_1, sec_10, min_1, min_10, hour_1, hour_10; //-------------------------------------------------------------------------------------------------------------------------------------------- // I2C FUNCTION //-------------------------------------------------------------------------------------------------------------------------------------------- void I2C_Init(uint32_t i2c_clk_freq) { SSPCON = 0x28; // configure MSSP module to work in I2C mode SSPADD = (_XTAL_FREQ/(4 * i2c_clk_freq)) - 1; // set I2C clock frequency SSPSTAT = 0; } void I2C_Start() { while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); // wait for MSSP module to be free (not busy) SEN = 1; // initiate start condition } void I2C_Repeated_Start() { while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); // wait for MSSP module to be free (not busy) RSEN = 1; // initiate repeated start condition } void I2C_Stop() { while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); // wait for MSSP module to be free (not busy) PEN = 1; // initiate stop condition } void I2C_Write(uint8_t i2c_data) { while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); // wait for MSSP module to be free (not busy) SSPBUF = i2c_data; // update buffer } uint8_t I2C_Read(uint8_t ack) { uint8_t _data; while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); // wait for MSSP module to be free (not busy) RCEN = 1; while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); // wait for MSSP module to be free (not busy) _data = SSPBUF; // read data from buffer while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); // wait for MSSP module to be free (not busy) // send acknowledge pulse ? (depends on ack, if 1 send, otherwise don't send) ACKDT = !ack; ACKEN = 1; return _data; // return data read } //------------------------------------------------------------------------------------------------------------------------ // Interrupt //------------------------------------------------------------------------------------------------------------------------ void interrupt Timer0_ISR(void) { if(INTCONbits.T0IF && INTCONbits.T0IE) { TMR0 = 2; INTCONbits.T0IF = 0; PORTA &= DIGIT_ANODE_MASK; PORTD = 0x00; switch(g_current_digit) { case HOURS_TENS: { PORTD = SEGMENT_MAP[hour_10]; PORTA = HRTEN; g_current_digit = HOURS_ONES; } } break; case HOURS_ONES: { PORTD = SEGMENT_MAP[hour_1]; PORTA = HRONE; //LATCbits.LATC5 = 0b0; g_current_digit = MINUTES_TENS; } break; case MINUTES_TENS: { PORTD = SEGMENT_MAP[min_10]; PORTA = MNTEN; g_current_digit = MINUTES_ONES; } break; case MINUTES_ONES: { PORTD = SEGMENT_MAP[min_1]; PORTA = MNONE; g_current_digit = SECONDS_TENS; } break; case SECONDS_TENS: { PORTD = SEGMENT_MAP[sec_10]; PORTA = SCTEN; g_current_digit = SECONDS_ONES; } break; case SECONDS_ONES: { PORTD = SEGMENT_MAP[sec_1]; PORTA = SCONE; g_current_digit = HOURS_TENS; } break; default: { g_current_digit = HOURS_TENS; } } } //------------------------------------------------------------------------------------------------------------------------ // DEBOUNCE OF BUTTON //------------------------------------------------------------------------------------------------------------------------ __bit debounce () { uint8_t count = 0; for(uint8_t i = 0; i < 5; i++) { if (BUTTON1 == 0) count++; __delay_ms(10); } if(count > 2) return 1; else return 0; } //------------------------------------------------------------------------------------------------------------------------ // START OF BUTTON ROUTINE PARAMETER //------------------------------------------------------------------------------------------------------------------------ uint8_t edit(uint8_t parameter) { while(debounce()); // call debounce function (wait for B1 to be released) while(1) { while(!BUTTON2) // if button B2 is pressed { parameter++; __delay_ms(300); //this delay for prevent several count on one press // if (i == 0 && parameter <= 12) //PowerSave &= 0x01; if(i == 0 && parameter > 23 ) // if hours > 23 ==> hours = 0 parameter = 0; if(i == 1 && parameter > 59) // if minutes > 59 ==> minutes = 0 parameter = 0; if (i == 0) { if (parameter == 0)//24 { hour_1 = ((12 - parameter) % 10); hour_10 = ((12 - parameter) / 10); __delay_ms(10); ampm = TRUE; } else if (parameter >= 1 && parameter <= 12 ) { hour_1 = (parameter % 10); hour_10 = (parameter / 10); __delay_ms(10); ampm = FALSE; } else { hour_1 = ((parameter - 12) % 10); hour_10 = ((parameter - 12) / 10); __delay_ms(10); ampm = TRUE; } } if (i == 1) { min_1 = (parameter % 10); min_10 = (parameter / 10); __delay_ms(10); //delay from 200 to 10 minimize to prevent blink on when update time } } if(!BUTTON1) // if button B1 is pressed if(debounce()) // call debounce function (make sure if B1 is pressed) { i++; // increment 'i' for the next parameter return parameter; // return parameter value and exit } } } //------------------------------------------------------------------------------------------------------------------------ // BCD>> <<DCIMAL //------------------------------------------------------------------------------------------------------------------------ uint8_t bcd_to_decimal(uint8_t number) { return((number >> 4) * 10 + (number & 0x0F)); } uint8_t decimal_to_bcd(uint8_t number) { return(((number / 10) << 4) + (number % 10)); } //------------------------------------------------------------------------------------------------------------------------ // TIMER0 INITIALIZATION //------------------------------------------------------------------------------------------------------------------------ void Timer0_start() { INTCONbits.T0IE = 1; INTCONbits.T0IF = 0; OPTION_REGbits.T0CS = 0; OPTION_REGbits.PSA = 0; OPTION_REGbits.PS = 2; TMR0 = 2; PEIE=1; GIE=1; } // Write data to DS3231 RTC void Write_Data() { I2C_Start(); I2C_Write(0xD0); I2C_Write(0); I2C_Write(0); I2C_Write(min); I2C_Write(hour); I2C_Write(1); I2C_Write(m_day); I2C_Write(month); I2C_Write(year); I2C_Stop(); } // Read current time and date from the RTC chip void Read_Data() { I2C_Start(); I2C_Write(0xD0); I2C_Write(0); I2C_Repeated_Start(); I2C_Write(0xD1); sec = I2C_Read(1); min = I2C_Read(1); hour = I2C_Read(1); I2C_Read(1); m_day = I2C_Read(1); month = I2C_Read(1); year = I2C_Read(0); I2C_Stop(); } //-------------------------------------------------------------------------------------------------------------------------------------------- // MAIN START HERE //-------------------------------------------------------------------------------------------------------------------------------------------- void main(void) { OSCCON = 0X70; I2C_Init(100000); Timer0_start(); g_current_digit = 0; ANSEL = 0; TRISA = 0x00; TRISC = 0x18; TRISD = 0x00; // Enable RB0 and RB1 internal pull ups nRBPU = 0; //OPTION_REGbits.nRBPU = 0; WPUB = 0x03; while(1) { if(!BUTTON1) // if button B1 is pressed if(debounce()) // call debounce function (make sure if B1 is pressed) { i = 0; hour = edit(hour); min = edit(min); while(debounce()); // call debounce function (wait for button B1 to be released) // convert decimal to BCD min = decimal_to_bcd(min); hour = decimal_to_bcd(hour); // Write data to RTC Write_Data(); } // read current time from the RTC chip Read_Data(); // Start of conversion to DECIMAL sec = bcd_to_decimal(sec); min = bcd_to_decimal(min); hour = bcd_to_decimal(hour); m_day = bcd_to_decimal(m_day); month = bcd_to_decimal(month); year = bcd_to_decimal(year); // WHEN TIME ADJUSTED THROUGH BUTTON, TRYING TO CHECK WHETHER WORKING OR NOT AM/PM. PORTAbits.RA7 = ampm; //CHANGE TO 12HRS FORMAT FROM 24HRS TO DISP IN SEGMENS if (hour <= 12) hour = hour; else hour = (hour - 12); // 2.29AM IS ADJUSTED BY THE BUTTON, WHEN 2.30AM WILL REACH THE DISP IS TO BE OFF AND AT 2.30AM WILL ON THE DISPLAY, and this will continue once in a day at this said time. if ((hour == 2 && min >= 30) && (hour == 2 && min <= 31)) INTCONbits.T0IE = 0; else INTCONbits.T0IE = 1; //Split the into DIGIT to display on 7-SEGMENT sec_1 = (sec%10); sec_10 = (sec/10); min_1 = (min%10); min_10 = (min/10); hour_1 = (hour%10); hour_10 = (hour/10); } }
Abhimanyu Pandit
Permalinkdear saj, i would suggest to add a boolean flag for am and pm and then first check the flag then check the time. This way u can easily do this. Also if you want to take reference then you can also look the code of Automatic Medicine Reminder Using Arduino
- Log in or register to post comments
Joined January 21, 2019 42Monday at 12:12 PM