Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] digital clock c program hi-tech c compiler.

Status
Not open for further replies.

azarutz

Member level 2
Joined
Mar 4, 2012
Messages
42
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Location
India
Activity points
1,579
hi my digital clock program compiled without error , but didnt get the output .
is anything i leave it?..

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <pic.h>
//#include  <htc.h>
#define RS RB0
#define RW RB1
#define E RB2
void picinit(void);
void lcdinit(void);
void senddata(char);
void command(char);
void delay(int);
void interrupt ISR();
int sec=0,min=0,hr=0,c,d,e,f,g,h,i=0;
void main()
{  
  
     GIE=1;  // Global interrupt enable
     TMR0IE=1;
     TMR0=0x00;
     TMR0IF=0;
    picinit();
    lcdinit();
   OPTION_REG=0b00000111;
   while(1)
   {  
     command(0x80); //star position at 1st row nd 1st column
      c=hr%10;
      hr=hr/10;
      d=hr%10;
      e=min%10;
      min=min/10;
      f=min%10;  
      g=sec%10;
      sec=sec/10;
      h=sec%10;
     senddata(0x30+d);
     senddata(0x30+c);
     senddata(0x3a);
     senddata(0x30+f);
     senddata(0x30+e);
     senddata(0x3a);
     senddata(0x30+h);
     senddata(0x30+g);
     //senddata(0x36);
  }
}
 
void interrupt ISR()
{
  if(TMR0IE==1 && TMR0IF==1)
  {
   TMR0IF=0;
   i++;
   //display();
   if(i==72)
    {
    sec++;
    if(sec==60)
    {
     min++;
     sec=0;
     if(min==60)
      {
        hr++;
        min=0;
      }
    }
  } 
 
 }
}
void picinit()
{ 
   TRISB=0x00;//B port defined as output
   PORTB=0x00;
   TRISD=0x00;//D port definrd as output
   PORTD=0x00;
}
void lcdinit()
{
    command(0x38);//set function
    command(0x01);//clear display
    command(0x0e);//display on cursor blinking
    //command(0x06);
    
}
void command(char comm)
{
    PORTD=comm;
    RS=0; //register select
    RW=0;//read or write
    E=1; //enable data line
    delay(1000);
    E=0; //disable data line
   delay(1000);
}
void senddata(char data)
{
   PORTD=data;
   RS=1;
   RW=0;
   E=1;
   delay(1000);
   E=0;
   delay(1000);
}
void delay(int d)
{
   int i;
   for(i=0;i<=d;i++);
}

 
Last edited by a moderator:

hi my digital clock program compiled without error , but didnt get the output .
is anything i leave it?..

Give some more details like - whether the LCD lights up or not, If black boxes are appearing or not, or if the display is off.

---------- Post added at 23:28 ---------- Previous post was at 23:27 ----------

Give the circuit diagram - need to know how the LCD is connected
 

Yes, without saying where exactly you are facing problem, it is difficult to find the correct solution... Any way, here are some tips...

From your code, it seems you are using 8bit mode of LCD.
If your problem is LCD,
If it is showing black box, it means it is not initialized properly.. Also the initialization code seems not perfect. You need some delays and need to repeat 0x38 for 3 times (as per the spec)..BUT STILL, IT 'MAY' WORK..
Next thing I noticed is, after making RS = 1 or RS = 0, I think you need a small delay of atleast 50uS .. Also, no delay is needed in between EN=1;EN=0.
(some thing like below)
Code:
void command(char comm)
{
PORTD=comm;
RS=0; 
RW=0;
__delay_us(60);
E=1; 
asm("nop");
E=0; 
__delay_ms(2);
}

Code:
void senddata(char data)
{
PORTD=data;
RS=1; 
RW=0;
__delay_us(60);
E=1; 
asm("nop");
E=0; 
__delay_us(10);
}
Also, you can use the hi tech C inbuild delay ie for eg: __delay_ms(15); __delay_us(20); etc. For that you need to define the cpu clock at the top.. ie eg: #define _XTAL_FREQ 20e6

If you use clear command, you need to give a delay of atleast 2ms before introducing another command or data or always use a delay of about 3ms on the end of commad function...



Now,..
If the problem is not with LCD,
then it will be better to include an LED to toggle on each second increment so that you can confirm your ISR is working properly...

Also, no need to do the display routine in a continuous loop, I think there is a chance for trouble since the LCD is updating very frequently..... Instead update the LCD only when a time increment occur..
 
Last edited:

Give some more details like - whether the LCD lights up or not, If black boxes are appearing or not, or if the display is off.

my lcd initialisation commands are working properly because i tested it without ISR , my display turn on and blinking, problem is sec variable it increaments first time only when program starts after that timer didnt run or it didnt call the ISR . and i attached my circuit diagram .


Untitled.png
 

If the problem is not with LCD,
then it will be better to include an LED to toggle on each second increment so that you can confirm your ISR is working properly...
hi i think problem was in ISR only i connected a led to blink on every second increment it seems in low output state only ..
here is the code ..
Code:
void interrupt ISR()
{
  if(TMR0IE==1 && TMR0IF==1)
  {
   TMR0IF=0;
   i++;
   if(i==72)
    {
    sec++;
    display();
    RB4=1;
    delay(100000000);
    RB4=0;
    if(sec==60)
    {
     min++;
     sec=0;
     if(min==60)
      {
        hr++;
        min=0;
      }
    }
  } 
 
 }
}
 

Comment out the display() line as you'd done previously, as I don't see a display() routine (you probably have on).

One thing you haven't done here, (which might be the problem) is that, you didn't clear "i" once it got to 72. I think, that's your problem. Since you declared it as int, it keeps on counting until it overflows and then comes to 72 and then, you get another second interrupt, which has now become a lot more than one second.

Code:
void interrupt ISR()
{
  if(TMR0IE==1 && TMR0IF==1)
  {
   TMR0IF=0;
   i++;
   if(i==72)
    {
    [B][COLOR="#FF0000"]i=0; //Clear "i", so that it starts counting from 0 again[/COLOR][/B]
    sec++;
    display();
    RB4=1;
    delay(100000000);
    RB4=0;
    if(sec==60)
    {
     min++;
     sec=0;
     if(min==60)
      {
        hr++;
        min=0;
      }
    }
  } 
 
 }
}

Hope this helps.
Tahmid.
 
Comment out the display() line as you'd done previously, as I don't see a display() routine (you probably have on).
One thing you haven't done here, (which might be the problem) is that, you didn't clear "i" once it got to 72. I think, that's your problem. Since you declared it as int, it keeps on counting until it overflows and then comes to 72 and then, you get another second interrupt, which has now become a lot more than one second.
ya my program is here . i cleared i variable but it didnt solve the problem . the display function part are some mathematical to send ascii value to the display

Code:
#include <pic.h>
//#include  <htc.h>
#define RS RB0
#define RW RB1
#define E RB2
void picinit(void);
void lcdinit(void);
void senddata(char);
void command(char);
void delay(int);
void interrupt ISR();
void display(void);
int sec=0,min=0,hr=0,c,d,e,f,g,h,i=0;
void main()
{  
   GIE=1;	 // Global interrupt enable
   TMR0IE=1;
   TMR0=0x00;
   TMR0IF=0;
   picinit();
   lcdinit();
   OPTION_REG=0b00000111;
   while(1);
}

void interrupt ISR()
{
  if(TMR0IE==1 && TMR0IF==1)
  {
   TMR0IF=0;
   i++;
   if(i==72)
    {
    i=0;
    sec++;
    display();
    if(sec==60)
     {
     min++;
     sec=0;
     if(min==60)
      {
        hr++;
        min=0;
      }
     }
    } 
   }
  }
void picinit()
{ 
   TRISB=0x00;//B port defined as output
   PORTB=0x00;
   TRISD=0x00;//D port definrd as output
   PORTD=0x00;
}
void lcdinit()
{
	command(0x38);//set function
	command(0x01);//clear display
	command(0x0e);//display on cursor blinking
    //command(0x06);
	
}
void command(char comm)
{
   PORTD=comm;
   RS=0; //register select
   RW=0;//read or write
   E=1; //enable data line
   delay(1000);
   E=0; //disable data line
   delay(1000);
}
void senddata(char data)
{
   PORTD=data;
   RS=1;
   RW=0;
   E=1;
   delay(1000);
   E=0;
   delay(1000);
}
void display(void)
{ 
    command(0x80); //star position at 1st row nd 1st column
    c=hr%10;
    hr=hr/10;
    d=hr%10;
    e=min%10;
    min=min/10;
    f=min%10;  
    g=sec%10;
    sec=sec/10;
    h=sec%10;
    senddata(0x30+d);
    senddata(0x30+c);
    senddata(0x3a);
    senddata(0x30+f);
    senddata(0x30+e);
    senddata(0x3a);
    senddata(0x30+h);
    senddata(0x30+g);
     //senddata(0x36);
}
void delay(int d)
{
   int i;
   for(i=0;i<=d;i++);
}
 

There is a mistake in your display function...

Check how u implemented the conversion of int to it's corresponding ascii values. Try this modified code. It should work AT LEAST in proteus.
But keep this in mind, even if the simulation is working perfect, it doesn't means it should work in real hardware... If you feel any trouble like LCD black row etc, then just try to improve your LCD code...

Code:
#include <pic.h>
//#include  <htc.h>
#define RS RB0
#define RW RB1
#define E RB2
void picinit(void);
void lcdinit(void);
void senddata(char);
void command(char);
void delay(int);
void interrupt ISR();
void display(void);
int sec=0,min=0,hr=0,c,d,e,f,g,h,i=0;
char display_flag;
void main()
{  
   GIE=1;	 // Global interrupt enable
   TMR0IE=1;
   TMR0=0x00;
   TMR0IF=0;
   picinit();
   lcdinit();
   OPTION_REG=0b00000111;
   while(1) {
	    while(display_flag == 0);
	    display_flag = 0;
	    display();
	}  
}

void interrupt ISR()
{
  if(TMR0IE==1 && TMR0IF==1)
  {
   TMR0IF=0;
   i++;
   if(i==72)
    {
    i=0;
    sec++;
	display_flag = 1;
    //display();
    if(sec==60)
     {
     min++;
     sec=0;
     if(min==60)
      {
        hr++;
        min=0;
      }
     }
    } 
   }
  }
void picinit()
{ 
   TRISB=0x00;//B port defined as output
   PORTB=0x00;
   TRISD=0x00;//D port definrd as output
   PORTD=0x00;
}
void lcdinit()
{
	command(0x38);//set function
	command(0x01);//clear display
	command(0x0e);//display on cursor blinking
    //command(0x06);
	
}
void command(char comm)
{
   PORTD=comm;
   RS=0; //register select
   RW=0;//read or write
   E=1; //enable data line
   delay(1000);
   E=0; //disable data line
   delay(1000);
}
void senddata(char data)
{
   PORTD=data;
   RS=1;
   RW=0;
   E=1;
   delay(1000);
   E=0;
   delay(1000);
}
void display(void)
{ 
    command(0x80); //star position at 1st row nd 1st column

	c=hr/10;
    d=hr%10;
    
    e=min/10;
    f=min%10;

    g=sec/10;
    h=sec%10;

    senddata(0x30+d);
    senddata(0x30+c);
    senddata(0x3a);
    senddata(0x30+f);
    senddata(0x30+e);
    senddata(0x3a);
    senddata(0x30+h);
    senddata(0x30+g);
     //senddata(0x36);
}
void delay(int d)
{
   int j;
   for(j=0;j<=d;j++);
}
 
Last edited:
Code:
   while(1) {
	    while(display_flag == 0);
	    display_flag = 0;
	    display();
	}  
}

ya,thanks i got output but i didnt get that the need of display_flag character varible in while loop.
 

I made it like that just to inform you the ISR code should be as small as possible...May be it will work it your case even if you put the display function inside the ISR. But just think, if your interrupt frequency is high and if you made the display function inside the ISR, then you will miss some interrupts.... So it is a good practice to make the ISR as small as possible ....
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top