Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic 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.

Register Log in

stopwatch using PIC?

Status
Not open for further replies.

hemnath

Advanced Member level 2
Joined
Jun 24, 2012
Messages
676
Helped
61
Reputation
120
Reaction score
57
Trophy points
1,308
Location
Chennai
Activity points
6,409
I want to design stopwatch which shows milliseconds, seconds, minutes in LCD. I am using CCS C compiler, Microcontroller PIC 18F2520 and Cyrstal 4Mhz. which timer to be used??? please help
 

hemnath

Advanced Member level 2
Joined
Jun 24, 2012
Messages
676
Helped
61
Reputation
120
Reaction score
57
Trophy points
1,308
Location
Chennai
Activity points
6,409
i want the interrupt to occur for every 1ms and increment a count value. for 1ms, i have calculated the value 0xF82F to load in timer0.
this is the code i have used to increment just millisecond in LCD. But its not working.
HTML:
#include "18F2520.h"
#include <f2520_regs.h>
#fuses INTRC_IO
#use delay(clock=4000000)

#define RS PIN_A2 
#define EN PIN_A1 

void T0_init();
void lcd_cmd(unsigned char);
void lcd_data(unsigned char);

unsigned int16 temp;
unsigned int16 count=0;

void main()
{
TRISA = 0x00;
LATA = 0x00;
T0CON = 0x00;   			// 0b00000000   Prescalar 1:2 , 16-bit mode, Internal clock.
while(1)
{
T0_init();
temp++;
lcd_data((temp/1000)+0x30);
lcd_data(((temp/100)%10)+0x30);
lcd_data(((temp/10)%10)+0x30);
lcd_data(((temp/1)%10)+0x30);
}
}

void T0_init()
{
TMR0H = 0xF8; 				
TMR0L = 0x2F;     			
TMR0ON = 1;
while(TMR0IF==0);
TMR0ON = 0;
TMR0IF =0;
}

void lcd_cmd(unsigned char c) 
{
   output_b (c);
   output_low(RS);
   output_high (EN);
   delay_ms (10);
   output_low (EN);
}

void lcd_data(unsigned char z)
{
output_b(z);
output_high(RS);
output_high(EN);
delay_ms(10);
output_low(EN);
}
 

Joined
Jul 25, 2012
Messages
1,192
Helped
170
Reputation
340
Reaction score
161
Trophy points
1,343
Activity points
0
Which PIC are you using? Where is timer0 interrupt code? OK. i got it it is PIC18F2520. can you tell me your clock frequency?
 

hemnath

Advanced Member level 2
Joined
Jun 24, 2012
Messages
676
Helped
61
Reputation
120
Reaction score
57
Trophy points
1,308
Location
Chennai
Activity points
6,409
Please look at my first post. I am using PIC18F2520
 

Joined
Jul 25, 2012
Messages
1,192
Helped
170
Reputation
340
Reaction score
161
Trophy points
1,343
Activity points
0
OK I got it it is 4 MHz

use this code for timer

Code:
//Timer0
//Prescaler 1:1; TMR0 Preload = 64537; Actual Interrupt Time : 1 ms
 
//Place/Copy this part in declaration section
void InitTimer0(){
  T0CON	 = 0x88;
  TMR0H	 = 0xFC;
  TMR0L	 = 0x19;
  GIE_bit	 = 1;
  TMR0IE_bit	 = 1;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit = 0;
    TMR0H	 = 0xFC;
    TMR0L	 = 0x19;
    //Enter your code here
  }
}
Code:
//Timer0

//Prescaler 1:1; TMR0 Preload = 64537; Actual Interrupt Time : 1 ms
 

//Place/Copy this part in declaration section


unsigned long int time = 0;
sbit interrupt_flag = 0;


// time gives no of milli sec

void InitTimer0()
{
  

T0CON	 = 0x88;
  
TMR0H	 = 0xFC;
  
TMR0L	 = 0x19;
  
GIE_bit	 = 1;
  
TMR0IE_bit	 = 1;

}
 


void Interrupt()
{
  

	if (TMR0IF_bit)
	{ 
  
  		time++;
		interrupt_flag = 1;		

		TMR0IF_bit = 0;
    
		TMR0H	 = 0xFC;
    
		TMR0L	 = 0x19;
    
	}

}

void main() {

	while(1) {

		if(interrupt_flag == 1) {
			
			//then do something
			interrupt_flag = 0;

		}


	}


}
 
Last edited:

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,274
Trophy points
1,413
Location
Southwest, USA
Activity points
62,505
i want the interrupt to occur for every 1ms and increment a count value. for 1ms, i have calculated the value 0xF82F to load in timer0.
this is the code i have used to increment just millisecond in LCD. But its not working.
Where is the interrupt routine?

Also, the Timer0 initialization routine should typically only be executed once and therefore should be located outside of the while(1) loop.

The interrupt routine should handle the clearing the interrupt flag and resetting the timer.


BigDog
 

hemnath

Advanced Member level 2
Joined
Jun 24, 2012
Messages
676
Helped
61
Reputation
120
Reaction score
57
Trophy points
1,308
Location
Chennai
Activity points
6,409
I dont get anything on the LCD...
Is this correct??
HTML:
#include "18F2520.h"
#include <f2520_regs.h>
#fuses INTRC_IO
#use delay(clock=4000000)

#define RS PIN_A2 
#define EN PIN_A1 

void T0_init();
void lcd_cmd(unsigned char);
void lcd_data(unsigned char);

unsigned int16 temp;

void InitTimer0()
{
  T0CON	 = 0x88;
  TMR0H	 = 0xFC;
  TMR0L	 = 0x19;
  GIE	 = 1;
  TMR0IE = 1;
}
 
void Interrupt()
{
  if (TMR0IF)
	{ 
    TMR0IF = 0;
    TMR0H  = 0xFC;
    TMR0L  = 0x19;
    temp++;
	printf(lcd_data,"%5LU",temp);
  }
}

void main()
{
TRISB = 0x00;
LATB  = 0x00;
T0CON = 0x00;   			// 0b00000000   Prescalar 1:2 , 16-bit mode, Internal clock.
while(1)
{
InitTimer0();
}
}

void lcd_cmd(unsigned char c) 
{
   output_b (c);
   output_low(RS);
   output_high (EN);
   delay_ms (10);
   output_low (EN);
}

void lcd_data(unsigned char z)
{
output_b(z);
output_high(RS);
output_high(EN);
delay_ms(10);
output_low(EN);
}
 

Joined
Jul 25, 2012
Messages
1,192
Helped
170
Reputation
340
Reaction score
161
Trophy points
1,343
Activity points
0
Put InitTimer() outside the while loop. That is in the main loop but before while loop.

what does this function do
Code:
 printf(lcd_data,"%5LU",temp);
explain. are you using MPLAB C18?
 

hemnath

Advanced Member level 2
Joined
Jun 24, 2012
Messages
676
Helped
61
Reputation
120
Reaction score
57
Trophy points
1,308
Location
Chennai
Activity points
6,409
MPLAB CCS C compiler. It prints the data in temp to the LCD.
 

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,274
Trophy points
1,413
Location
Southwest, USA
Activity points
62,505
You should avoid putting routines like printf() within an interrupt routine.

The printf() routine should be within the superloop, while(1) loop.

The printf() routine will be continually executed, when the interrupt occurs the interrupt routine is called, the variable temp will be incremented and return execution back to the superloop which will update the LCD with the latest value of the variable temp.


BigDog
 

Joined
Jul 25, 2012
Messages
1,192
Helped
170
Reputation
340
Reaction score
161
Trophy points
1,343
Activity points
0
bigdogguru is right. In my code I have used interrupt_flag. try using that and in the while (1) loop, when interrupt-flag == 1 then do your printing and then set interrupt_flag to 0.

explain this. what is lcddata in printf(lcd_data,"%5LU",temp);
 

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,274
Trophy points
1,413
Location
Southwest, USA
Activity points
62,505
I believe lcd_data is a data stream/handle previously defined in CCS.

Output from the printf() routine is routed to first parameter, in this case the lcd_data stream/handle which represents the attached LCD display.


BigDog
 

hemnath

Advanced Member level 2
Joined
Jun 24, 2012
Messages
676
Helped
61
Reputation
120
Reaction score
57
Trophy points
1,308
Location
Chennai
Activity points
6,409
I'm extremely sorry with this. I have forgot to initialize the LCD. i have tried the code with 1sec interrupt and it perfectly works. for 1msec, I have changed the timer value TMR0H = 0xF8, TMR0L = 0x2F and changed T0CON to 0x00. But its not working .
HTML:
#include "18F2520.h"
#include <f2520_regs.h>
#fuses INTRC_IO
#use delay(clock=4000000)

#define RS PIN_A2 
#define EN PIN_A1 

void lcd_cmd(unsigned char);
void lcd_data(unsigned char);
void T0_init();
void lcd_init();

unsigned int16 temp;

void main()
{
TRISA = 0x00;
LATA  = 0x00;
TRISB = 0x00;
LATB  = 0x00;
T0CON = 0x00;			// Prescaler= 1:2, 16-bit mode, Internal Clock
lcd_init();
while(1)
{
T0_init();
lcd_cmd(0x80);
printf(lcd_data,"%5LU",temp);
}
}

void T0_init()
{
	TMR0H = 0xF8;               // Values calculated for 1 second delay with 4MHz crystal
	TMR0L = 0x2F;
	TMR0ON = 1;                 // Timer0 On
	while(TMR0IF == 0);        	// Wait until TMR0IF gets flagged
	temp++;	
	TMR0ON = 0;                 // Timer0 Off
	TMR0IF = 0;                // Clear Timer0 interrupt flag
}

void lcd_init()
{
   lcd_cmd(0x30);      // Configure the LCD in 8-bit mode, 1 line and 5x7 font
   lcd_cmd(0x0C);      // Display On and Cursor Off
   lcd_cmd(0x01);      // Clear display screen
   lcd_cmd(0x06);      // Increment cursor
   lcd_cmd(0x80);      // Set cursor position to 1st line, 1st column
}

void lcd_cmd(unsigned char c) 
{
   output_b (c);
   output_low(RS);
   output_high (EN);
   delay_ms (10);
   output_low (EN);
}

void lcd_data(unsigned char z)
{
output_b(z);
output_high(RS);
output_high(EN);
delay_ms(10);
output_low(EN);
}
 

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,274
Trophy points
1,413
Location
Southwest, USA
Activity points
62,505
As mentioned before the Timer0 initialization routine, T0_init() should be outside the superloop, while(1).

So where has the interrupt routine disappeared to?

BigDog
 
Joined
Jul 25, 2012
Messages
1,192
Helped
170
Reputation
340
Reaction score
161
Trophy points
1,343
Activity points
0
For 1 ms timer values are
Code:
TMR0H  = 0xFC;
TMR0L  = 0x19;
this code
Code:
 void T0_init()
{
	TMR0H = 0xF8;               // Values calculated for 1 second delay with 4MHz crystal
	TMR0L = 0x2F;
	TMR0ON = 1;                 // Timer0 On
	while(TMR0IF == 0);        	// Wait until TMR0IF gets flagged
	temp++;	
	TMR0ON = 0;                 // Timer0 Off
	TMR0IF = 0;                // Clear Timer0 interrupt flag
}
is wrong. you should check for TMR0IF in interrupt routine and not in timer initialize routine.

try this

Code:
#include "18F2520.h"
#include <f2520_regs.h>
#fuses INTRC_IO
#use delay(clock=4000000)

#define RS PIN_A2 
#define EN PIN_A1 

void lcd_cmd(unsigned char);
void lcd_data(unsigned char);
void T0_init();
void lcd_init();

unsigned int16 temp;
unsigned char intr_flag = 0;

void main()
{
TRISA = 0x00;
LATA  = 0x00;
TRISB = 0x00;
LATB  = 0x00;
T0CON = 0x00;			// Prescaler= 1:2, 16-bit mode, Internal Clock
lcd_init();
T0_init();

while(1)
{

   lcd_cmd(0x80);
   if(intr_flag == 1) {
   	printf(lcd_data,"%5LU",temp);
	intr_flag = 0;

   }
}
}

void T0_init()
{
   T0CON = 0x88;
   TMR0H = 0xFC;
   TMR0L = 0x19;
   GIE	 = 1;
   TMR0IE = 1;               // Clear Timer0 interrupt flag
}

void lcd_init()
{
   lcd_cmd(0x30);      // Configure the LCD in 8-bit mode, 1 line and 5x7 font
   lcd_cmd(0x0C);      // Display On and Cursor Off
   lcd_cmd(0x01);      // Clear display screen
   lcd_cmd(0x06);      // Increment cursor
   lcd_cmd(0x80);      // Set cursor position to 1st line, 1st column
}

void lcd_cmd(unsigned char c) 
{
   output_b (c);
   output_low(RS);
   output_high (EN);
   delay_ms (10);
   output_low (EN);
}

void lcd_data(unsigned char z)
{
   output_b(z);
   output_high(RS);
   output_high(EN);
   delay_ms(10);
   output_low(EN);
}

void Interrupt()
{
  if (TMR0IF)
	{ 
    TMR0IF = 0;
    TMR0H  = 0xFC;
    TMR0L  = 0x19;
    temp++;
    intr_flag = 1;
	
}
}
 
Last edited:

hemnath

Advanced Member level 2
Joined
Jun 24, 2012
Messages
676
Helped
61
Reputation
120
Reaction score
57
Trophy points
1,308
Location
Chennai
Activity points
6,409
I have changed the value to TMR0H = 0xFC; TMR0L = 0x19; It's not working. For 1 sec, it will increment upto 1000 counts on the LCD. Is it right?
 

Joined
Jul 25, 2012
Messages
1,192
Helped
170
Reputation
340
Reaction score
161
Trophy points
1,343
Activity points
0
check the last post. code is given.

what is unsigned int16 temp;

can you use unsigned long int temp = 0;

It should increment upto the max value temp variable can hold.
 

hemnath

Advanced Member level 2
Joined
Jun 24, 2012
Messages
676
Helped
61
Reputation
120
Reaction score
57
Trophy points
1,308
Location
Chennai
Activity points
6,409
I have tried your code. Its not working. sorry.
 

Joined
Jul 25, 2012
Messages
1,192
Helped
170
Reputation
340
Reaction score
161
Trophy points
1,343
Activity points
0
may be the interrupt code
Code:
 void Interrupt()
{
  if (TMR0IF)
	{ 
    TMR0IF = 0;
    TMR0H  = 0xFC;
    TMR0L  = 0x19;
    temp++;
    intr_flag = 1;
	
}
should be written according to your compiler.

can you show how interrupt routine is written according to your compiler
 

Attachments

Last edited:

Status
Not open for further replies.
Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top