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
Joined January 21, 2019 42Monday at 12:12 PM
dear 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