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.

stopwatch using PIC?

Status
Not open for further replies.

hemnath

Advanced Member level 3
Joined
Jun 24, 2012
Messages
702
Helped
61
Reputation
120
Reaction score
57
Trophy points
1,308
Location
Chennai
Activity points
6,588
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
 

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

Which PIC are you using? Where is timer0 interrupt code? OK. i got it it is PIC18F2520. can you tell me your clock frequency?
 

Please look at my first post. I am using PIC18F2520
 

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:

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
 

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

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?
 

MPLAB CCS C compiler. It prints the data in temp to the LCD.
 

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
 

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);
 

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
 

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

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
 
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:
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?
 

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.
 

I have tried your code. Its not working. sorry.
 

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

  • pic18timer.rar
    59.7 KB · Views: 57
  • timer sim.rar
    115.2 KB · Views: 47
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top