# Days settings problem (PIC based LCD clock )

#### BGAmodz

##### Member
Hello everyone .

I have designed an LCD clock based on PIC16F84A , the program works this way :
I have two buttons , when i click the BT2 , i get LDC binking ( 3 fast blinkings) for 3 times each time is a preparation for a specified setting .
Preparation one : minutes .
Two : hours
three : Days
For example in the first blinking i need to keep the BT1 pressed to adjust minutes before the first blinking ends , if i do nothing in that first linking , i get another blinking , but this second one is for hours .and so on for days .

Now the problem is only in the days settings , when i get the third blinking specifically for day adjustment , i can adjust days but i get weard characters in the seconds right digit , its like when that digit reachs 10 it keeps incrementing and does not get back to zero .

I only got that problem when i used the TMR0 interrupt witch i configured using the OPTION_REG register to have an exact 1 SECOND for the clock .

Here's a picture of the glitch accompanied with program text :

Code:
char s1,s2,m1,m2,h1,h2,p,j;
char t;
bit r;
sbit LCD_RS at RB6_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D7 at RB5_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D4 at RB2_bit;

sbit LCD_RS_Direction at TRISB6_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D7_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB2_bit;

void interrupt(){
if(intcon.t0if){
t++;}
if(t==15){
s1++ ;
if(s1==58){s1= 48;}
t=0;
}
intcon.t0if=0;
if(intcon.intf){
r=~r;
}
intcon.intf=0;

}
void DisplayD()
{
if(j==1){Lcd_out(1,11,"MON");}
if(j==2){Lcd_out(1,11,"TUE");}
if(j==3){Lcd_out(1,11,"WED");}
if(j==4){Lcd_out(1,11,"THU");}
if(j==5){Lcd_out(1,11,"FRI");}
if(j==6){Lcd_out(1,11,"SAT");}
if(j==7){Lcd_out(1,11,"SUN");}
if(j=8){j=1;}
}
void Display (){
Lcd_chr(1,8,s1);
Lcd_chr(1,7,s2);
Lcd_chr(1,6,p);
Lcd_chr(1,5,m1);
Lcd_chr(1,4,m2);
Lcd_chr(1,3,p );
Lcd_chr(1,2,h1);
Lcd_chr(1,1,h2);
DisplayD();
}
void main() {
INTCON=0xB0;
OPTION_REG=0x17;
TRISB.b0=1;
PORTB.b0=0;
TRISA.b0=1;
PORTA.b0=0;
r=0;
tmr0=0;
Lcd_Init();
Lcd_cmd(_LCD_CURSOR_OFF);

Display ();
s1=s2=m1=m2=h1=h2=48;
p=58;
j=1;

for(;;){

Display ();

if (s1==58){s1=48;s2++;}
if (s2==54){s1=s2=48;m1++;}
if (m1==58){s1=s2=m1=48;m2++;}
if (m2==54){s1=s2=m1=m2=48;h1++;}
if (h1==58){s1=s2=m1=m2=h1=48;h2++;}
if (h1==52&&h2==50){s1=s2=m1=m2=h1=h2=48;j++;}

while(r==1){

//minutes

Lcd_cmd(_lcd_clear);delay_ms (500);Display (); delay_ms (500);Lcd_cmd(_lcd_clear);delay_ms(500);Display();delay_ms(500);
while(porta.b0==0){
Display();
m1++;
if(m1==58){m1=48;m2++;}
if(m2==54){m1=48;m2=48;}
delay_ms(100);
}
//Hours
Lcd_cmd(_lcd_clear);delay_ms (500);Display (); delay_ms (500);Lcd_cmd(_lcd_clear);delay_ms(500);Display();delay_ms(500);
while(porta.b0==0){
Display();
h1++;
if(h1==58){h1=48;h2++;}
if(h2==50&&h1==52){h1=48;h2=48;}
delay_ms(200);
}
//Days
Lcd_cmd(_lcd_clear);delay_ms (500);Display (); delay_ms (500);Lcd_cmd(_lcd_clear);delay_ms(500);Display();delay_ms(500);
while(porta.b0==0){

Display ();

j++;
delay_ms(1000);
if(j==8){j=1;}

}
r=0;
}
}
}

Last edited:

#### BGAmodz

##### Member
But j is just a variable for counting 7 days , from 0 to 7 , other variables are written in ASCI2 to be recognized in the LCD display .

#### BGAmodz

##### Member
Sorry , the problem i got is when i adjust days , when i do that , the seconds right digit gets incremented without getting back to zero , it continues to display other characters of the ASCI2 .

#### BGAmodz

##### Member
If you have isis , you can make this circuit and see how it acts .

#### Attachments

• 5.2 KB Views: 93

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
OK!! The problem is with the lines
C:
Lcd_cmd(_lcd_clear);delay_ms (500);Display (); delay_ms (500);  Lcd_cmd(_lcd_clear);delay_ms(500);Display();delay_ms(500);
You have 500 * 4 + LCD function delays WITHOUT error checking that 2 seconds that the clock is bieng updated without being processed.... You need to stop the interrupt while the clock is being changed...

#### misterT

##### Well-Known Member
But j is just a variable for counting 7 days , from 0 to 7 , other variables are written in ASCI2 to be recognized in the LCD display .
I didn't read the code, but if you count from 0 to 7 it makes 8 days.

#### misterT

##### Well-Known Member
Hi MrT... the code works fine if he disables the interrupts... J is 1 to 7
When you write code for embedded systems the details are important. If you say 0 to 7 and write 1 to 7 then that is a major problem. There are examples that cost lives. http://en.wikipedia.org/wiki/Therac-25

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Not quite the same.... Radiation therapy vs a clock for homework!!!

There are some applications where you need to start at 1... We traverse duty charts for cranes and they start at 1...

#### misterT

##### Well-Known Member
Not quite the same.... Radiation therapy vs a clock for homework!!!

There are some applications where you need to start at 1... We traverse duty charts for cranes and they start at 1...
Sure.. but, I bet that the documentation does not say 0 when they mean 1 (I hope).

#### BGAmodz

##### Member
Sorry its from 1 to 7 indeed , ian rogers is right if i disable the TMR0 interrupt only the code works fine , but i need to implement the timer to have an exact 1 SEC .

So according to you should i put TMR0= 0; on the adjust section ???

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Its fine... You don't need the timer while you are adjusting the time... The line in question has more than a 2 second delay... so clearing timer 0 won't help... Just disable the interrupts while r is on..

#### BGAmodz

##### Member
I cant clear interrupt while r is on , r is part of the interrupt

#### NorthGuy

##### Well-Known Member
In the interrupt code you simply do "s1++" without checking for overflow. While you do your adjustments, the interrupt may be called several times without the "if (s1==58)" code being called from the main(). This may cause an overflow in s1.

#### BGAmodz

##### Member
Hey thanks northguy , i have edited the timer 0 interrupt , and got rid of that problem but i can't adjust days .

I have edied the code btw.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
I cant clear interrupt while r is on , r is part of the interrupt
No it isn't... Its only used as a "Setting switch" As long as the interrupt catches your input.. You are clearing r at the end of the "setting" while statement...

#### BGAmodz

##### Member
Thanks ian for the comment , i have already got rid of that s1 overflow , but another problem occurs , i can't adjust days after that .
For now i will dig more into my code and see if can find a sollution .

Forum Supporter