16F884 Timer0 Counter  [SOLVED]

Find out how to setup your programmer's software and how to solve many common problems.

Moderator: phalanx

16F884 Timer0 Counter

Postby iamgbs » Fri Aug 11, 2017 7:46 pm

Hi all,

Having a problem with doing the following (simple?) stuff:

Using PIC16F884
Want to use Timer0 as a counter, with T0CKI as input to read 0 - 300H pulses/Hz sq wave.
Using MikroE Easypic v7 development board with MikroC Pro compiler.
TMR0 counts as it should, and displays as designed, but actual count value is wrong (eg 100HZ gives count of 80, etc). Using commercial Freq Generator (set at 100Hz Square wave, 5V pktopk), Scope (verifies amplitude and freq) and Frequency Counter (reads 100Hz), so confident readings are correct.
Question is: Can someone help me figure out why this is not counting accurately please? I seem to be stuck in my own roundabout and 6 days at it is disheartening!

My concept:
Setup Timer 0 as Counter
Start Timer
Wait 1 second
Stop and read Timer value

My attempt:

char pulsecnt;

InitTimer0(){
OPTION_REG = 0x28; //Setup Timer0 as T0CKI source (T0CS=1); Low to High transition (T0SE=0); No Prescalar (PSA=1)
INTCON = 0xA0; //Makes no difference if used or not
}

ReadCount(){
InitTimer0();
OPTION_REG = 0x28; //Starts Timer, but can be deleted as it is already in Init
Delay_ms(1000); //Wait 1 second
OPTION_REG = 0x88; //Stops Timer
pulsecnt = TMR0; //Read Timer0 register

return pulsecnt;
}

Thanks, I would really appreciate any help you can give me.
iamgbs
 
Posts: 3
Joined: Fri Aug 11, 2017 7:08 pm

Re: 16F884 Timer0 Counter

Postby phalanx » Sat Aug 12, 2017 10:19 am

There are a few things you should look at.

First is configuring your T0CKI pin as an input. The TRIS registers default to digital input but the ANSEL and ANSELH registers default to analog inputs. You need to clear the appropriate bit for your pin in the ANSEL(H) register to make it a digital input.

Second has to do with starting Timer0. Unlike the other timers, there is no specific "ON" bit for Timer0. It's always incrementing if using the internal clock and will always increment if looking for an edge on T0CKI. For monitoring a slow signal like your 100Hz input, you should configure the OPTION register just like you are doing now followed immediately by an instruction to clear the TMR0 register. Then you can wait however long you need to before working with the TMR0 count.

Third is a continuation of the idea in #2. Since Timer0 is always running, when you are setting OPTION_REG to 0x88, besides changing the pull-up enable bit for some reason, you are setting Timer0 to use Fosc/4 as its clock input before reading the TMR0 register. In that little short period of time inbetween instructions, TMR0 will increment multiple times due to Fosc/4 being significantly faster than your external signal. As soon as you are done with your delay routine, you should immediately read TMR0 before doing anything else. There is also no need to change the clock input for Timer0. You can leave it on your external clock but remember to clear TMR0 before starting a new acquisition period.

Fourth has to do with counter overflows. You are using an 8-bit timer (0-255) over a 1 second period to capture pulses up to 300Hz. Since 300 is greater than 255, the timer can overflow and you will not know whether you measured a slow signal or a very fast one. You need to handle overflow conditions for accurate measurements. You could also use Timer1 instead which has a 16-bit (0-65535) timer register which would allow for measuring higher frequency inputs without overflow processing.

Ultimately, what are you trying to accomplish in your project? There is other hardware in the PIC designed for counting that could potentially serve you better depending on your application.

-Bill
User avatar
phalanx
Non-SFE Guru
 
Posts: 1928
Joined: Sun Nov 30, 2003 8:57 am
Location: Candia, NH

Re: 16F884 Timer0 Counter

Postby iamgbs » Sat Aug 12, 2017 5:55 pm

Thank you for the quick response, Bill.
Yes, ANSEL and ANSELH are correctly setup for digital I/O on that pin.
Changed code as suggested (deleted OPTION_REG to 0x88; read TMR0 right after Init):
char pulsecnt;

InitTimer0(){
OPTION_REG = 0x28; //Setup Timer0 as T0CKI source (T0CS=1); Low to High transition (T0SE=0); No Prescalar (PSA=1)
}

ReadCount(){
InitTimer0();
TMR0=0;
Delay_ms(1000); //Wait 1 second
pulsecnt = TMR0; //Read Timer0 register

return pulsecnt;
}

No overflows, as max I actually need to read is less than 255.
Unfortunately, same result (100Hz reads 80).

Further investigation shows that no matter what the freq, it is always 25% low. So a quick WORKAROUND is to multiply it by 1.25 to get the correct value. The FIX is to find the reason for the error, and that is my objective.
My project is simple (I thought). It is to read a flow meter which pulses at 5Hz/Litre. Easy to calculate the L/min if the count was correct in the first place!

-Geoff
iamgbs
 
Posts: 3
Joined: Fri Aug 11, 2017 7:08 pm

Re: 16F884 Timer0 Counter  [SOLVED]

Postby phalanx » Sat Aug 12, 2017 8:45 pm

The fact that you are 25% low regardless of your input frequency would suggest either your oscillator frequency is off, or your compiler is using an incorrect frequency value when it calculates the delay values inside of the Delay_ms() function. Verify that your oscillator is running at the frequency you expect and make sure you have informed the compiler of your clock or instruction rate which is usually done by a compiler directive.

-Bill
User avatar
phalanx
Non-SFE Guru
 
Posts: 1928
Joined: Sun Nov 30, 2003 8:57 am
Location: Candia, NH

Re: 16F884 Timer0 Counter

Postby iamgbs » Sun Aug 13, 2017 1:41 am

Thank you so much for your reply and patience. You SOLVED the problem!
Yes, Osc freq was off. I failed to recognize that default OSC Freq is 8MHZ. I am running at 10MHz. Hence, reads 80 when should be 100 (Duhhh).
Thanks again Bill. I am sure there is a place for engineers like you in heaven (or wherever). :-)
Regards,
Geoff
iamgbs
 
Posts: 3
Joined: Fri Aug 11, 2017 7:08 pm

Re: 16F884 Timer0 Counter

Postby phalanx » Mon Aug 14, 2017 5:55 am

I'm glad we could square you away!

-Bill
User avatar
phalanx
Non-SFE Guru
 
Posts: 1928
Joined: Sun Nov 30, 2003 8:57 am
Location: Candia, NH


Return to PIC Microcontrollers - Software and Hardware

Who is online

Users browsing this forum: No registered users and 2 guests