• 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.

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 :

DxbEwRB.jpg



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++;}



  //CLOCK ADJUST
 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 .
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
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
Most Helpful 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
Most Helpful Member

misterT

Well-Known Member
Most Helpful 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
Most Helpful Member
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..
 

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
Most Helpful Member
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 .
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
I was running it on ISIS and it was working just fine.... I disabled the interrupts and I could alter all three values...

I have converted it to XC8, but still should be the same on your compiler...
 

Latest threads

EE World Online Articles

Loading

 
Top