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 i= deas? 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 =3D 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[] =3D "Startup" print_string(serial_hw_data, starttmrmsg) print_crlf(serial_hw_data) -- time frame is made using timer2 var byte tmrupd var byte tmrcnt =3D 100 -- we need 10 overflows var byte running var byte PRval=3D250 -- 16x250x10x(1/4MHz)=3D100000us=3D10ms ---------------- timeframe T2CON =3D 0 -- to get 10ms T2CON_T2CKPS =3D 2 -- prescaler=3D1:16 T2CON_TOUTPS =3D 9 -- postscaler=3D1:10 -- to get 1ms ;T2CON_T2CKPS =3D 0 -- prescaler=3D1:1 ;T2CON_TOUTPS =3D 15 -- postscaler=3D1:16 T2CON_TMR2ON =3D 0 -- tmr2 off TMR2 =3D 0 -- tmr2, pre, post scalers clear PR2 =3D PRval -- value when tmr has to be reset PIR1_TMR2IF =3D 0 -- int flag clear PIE1_TMR2IE =3D 0 -- int off ---------------- pulse counter var dword cntcnt var byte cntupd T1CON =3D 0 ;T1CON_TMR1CS =3D 1 -- use input from T1CKI T1CON_TMR1CS =3D 0 -- use input from internal clock T1CON_NT1SYNC =3D 1 -- do not synchronize sgnal to clock (inverted l= ogic) T1CON_T1CKPS =3D 0 -- set prscaler (0=3D1:1, 1=3D1:2, 2=3D1:4, 3=3D1= :8) T1CON_TMR1ON =3D 0 -- tmr1 off TMR1 =3D 0 -- clear timer PIR1_TMR1IF =3D 0 -- clear int flag PIE1_TMR1IE =3D 0 -- int off const byte tmrmsg2[] =3D "Finish TMR: " const byte cntmsg2[] =3D "Finish CNT: " INTCON_GIE =3D 0 INTCON_PEIE =3D 0 portA_direction =3D all_output portB_direction =3D all_output portC_direction =3D all_output alias led is pin_C3 pin_C3_direction =3D output pin_C0_direction =3D input pin_C1_direction =3D input ---------------------------------------------------------------------------= --------------------- forever loop tmrcnt=3D100 cntcnt=3D0 T2CON_TMR2ON =3D 0 -- tmr2 off T1CON_TMR1ON =3D 0 -- tmr1 off PR2 =3D PRval PIR1_TMR2IF =3D 0 -- int flag clear PIR1_TMR1IF =3D 0 -- int flag clear TMR1 =3D 0 TMR2 =3D 0 -- start both timers T1CON_TMR1ON =3D 1 -- tmr1 on T2CON_TMR2ON =3D 1 -- tmr2 on led =3D on ; while (tmrcnt !=3D 0) loop -- unnecessary test? forever loop if (PIR1_TMR2IF=3D=3D1) then tmrcnt =3D tmrcnt-1 if (tmrcnt =3D=3D 0) then T1CON_TMR1ON =3D 0 -- stop both timers as fast as possible T2CON_TMR2ON =3D 0 exit loop -- needed only in forever loop end if PIR1_TMR2IF =3D 0 end if -- will skip this if tmrcnt was already 0 -> may cause erro= rs if PIR1_TMR1IF =3D=3D 1 then -- pulse counter overfl= owed cntcnt =3D cntcnt + 1 -- adding 1 should be faster than adding 65536 PIR1_TMR1IF =3D 0 end if end loop led =3D off cntcnt =3D cntcnt * 65536 -- sum full overflows cntcnt =3D cntcnt + TMR1 -- add leftover from the last cycle tmrcnt =3D 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 --=20 KPL --=20 http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .