Exact match. Not showing close matches.
PICList
Thread
'[PIC] pulse counter, pulses lost'
2012\02\19@144311
by
KPL
|
Hi,
Since this is more about pic itself than about jal, I wll ask here.
While playing (educating myself) with timers, I tried to build a
frequency counter. The one where time period of counting pulses would
change depending on pulse rate, that is, frequency.
At first I used tmr0 and tmr1, then rebuilt using tmr1 and tmr2, but
still can not get exactly what I was looking for. I have spent many
late evenings trying, probably somebody from a side can spot my error.
Basically, TIMER2 is used to make a time frame when pulses must be
counted, but TIMER1 is the one that counts pulses. Both have
interrupts enabled, and interrupt routine just adds 1 to a variable,
which is then dealt with in main code.
No prescalers or postscalers are used.
In main code, when a time frame counter or a pulse counter exceeds
pre-defined values, both timers are stopped, their values added to
respective variables, and both variables just sent via serial link to
my PC.
The problem is:
When TIMER1 (pulse counter) is fed from internal clock, I get correct values:
Finish TMR: 5000307
Finish CNT: 5000306
20MHz crystal is used, so 5MHz instruction clock, and one tick of a
timer is 0.2us, so this gives frequency : F=(CNT * 5000000) / TMR =
4999999.0 Hz. That error of 1 pulse can be eliminated by changing
timer start/stop order.
These are about the same, which is correct, since both timers advance
at the same speed. That made me think that program works correctly.
The only pulse source with predictable frequency I have, is an quartz
oscillator, marked as 1.8432MHz. Another frequency counter shows it's
frequency as 1843150Hz.
When I change T1CON_TMR1CS to 1, and feed pulses from the oscillator,
I get results like this :
Finish TMR: 5000304
Finish CNT: 1843100
which gives F=1842987.94 Hz - which shows I am missing several hundred
pulses, or my time frame was several hundred pulses too long.
5000000 TMR pulses is one second, so it is more-than-enough time
period to count this frequency.
So, I tried to move all the stuff around, changed start and stop
sequences, checked datasheets, got a bit different results, but did
not get better precision.
Enabling or disabling T1SYNC did not change anything, since the
frequency I'm trying to measure is quite low.
It's not like this circuit is mission-critical or something, I just
want to understand what I'm doing wrong. And I want a good frequency
counter.
Where are my pulses?! :)
How can it be, it's working perfectly with internal clock, but runs
wrong with external one.
Code is in Jal2, with jallibs, and it looks like this:
include 16f886 -- target PICmicro
pragma target clock 20_000_000 -- oscillator frequency
pragma target OSC HS -- HS crystal or resonator
pragma target WDT disabled -- no watchdog
pragma target LVP disabled -- no Low Voltage Programming
pragma target MCLR internal -- reset externally
--
enable_digital_io()
------------------------------------------------------------------------------------------------
include delay
include print
-- UART
const serial_hw_baudrate = 115200
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- print start
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
const byte starttmrmsg[] = "Startup"
print_string(serial_hw_data, starttmrmsg)
print_crlf(serial_hw_data)
-- time frame is made using timer2
var byte tmrupd
var dword tmrcnt
var byte running
const dword tmrmax = 5000000
T2CON = 0
T2CON_T2CKPS = 0 -- prescaler=1:1
T2CON_TOUTPS = 0 -- postscaler=1:1
T2CON_TMR2ON = 0 -- tmr2 off
TMR2 = 0 -- tmr2, pre, post scalers clear
PIR1_TMR2IF = 0 -- int flag clear
PIE1_TMR2IE = 0 -- int off
-- pulse counter is done using timer1
var byte cntupd
var dword cntcnt
const dword cntmax = 5000000
T1CON = 0
T1CON_TMR1CS = 1 -- use input from T1CKI
;T1CON_TMR1CS = 0 -- use input from internal clock
;T1CON_T1GINV = 0 -- gate active=low
T1CON_TMR1GE = 0 -- tmr0 gate not used
;T1CON_T1OSCEN = 0 -- tmr1 osc not used
T1CON_NT1SYNC = 1 -- do not synchronize sgnal to clock (inverted logic)
T1CON_T1CKPS = 0 -- set prscaler (0:1, 1:2, 2:4, 3:8)
T1CON_TMR1ON = 0 -- tmr1 off
TMR1 = 0 -- clear timer
PIR1_TMR1IF = 0 -- clear int flag
PIE1_TMR1IE = 0 -- int off
const byte tmrmsg0[] = "Start TMR: "
const byte tmrmsg1[] = "Update TMR: "
const byte tmrmsg2[] = "Finish TMR: "
const byte cntmsg0[] = "Start CNT: "
const byte cntmsg1[] = "Update CNT: "
const byte cntmsg2[] = "Finish CNT: "
const byte freqmsg0[] = "Freq: "
INTCON_GIE = 1 -- enables all unmasked interrupts
INTCON_PEIE = 1 -- enables all unmasked peripheral interrupts
portA_direction = all_output
portB_direction = all_output
portC_direction = all_output
alias led is pin_C3
pin_C3_direction = output
pin_C0_direction = input
var dword freq
------------------------------------------------------------------------------------------------
forever loop
running = 0
cntcnt=0
cntupd=0
tmrcnt=0
tmrupd=0
;print_string(serial_hw_data, tmrmsg0)
;print_dword_dec(serial_hw_data, tmrcnt)
;print_crlf(serial_hw_data)
;print_string(serial_hw_data, cntmsg0)
;print_dword_dec(serial_hw_data, cntcnt)
;print_crlf(serial_hw_data)
TMR1 = 0
TMR2 = 0
;while (pin_C0) loop end loop
;while (! pin_C0) loop end loop
T1CON_TMR1ON = 1 -- tmr2 on
T2CON_TMR2ON = 1 -- tmr2 on
PIR1_TMR2IF = 0 -- int flag clear
PIE1_TMR2IE = 1 -- int on
PIR1_TMR1IF = 0 -- int flag clear
PIE1_TMR1IE = 1 -- int on
running = 1
led = on
while (running == 1) loop
if (cntupd > 0) then
cntcnt = cntcnt + 65536
cntupd = cntupd - 1
; print_string(serial_hw_data, cntmsg1)
; print_dword_dec(serial_hw_data, cntcnt)
; print_crlf(serial_hw_data)
end if
if (tmrupd > 0) then
tmrcnt = tmrcnt + 256
tmrupd = tmrupd - 1
; print_string(serial_hw_data, tmrmsg1)
; print_dword_dec(serial_hw_data, tmrcnt)
; print_crlf(serial_hw_data)
end if
if (tmrcnt > tmrmax) then
T1CON_TMR1ON = 0 -- tmr1 off
T2CON_TMR2ON = 0 -- tmr2 off
running = 0
elsif (cntcnt > cntmax) then
T1CON_TMR1ON = 0 -- tmr1 off
T2CON_TMR2ON = 0 -- tmr2 off
running = 0
end if
end loop
led = off
cntcnt = cntcnt + TMR1
tmrcnt = tmrcnt + TMR2
print_string(serial_hw_data, tmrmsg2)
print_dword_dec(serial_hw_data, tmrcnt)
print_crlf(serial_hw_data)
print_string(serial_hw_data, cntmsg2)
print_dword_dec(serial_hw_data, cntcnt)
print_crlf(serial_hw_data)
delay_1s(3) -- some delay
print_crlf(serial_hw_data)
end loop
------------------------------------------------------------------------------------------------
procedure ISR() is
; pragma interrupt fast
pragma interrupt
if PIR1_TMR2IF == true then -- timeframe timer overflowed
tmrupd = tmrupd+1
PIR1_TMR2IF = 0
end if
if PIR1_TMR1IF == true then -- pulse counter overflowed
cntupd = cntupd+1
PIR1_TMR1IF = 0
end if
end procedure
-- KP
2012\02\20@123333
by
KPL
|
Oh, well.
I will never ever buy cheap crystals again.
I will never ever buy cheap crystals again.
I will never ever buy cheap crystals again.
I swear.
Seems like my 20MHz crystal was not 20MHz at all. With a different
crystal it counts correctly.
On Sun, Feb 19, 2012 at 21:43, KPL <spam_OUTkpl.listesTakeThisOuT
gmail.com> wrote:
{Quote hidden}> Hi,
>
> Since this is more about pic itself than about jal, I wll ask here.
>
> While playing (educating myself) with timers, I tried to build a
> frequency counter. The one where time period of counting pulses would
> change depending on pulse rate, that is, frequency.
> At first I used tmr0 and tmr1, then rebuilt using tmr1 and tmr2, but
> still can not get exactly what I was looking for. I have spent many
> late evenings trying, probably somebody from a side can spot my error.
>
> Basically, TIMER2 is used to make a time frame when pulses must be
> counted, but TIMER1 is the one that counts pulses. Both have
> interrupts enabled, and interrupt routine just adds 1 to a variable,
> which is then dealt with in main code.
> No prescalers or postscalers are used.
> In main code, when a time frame counter or a pulse counter exceeds
> pre-defined values, both timers are stopped, their values added to
> respective variables, and both variables just sent via serial link to
> my PC.
> The problem is:
> When TIMER1 (pulse counter) is fed from internal clock, I get correct values:
>
> Finish TMR: 5000307
> Finish CNT: 5000306
>
> 20MHz crystal is used, so 5MHz instruction clock, and one tick of a
> timer is 0.2us, so this gives frequency : F=(CNT * 5000000) / TMR =
> 4999999.0 Hz. That error of 1 pulse can be eliminated by changing
> timer start/stop order.
>
> These are about the same, which is correct, since both timers advance
> at the same speed. That made me think that program works correctly.
>
> The only pulse source with predictable frequency I have, is an quartz
> oscillator, marked as 1.8432MHz. Another frequency counter shows it's
> frequency as 1843150Hz.
> When I change T1CON_TMR1CS to 1, and feed pulses from the oscillator,
> I get results like this :
>
> Finish TMR: 5000304
> Finish CNT: 1843100
>
> which gives F=1842987.94 Hz - which shows I am missing several hundred
> pulses, or my time frame was several hundred pulses too long.
> 5000000 TMR pulses is one second, so it is more-than-enough time
> period to count this frequency.
>
> So, I tried to move all the stuff around, changed start and stop
> sequences, checked datasheets, got a bit different results, but did
> not get better precision.
> Enabling or disabling T1SYNC did not change anything, since the
> frequency I'm trying to measure is quite low.
> It's not like this circuit is mission-critical or something, I just
> want to understand what I'm doing wrong. And I want a good frequency
> counter.
> Where are my pulses?! :)
> How can it be, it's working perfectly with internal clock, but runs
> wrong with external one.
> Code is in Jal2, with jallibs, and it looks like this:
>
>
> include 16f886 -- target PICmicro
> pragma target clock 20_000_000 -- oscillator frequency
> pragma target OSC HS -- HS crystal or resonator
> pragma target WDT disabled -- no watchdog
> pragma target LVP disabled -- no Low Voltage Programming
> pragma target MCLR internal -- reset externally
> --
> enable_digital_io()
> ------------------------------------------------------------------------------------------------
>
> include delay
> include print
>
> -- UART
> const serial_hw_baudrate = 115200
> include serial_hardware
> serial_hw_init()
> alias serial_write is serial_hw_write
> alias serial_read is serial_hw_read
> alias serial_data is serial_hw_data
> alias serial_data_available is serial_hw_data_available
>
> -- print start
> print_crlf(serial_hw_data)
> print_crlf(serial_hw_data)
> const byte starttmrmsg[] = "Startup"
> print_string(serial_hw_data, starttmrmsg)
> print_crlf(serial_hw_data)
>
> -- time frame is made using timer2
> var byte tmrupd
> var dword tmrcnt
> var byte running
> const dword tmrmax = 5000000
>
> T2CON = 0
> T2CON_T2CKPS = 0 -- prescaler=1:1
> T2CON_TOUTPS = 0 -- postscaler=1:1
> T2CON_TMR2ON = 0 -- tmr2 off
> TMR2 = 0 -- tmr2, pre, post scalers clear
> PIR1_TMR2IF = 0 -- int flag clear
> PIE1_TMR2IE = 0 -- int off
>
> -- pulse counter is done using timer1
> var byte cntupd
> var dword cntcnt
> const dword cntmax = 5000000
>
> T1CON = 0
> T1CON_TMR1CS = 1 -- use input from T1CKI
> ;T1CON_TMR1CS = 0 -- use input from internal clock
> ;T1CON_T1GINV = 0 -- gate active=low
> T1CON_TMR1GE = 0 -- tmr0 gate not used
> ;T1CON_T1OSCEN = 0 -- tmr1 osc not used
> T1CON_NT1SYNC = 1 -- do not synchronize sgnal to clock (inverted logic)
> T1CON_T1CKPS = 0 -- set prscaler (0:1, 1:2, 2:4, 3:8)
> T1CON_TMR1ON = 0 -- tmr1 off
> TMR1 = 0 -- clear timer
> PIR1_TMR1IF = 0 -- clear int flag
> PIE1_TMR1IE = 0 -- int off
>
> const byte tmrmsg0[] = "Start TMR: "
> const byte tmrmsg1[] = "Update TMR: "
> const byte tmrmsg2[] = "Finish TMR: "
> const byte cntmsg0[] = "Start CNT: "
> const byte cntmsg1[] = "Update CNT: "
> const byte cntmsg2[] = "Finish CNT: "
> const byte freqmsg0[] = "Freq: "
>
> INTCON_GIE = 1 -- enables all unmasked interrupts
> INTCON_PEIE = 1 -- enables all unmasked peripheral interrupts
>
> portA_direction = all_output
> portB_direction = all_output
> portC_direction = all_output
>
> alias led is pin_C3
> pin_C3_direction = output
>
> pin_C0_direction = input
>
> var dword freq
>
> ------------------------------------------------------------------------------------------------
> forever loop
> running = 0
> cntcnt=0
> cntupd=0
> tmrcnt=0
> tmrupd=0
> ;print_string(serial_hw_data, tmrmsg0)
> ;print_dword_dec(serial_hw_data, tmrcnt)
> ;print_crlf(serial_hw_data)
> ;print_string(serial_hw_data, cntmsg0)
> ;print_dword_dec(serial_hw_data, cntcnt)
> ;print_crlf(serial_hw_data)
> TMR1 = 0
> TMR2 = 0
> ;while (pin_C0) loop end loop
> ;while (! pin_C0) loop end loop
> T1CON_TMR1ON = 1 -- tmr2 on
> T2CON_TMR2ON = 1 -- tmr2 on
>
> PIR1_TMR2IF = 0 -- int flag clear
> PIE1_TMR2IE = 1 -- int on
> PIR1_TMR1IF = 0 -- int flag clear
> PIE1_TMR1IE = 1 -- int on
>
> running = 1
>
> led = on
> while (running == 1) loop
> if (cntupd > 0) then
> cntcnt = cntcnt + 65536
> cntupd = cntupd - 1
> ; print_string(serial_hw_data, cntmsg1)
> ; print_dword_dec(serial_hw_data, cntcnt)
> ; print_crlf(serial_hw_data)
> end if
> if (tmrupd > 0) then
> tmrcnt = tmrcnt + 256
> tmrupd = tmrupd - 1
> ; print_string(serial_hw_data, tmrmsg1)
> ; print_dword_dec(serial_hw_data, tmrcnt)
> ; print_crlf(serial_hw_data)
> end if
>
> if (tmrcnt > tmrmax) then
> T1CON_TMR1ON = 0 -- tmr1 off
> T2CON_TMR2ON = 0 -- tmr2 off
> running = 0
> elsif (cntcnt > cntmax) then
> T1CON_TMR1ON = 0 -- tmr1 off
> T2CON_TMR2ON = 0 -- tmr2 off
> running = 0
> end if
> end loop
> led = off
>
> cntcnt = cntcnt + TMR1
> tmrcnt = tmrcnt + TMR2
>
> print_string(serial_hw_data, tmrmsg2)
> print_dword_dec(serial_hw_data, tmrcnt)
> print_crlf(serial_hw_data)
> print_string(serial_hw_data, cntmsg2)
> print_dword_dec(serial_hw_data, cntcnt)
> print_crlf(serial_hw_data)
>
> delay_1s(3) -- some delay
> print_crlf(serial_hw_data)
>
> end loop
>
> ------------------------------------------------------------------------------------------------
>
> procedure ISR() is
> ; pragma interrupt fast
> pragma interrupt
> if PIR1_TMR2IF == true then -- timeframe timer overflowed
> tmrupd = tmrupd+1
> PIR1_TMR2IF = 0
> end if
> if PIR1_TMR1IF == true then -- pulse counter overflowed
> cntupd = cntupd+1
> PIR1_TMR1IF = 0
> end if
> end procedure
>
>
>
>
>
> --
> KPL
--
KPL
2012\02\20@124133
by
John Gardner
Crystals are designed for specific operating modes.
Sure you got that right? Just a thought...
2012\02\20@125948
by
Bob Ammerman
Some years ago I bought some 20MHZ xtals from DigiKey. They came in, I
installed them and all my timing was a bit off. After spending a whole bunch
of time looking at my code and the hardware I finally took a closer look at
the xtals and found they were marked 19.<something>. Apparently DigiKey
mispicked them, and I didn't perform an appropriate incoming inspection.
-- Bob Ammerman
{Original Message removed}
2012\02\20@142507
by
KPL
Who knows. There was no more info.
I think this one came from here:
http://futurlec.com/ICCrystalsMain.shtml
but since I have no proper tools to test them, I can not say all of
them are bad. Probably that's just that one. Unfortunately I had it
solderet in a small plug-in development board, where it is difficult
to replace.
On Mon, Feb 20, 2012 at 19:41, John Gardner <.....goflo3KILLspam
@spam@gmail.com> wrote:
> Crystals are designed for specific operating modes.
> Sure you got that right? Â Just a thought....
>
2012\02\20@154916
by
KPL
|
Now i'm wondering what would be the best way to calculate frequency
itself, without overflowing 4-byte integer, with maximum possible
precision.
CNT=131129
TMR=355708
Freq==5000000*CNT/TMR=1843211.28566127
CNT can be quite large number, so multiplied by 5e6 it can overflow. I
would like to get maximum significant digits, not for precision but
for resolution. Are there any tricks?
I see I can define frequency as a byte*6 variable, for example - but
seems like I am getting weird results. is JALv2 able to deal with such
numbers?
On Mon, Feb 20, 2012 at 21:25, KPL <kpl.listes
KILLspamgmail.com> wrote:
{Quote hidden}> Who knows. There was no more info.
> I think this one came from here:
>
http://futurlec.com/ICCrystalsMain.shtml
> but since I have no proper tools to test them, I can not say all of
> them are bad. Probably that's just that one. Unfortunately I had it
> solderet in a small plug-in development board, where it is difficult
> to replace.
>
>
> On Mon, Feb 20, 2012 at 19:41, John Gardner <
.....goflo3KILLspam
.....gmail.com> wrote:
>> Crystals are designed for specific operating modes.
>> Sure you got that right? Â Just a thought....
>> -
2012\02\20@160352
by
Rob Hamerling
On 02/20/12 09:49 pm, KPL wrote:
> I see I can define frequency as a byte*6 variable, for example - but
> seems like I am getting weird results. is JALv2 able to deal with such
> numbers?
I would think so! In Jallib you can find a sample program (16f688_print.jal) which uses a byte*32 variable.
Regards, Rob.
-- R. Hamerling, Netherlands --- http://www.robh.n
2012\02\20@161209
by
Carl Denk
|
Set up the timer to increment an up counter, when the counter >= a number you select, could increment another counter, cascading until you accumulate the number of timer periods you need, then reset counter() and set flag you have arrived. This sort of thing can be done with down counters also. Sorry my explanation isn't very ellagant, but hope the message gets through. :)
On 2/20/2012 3:49 PM, KPL wrote:
{Quote hidden}> Now i'm wondering what would be the best way to calculate frequency
> itself, without overflowing 4-byte integer, with maximum possible
> precision.
>
> CNT=131129
> TMR=355708
> Freq==5000000*CNT/TMR=1843211.28566127
>
> CNT can be quite large number, so multiplied by 5e6 it can overflow. I
> would like to get maximum significant digits, not for precision but
> for resolution. Are there any tricks?
>
> I see I can define frequency as a byte*6 variable, for example - but
> seems like I am getting weird results. is JALv2 able to deal with such
> numbers?
>
>
> On Mon, Feb 20, 2012 at 21:25, KPL<
EraseMEkpl.listesspam_OUT
TakeThisOuTgmail.com> wrote:
>
>> Who knows. There was no more info.
>> I think this one came from here:
>>
http://futurlec.com/ICCrystalsMain.shtml
>> but since I have no proper tools to test them, I can not say all of
>> them are bad. Probably that's just that one. Unfortunately I had it
>> solderet in a small plug-in development board, where it is difficult
>> to replace.
>>
>>
>> On Mon, Feb 20, 2012 at 19:41, John Gardner<
goflo3
spam_OUTgmail.com> wrote:
>>
>>> Crystals are designed for specific operating modes.
>>> Sure you got that right? Â Just a thought....
>>> --
2012\02\20@170016
by
IVP
> Seems like my 20MHz crystal was not 20MHz at all
I've had one occassion where grounding the crystal case solved a
timing issue, so I routinely do that now. Whether that really was just
a one-off funny crystal, don't kno
2012\02\21@093056
by
Mark Hanchey
On 2/20/2012 12:33 PM, KPL wrote:
> Oh, well.
>
> I will never ever buy cheap crystals again.
> I will never ever buy cheap crystals again.
> I will never ever buy cheap crystals again.
> I swear.
> Seems like my 20MHz crystal was not 20MHz at all. With a different
> crystal it counts correctly.
>
One of the first test I do on every setup is to set the timer to toggle a pin at 500Khz and I measure that with a frequency counter before I start to write code specific to the chip. That lets me know that everything is running correctly clock wise . I have had issues before that were crystal related and pic related where either one was at fault. Especially useful for when using the internal clock of the pic chips that have them . I used to assume that the internal clock is what it says but depending on the application can be a source of problems if you don't check it first.
Mark
2012\02\21@093423
by
Mark Hanchey
On 2/20/2012 5:00 PM, IVP wrote:
>> Seems like my 20MHz crystal was not 20MHz at all
> I've had one occassion where grounding the crystal case solved a
> timing issue, so I routinely do that now. Whether that really was just
> a one-off funny crystal, don't know
I do this too. Often just a tiny bit of flux on the case and the solder easily will stick to it. Also helps to keep the crystal from getting pulled off the board accidentally , I have several broken crystals from that.
Mark
2012\02\21@095015
by
jim
snip... That lets me know that everything is running correctly clock
wise ..snip.
But does it run counterclockwise?
Regards,
Jim
> ---{Original Message removed}
2012\02\21@100440
by
Chris Roper
You are confusing it with the Arduino Jim
On 21 February 2012 16:50, <@spam@jimKILLspam
jpes.com> wrote:
{Quote hidden}>
>
> snip... That lets me know that everything is running correctly clock
> wise ..snip.
> But does it run counterclockwise?
>
>
>
> Regards,
>
> Jim
>
2012\02\24@163015
by
KPL
|
And so, I'm still playing with same stuff.
Results from those previous tests were unstabe, so i decided to try
the "default" way to count a frequency, that is - make a 1 second
delay, and directly count pulses. No big number divisions, almost no
math at all.
But still, I can not get really useful results, since I'm always
geting more pulses counted than there should be.
I tried counting timer overflows using interrupts, then rebuilt the
code to work without them, with about the same results. In this case I
can avoid delays caused by context saving and restoring at interrupts.
I could see place where error of several pulses could be coming from,
but I'm getting thousands of them!
Timing should be almost right, since timer2 overflow bit is checked in
a loop, and just last iteration has several more instructions, where
several additional pulses could get added if fast enough pulses are
coming in.
Timer1 counts pulses, and just full overflows are counted, to save
instructions. When time period is over, those are multiplied by 65536,
and TMR1 value is added.
For testing purposes, I'm feeding counter with pulses from internal
source, so it should count 4000000 pulses in that second. But I'm
getting 4016008.
I see some error could be generated if both timers overflowed at the
same time, but then some pulses would get lost, not added. I see a way
to avoid that, but in this case it should not matter.
I feel much more familiar with timers now, but still do not get this. Any ideas?
include 16f876a -- target PICmicro
pragma target clock 16_000_000 -- oscillator frequency
pragma target OSC HS -- HS crystal or resonator
pragma target WDT disabled -- no watchdog
pragma target LVP disabled -- no Low Voltage Programming
------------------------------------------------------------------------------------------------
enable_digital_io()
include delay
include print
include format
-- UART
const serial_hw_baudrate = 115200 -- set the baudrate
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- print start
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
const byte starttmrmsg[] = "Startup"
print_string(serial_hw_data, starttmrmsg)
print_crlf(serial_hw_data)
-- time frame is made using timer2
var byte tmrupd
var byte tmrcnt = 100 -- we need 10 overflows
var byte running
var byte PRval=250 -- 16x250x10x(1/4MHz)=100000us=10ms
---------------- timeframe
T2CON = 0
-- to get 10ms
T2CON_T2CKPS = 2 -- prescaler=1:16
T2CON_TOUTPS = 9 -- postscaler=1:10
-- to get 1ms
;T2CON_T2CKPS = 0 -- prescaler=1:1
;T2CON_TOUTPS = 15 -- postscaler=1:16
T2CON_TMR2ON = 0 -- tmr2 off
TMR2 = 0 -- tmr2, pre, post scalers clear
PR2 = PRval -- value when tmr has to be reset
PIR1_TMR2IF = 0 -- int flag clear
PIE1_TMR2IE = 0 -- int off
---------------- pulse counter
var dword cntcnt
var byte cntupd
T1CON = 0
;T1CON_TMR1CS = 1 -- use input from T1CKI
T1CON_TMR1CS = 0 -- use input from internal clock
T1CON_NT1SYNC = 1 -- do not synchronize sgnal to clock (inverted logic)
T1CON_T1CKPS = 0 -- set prscaler (0=1:1, 1=1:2, 2=1:4, 3=1:8)
T1CON_TMR1ON = 0 -- tmr1 off
TMR1 = 0 -- clear timer
PIR1_TMR1IF = 0 -- clear int flag
PIE1_TMR1IE = 0 -- int off
const byte tmrmsg2[] = "Finish TMR: "
const byte cntmsg2[] = "Finish CNT: "
INTCON_GIE = 0
INTCON_PEIE = 0
portA_direction = all_output
portB_direction = all_output
portC_direction = all_output
alias led is pin_C3
pin_C3_direction = output
pin_C0_direction = input
pin_C1_direction = input
------------------------------------------------------------------------------------------------
forever loop
tmrcnt=100
cntcnt=0
T2CON_TMR2ON = 0 -- tmr2 off
T1CON_TMR1ON = 0 -- tmr1 off
PR2 = PRval
PIR1_TMR2IF = 0 -- int flag clear
PIR1_TMR1IF = 0 -- int flag clear
TMR1 = 0
TMR2 = 0
-- start both timers
T1CON_TMR1ON = 1 -- tmr1 on
T2CON_TMR2ON = 1 -- tmr2 on
led = on
; while (tmrcnt != 0) loop -- unnecessary test?
forever loop
if (PIR1_TMR2IF==1) then
tmrcnt = tmrcnt-1
if (tmrcnt == 0) then
T1CON_TMR1ON = 0 -- stop both
timers as fast as possible
T2CON_TMR2ON = 0
exit loop --
needed only in forever loop
end if
PIR1_TMR2IF = 0
end if
-- will skip this if tmrcnt was already 0 -> may cause errors
if PIR1_TMR1IF == 1 then -- pulse counter overflowed
cntcnt = cntcnt + 1 -- adding 1
should be faster than adding 65536
PIR1_TMR1IF = 0
end if
end loop
led = off
cntcnt = cntcnt * 65536 -- sum full overflows
cntcnt = cntcnt + TMR1 -- add leftover from the last cycle
tmrcnt = TMR2
print_string(serial_hw_data, tmrmsg2)
print_dword_dec(serial_hw_data, tmrcnt)
print_crlf(serial_hw_data)
print_string(serial_hw_data, cntmsg2)
print_dword_dec(serial_hw_data, cntcnt)
print_crlf(serial_hw_data)
delay_1s(3) -- some delay
print_crlf(serial_hw_data)
end loop
-- KP
More... (looser matching)
- Last day of these posts
- In 2012
, 2013 only
- Today
- New search...