View previous topic :: View next topic |
Author |
Message |
jpts
Joined: 08 Mar 2017 Posts: 40
|
Timer0 vs Timer1 |
Posted: Tue May 09, 2017 4:59 pm |
|
|
The following program use TIMER0 as external pulse counter. PIC16F648A
Code: | long Int ExtPulse;
Main()
setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1|RTCC_8_bit);
while(TRUE)
{
if (get_timer0() >0)
{
Ext Pulse= get_timer0();
set_timer0(0);
}
while(ExtPulse > 0)
{
output_high(PIN_B3); // pulse ouput
delay_us(300);
output_low(PIN_B3);
delay_us(300);
ExtPulse --;
}
|
Using external read counter, connected on PIN_b3, its count exactly the number of pulses in at PIN_RA4.
The problem is with Timer1. Using same program above, but instead Timer 0, change to Timer 1. Also the pulse In at PIN_RB6 and configuration TIMER 1:
Code: | setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); |
Timer 1 miss pulses . Its count, but compare pulses out, x Pulses in, its miss pulses. Why ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 10, 2017 2:41 am |
|
|
Quote: | Its count, but compare pulses out, x Pulses in, its miss pulses. Why ? |
Give more details on this. If you put in 100 pulses, how many does it miss ?
1. What is the source of the signal ?
2. Describe your input circuit.
3. Give every possible detail about the input signal:
- Is it a rectangular waveform or is it a sine wave, etc. ?
- Is it a continuous signal or occassional pulses ?
- What is the frequency ?
- What is the duration of the positive and negative pulses ?
- What are the low and high voltages of the waveform ?
4. What is the Vdd voltage of the PIC ?
5. What is the oscillator frequency of the PIC ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19592
|
|
Posted: Wed May 10, 2017 4:07 am |
|
|
I'm surprised it is not the other way round.
T0, always runs as a synchronous counter. Won't actually see really short pulses. They have to present for 2 pulses of the master clock, to be counted.
T1. has this as an option. As you have it set, it won't be using this synchronisation, so could count fast edges. To set it to sync like Timer0, the option is:
Code: |
setup_timer_1(T1_EXTERNAL_SYNC|T1_DIV_BY_1);
|
So I'd actually have expected T1 to be counting extra edges, rather than missing them....
Both inputs are Schmitt types, so have the same input thresholds. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9272 Location: Greensville,Ontario
|
|
Posted: Wed May 10, 2017 5:16 am |
|
|
The number of pulses is important as Timer1 is a 16 bit counter and there are 'implications' regarding reading it when rollover occours.
We do need to know the source of the pulses though and how you know Timer 1 misses but Timer0 doesn't.
edit: RB6 is also used for programming the PIC, so is it still in the ICD or programmer while the test is run ?? Also RB7 is kinda tied in as well, might be a potential source of 'problem'....
Jay |
|
|
jpts
Joined: 08 Mar 2017 Posts: 40
|
|
Posted: Wed May 10, 2017 10:35 am |
|
|
Tks all for supporting ...
About this Project, its will be used to count pulses from a flow meter. For testing purpose, I did a pulse simulator using other PIC with a simple program:
Code: |
Main()
Long int pulse_out = 10000;
While (true)
{
While (pulse_out > 0) // 10k pulses will be out and stop! restart to start
{
output_high(PIN_B0);
Delay_us(200);
output_low(PIN_B0);
Delay_us(200);
Pulse_out--;
}
} |
Complementing information.
1) Using Timer0, the pulses out (read by external pulse counter) is exactly 10K
2) Using TIMER1, (same everything) miss about 10 to 13 pulses. So its count ~9990.
3) During T1 test, ICD is disconnected from circuit to make sure no interference.
4) In program, I am monitoring the rollover. In case its happen, a printout will advise like this … #INT_TIMER0 { printf (“interruption occur”)}…but its not happen. For TIMER1 its more difficult to occur once its 16 bits.
In Resume:
PIC SIMULATOR (10k PULSEs ) --> PIC(reading pulses by T0 or T1)-->External Pulse counter |
|
|
jpts
Joined: 08 Mar 2017 Posts: 40
|
|
Posted: Wed May 10, 2017 11:08 am |
|
|
Complementing the information about missing pulses using T1. When a delay is added in program it miss!!!!
Look:
Code: | Main()
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
while(TRUE)
{
delay_ms(10); //Add any delay, miss pulses. without delay count OK.
if (get_timer1() >0)
{
Ext Pulse= get_timer1();
set_timer1(0);
}
while(ExtPulse > 0)
{
output_high(PIN_B3); // pulse ouput
delay_us(300);
output_low(PIN_B3);
delay_us(300);
ExtPulse --;
} |
|
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1358
|
|
Posted: Wed May 10, 2017 12:08 pm |
|
|
Can you please answer some of PCM Programmer's questions about the signal? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19592
|
|
Posted: Wed May 10, 2017 12:59 pm |
|
|
He basically has. 200uSec high 200uSec low, from another PIC at present.
However there are obvious questions such as is the supply common, and how is the signal actually run (the T1 input is on the opposite side of the chip and it would be nice to know the actual signal arriving at the chip had been checked with a scope).
The fact that it actually seem to work if faster, suggests there is a capacitive coupling involved somewhere. A poor ground, or connection. |
|
|
jpts
Joined: 08 Mar 2017 Posts: 40
|
|
Posted: Wed May 10, 2017 1:01 pm |
|
|
Sure..
Signal pulse out:
Square signal. 5volts on 0v off. Pulse width 200us.
A 10k resistor to ground for avoid pin fluctuation.
Regarding, the same circuit works perfect with T0, but not T1. The only changes is set program to T1 and PIC pin.
Regards |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 306
|
|
Posted: Wed May 10, 2017 1:30 pm |
|
|
Every time you clear the timer you potentially also erase a pulse count as well. Don't do this. Clear the timer before you begin and then just read the timer value and compare it with the previous timer value read. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19592
|
|
Posted: Wed May 10, 2017 11:21 pm |
|
|
I still think he has a hardware connection problem.
A signal that counts well at high frequency, but less well at a lower frequency has all the symptoms of something involving capacitive coupling.
So I repeat the question about how the supplies and grounds of the two circuits are connected?. |
|
|
jpts
Joined: 08 Mar 2017 Posts: 40
|
|
Posted: Thu May 11, 2017 5:44 am |
|
|
I dont think its a hardware problem, once same circuit works perfect with T0.
I will take look about suggestion made by gaugeguy... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19592
|
|
Posted: Thu May 11, 2017 7:31 am |
|
|
Problem is that imagine there is a hardware problem and the signal is only _just_ getting to the voltage needed to trip the inputs. It only takes Timer0 to have 0.01v higher sensitivity than Timer1, for it only to show on the latter.
I'd so suspicious of this, because of the data you supply that increasing the frequency makes the problem go away. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 11, 2017 10:08 pm |
|
|
I made it work with a 16F628A (I don't have a 16F648A).
There are two boards, a transmitter and a receiver board.
The transmitter board sends 10K pulses when a button is pushed.
The receiver board takes in the pulses on the T1CKI input pin and counts
them in Timer1. When I press a button on the receiver board, it will
read Timer1 and display it on TeraTerm, which is running on my PC.
Test procedure:
1. Press reset on the transmitter board.
2. Press reset on the receiver board.
3. Press button B0 on the receiver board to display Timer1 = 0.
4. Press button B0 on the transmitter board to send the pulses.
5. Wait until LED B2 on the transmitter board goes on, and then off.
6. Press button B0 on the receiver board to display Timer1 on TeraTerm.
It should display 10000.
Here are the results. There are multiple lines because I pressed button
B0 on the receiver board several times.
Quote: | Start
Timer1 = 0
Timer1 = 0
Timer1 = 0
Timer1 = 0
Timer1 = 0
Timer1 = 0
Timer1 = 10000
Timer1 = 10000
Timer1 = 10000
|
To avoid the Timer1 errata, I initialize the signal pin (pulse output)
on the transmitter board to a logic high. Then I take it to a logic low.
This gives Timer1 on the receiver the initial falling edge that it needs.
http://ww1.microchip.com/downloads/en/DeviceDoc/80329B.pdf
Here is the pulse transmitter program. It runs on a PicDem2-Plus board
(older non-Rohs version). It's very similar to his program. It waits for
the button on Pin B0 to be pushed, and then it sends out 10000 pulses.
I'm sending the pulses out on Pin D7. It's unused on that board.
Code: |
#include <18F46K22.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOPBADEN
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
#define BUTTON_PIN PIN_B0 // Has a 4.7K pullup to +5v
#define SIGNAL_PIN PIN_D7
#define LED_PIN PIN_B2
//======================================
void main()
{
int32 pulse_out = 10000;
output_low(SIGNAL_PIN);
output_low(LED_PIN);
delay_ms(500);
while(input(BUTTON_PIN)); // Wait here until button is pressed
delay_ms(500);
output_high(LED_PIN); // Show that pulses are being transmitted
while(pulse_out > 0) // Send 10K pulses
{
output_high(SIGNAL_PIN);
delay_us(200);
output_low(SIGNAL_PIN);
delay_us(200);
pulse_out--;
}
output_low(LED_PIN); // Show that pulse transmission is done
while(TRUE);
}
|
Here is the receiver program. The 16F628A is on a 2nd PicDem2-Plus
board. A jumper wire on Pin D7 of the transmitter board connects
to Pin B6 on the receiver board. Pin B6 is the T1CKI input for the PIC.
There is also a ground wire jumpered between the two boards.
Also, there is a jumper from pin B2 to pin C6 on the receiver board to
connect the UART Tx pin so it will go to the MAX232A and out to the PC.
Also, I have the jumper on pin B6 disconnected when I program the
board with the Pickit 3. That's because pin B6 is the PGC pin for the
programmer, as well as the T1CKI pin. After programming, I re-connect
the jumper.
Code: | #include <16F628A.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, NOLVP
#use delay(clock=4M)
#use rs232 (baud=9600, UART1, ERRORS)
#define BUTTON_PIN PIN_B0
//==========================
void main()
{
printf("Start\n\r");
setup_timer_1(T1_EXTERNAL_SYNC | T1_DIV_BY_1);
set_timer1(0);
while(TRUE)
{
if(!input(BUTTON_PIN)) // If button is pressed
{
delay_ms(10); // Debounce delay
printf("Timer1 = %lu \n\r", get_timer1());
while(!input(BUTTON_PIN)); // Wait for button to be released
delay_ms(10); // Debounce delay
}
}
} |
Both boards run at +5v. The compiler is vs. 5.071. |
|
|
drh
Joined: 12 Jul 2004 Posts: 193 Location: Hemet, California USA
|
|
Posted: Fri May 12, 2017 7:57 am |
|
|
PCM Programmer should be getting paid for his help on this forum. _________________ David |
|
|
|