Continue to Site

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.

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

Timer 1 Source Code Debugging

Status
Not open for further replies.

noname06

New Member
Hi,

This source code is meant to be a timer. But I do not know why when i start my run the timer it will run until 0.49sec and start all over again from 0sec. It only happens when i start to run my program each time. Can anyone tell me where is the error??

Code:
#define _XTAL_FREQ 20000000
#include <htc.h>
#include <stdio.h>
#include <p18f4550.h>
#include "config.h"
#include "lcd.h"
#include <delays.h>

//global variable
int count=0,millisec=0,sec=0;
char TIMER_sec[20];

void interrupt tm1()
	{
	if(TMR1IE&&TMR1IF)
		{
		count++;
		// if(count==3)
		if(count==6)
			{
			if(millisec<99)
				millisec++;
			else
				{
				millisec=0;
				sec++;
				}
			count=0;
			}
		TMR1IF=0;
		TMR1IE=0;
		}
	}


void init()
	{
	TRISB=0B00000000;
	PORTB=0B00000000;

	TRISD=0B00000000;
	PORTD=0B00000000;	 //LCD

	//interrupts
	RCONbits.IPEN=1; //Enables priority levels on interrupts
	PEIE=1; //Enables all unmasked peripheral interrupts(PEIE)
	GIE=1; //Enables all unmasked interrupts(GIE)
	PIE1bits.TMR1IE=1; //Enables the TMR1 overflow interrupt
	IPR1bits.TMR1IP=1; //TMR1 Overflow Interrupt Priority bit (high priority)
	PIR1bits.TMR1IF=1; //TMR1 register did not overflowed

	//Timer1 Control Register
	T1CONbits.RD16 = 1; // 16-Bit = Read/Write Mode Enable bit
	T1CONbits.T1RUN = 1; // Device clock is derived from another source
	T1CONbits.T1CKPS1 = 1; //1:8 Prescaler value
	T1CONbits.T1CKPS0 = 1;
	T1CONbits.T1OSCEN = 0; //Timer1 oscillator is shut down
	T1CONbits.T1SYNC = 1; //Do not synchronize external clock input
	T1CONbits.TMR1CS = 1; //External clock from RC0/T1OSO/T13CKI pin (on the rising edge)
	T1CONbits.TMR1ON = 1; // starts Timer1
	}

void main ()
	{
	init();
	lcd_init();

	while(1)
		{
		if(T1CONbits.TMR1ON)
			{
			TMR1IE=1; // Enables the TMR1 overflow interrupt
			TMR1IF=1;
			}

		sprintf( TIMER_sec , "%d.%d sec", sec,millisec);
		lcd_goto(1,1);
		lcd_puts(TIMER_sec);
		}
	}
 
Last edited by a moderator:
What is clocking timer 1 I see its setup to be an external clock, and whats the clock freq.
 
I would check that the watch dog timer isn't resetting it. The WDT is in the config bits.

Mike.
 
this is my configuration header file
/*
* File: config.h
* Desc.: Configuration Bits
*/

#ifndef CONFIG_H
#define CONFIG_H

#define PWM1_PIN PORTAbits.RA0 // Pins for PWM channels
#define PWM2_PIN PORTAbits.RA1

#pragma config PLLDIV = 5 // For 20MHzMHz XTAL
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2 // USB clock source comes from the 96 MHz PLL divided by 2
#pragma config FOSC = HS // HS oscillator(HS)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor disabled
#pragma config IESO = OFF // Oscillator Switchover mode disabled
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config VREGEN = OFF // USB voltage regulator enabled
#pragma config WDT = OFF
#pragma config CCP2MX = OFF // CCP2 input/output is multiplexed with RB3
#pragma config PBADEN = OFF // PORTB<4:0> pins are configured as digital I/O on Reset
#pragma config LPT1OSC = OFF // Timer1 configured for higher power operation
#pragma config MCLRE = OFF // RE3 input pin enabled; MCLR pin disabled
#pragma config LVP = OFF

#endif /* CONFIG_H */
 
Where did you get that code?? It is truly horrible.

You are turning your int ON every loop in main, and also setting the int flag which will force an interrupt. Then in every interrupt you are clearing the int flag and turning the interrupts OFF again!

As a general rule you setup the timer, then turn timer int ON before entering main. Then the timer int will occur once, for every time the timer rolls over. And in the timer interrupt you just clear the timer overflow flag (TMR1IF).

Also another problem is your main loop does a sprintf and writes to the LCD for EVERY loop! This will be much slower than anything the timer currently does in your int. Generally in main you would wait for a new second, then when new second is detected you display the LCD then.

You should have a look at other people's clock code, and see how they have used the timer interrupt. :)
 
My main purpose of the timer software is to start the timer when a sensor goes high and to stop the timer when another sensor goes high..so now I am trying to run the timer using interrupt. I roughly get your meaning for the LCD part. but I am still a little bit blur on the interrupt part...
 
What do the sensors connect to? Does this sequence happen once only or does it repeat all the time?

If you say more about what the thing does than people can help much better with the changes to your code or offering you new code.
 
It does not happen everytime. My sensor is connected to my PIC...it is suppose to be a coin detection circuit. when the coin roll down the 1st sensor, the timer from the PIC will start running and when the coin passes the 2nd sensor the timer will stop. My main purpose is to differentiate different denomination of coins according to their time it rolls down the ramp. I do not know why my timer will run until 0.49sec and restart from 0.00sec. I have no idea which part of the code causes the timer to restart after 0.49sec...anyone can help me with the code?? thanks
 
Thank you for providing more info, that helps a lot.

You are measuring a single event, and it is quite slow, and you dont need a lot of accuracy.

Since you are struggling with interrupts and timers, why not try a much simpler solution?

Like this procedure;
1. Wait until sensor 1 detected. (coin inserted)
2. Then loop and make 1mS delays, and count the delays.
3. When sensor 2 detected, stop counting.

You can use the code delay like; Delay_mS(1) in your loop and no interrupts or timers are needed.
 
so i use a counter to calculate how many delays have i use??? but my project will have other things involved later on...i scare that by writing too long code it will affect my speed of the coins..my coins speed need accuracy..is it easier with interrupt or just delays??
 
i've tried to use the delay method but it takes too long due to the LCD inititalization at the start of the program...so i think i will just stick on with the interrupt...how do i program my interrupt correctly??
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top