Andrew Warren [fastfwd at ix.netcom.com] of Fast Forward Engineering San Diego, California says:
Timer-0 has four components: The clock input (either from the TMR0 pin or from the internal instruction clock), the TMR0 prescaler, the TMR0 register, and the TMR0 interrupt flags (GIE, T0IE, and T0IF).CLOCK INPUT:
You'll probably use the internal instruction clock as your TMR0 input; I'll assume that your PIC is running at 4 MHz. Since there's an internal divide-by-4 between the oscillator frequency and the instruction clock, this means that instruction clocks occur at a 1 MHz rate.
PRESCALER:
The TMR0 prescaler is set (via 4 bits in the OPTION register) to divide-by-1, -2, -4, -8, -16, -32, -64, -128, or -256. The TMR0 input clock (1 MHz in your case) is passed to the prescaler, whose divided-down output is then fed to the TMR0 register.
For example, if the TMR0 prescaler is set to divide-by-4 and the PIC is running at 4 MHz, the prescaler will send a 250 KHz clock to the TMR0 register.
TMR0 REGISTER:
The TMR0 register can be preloaded with any 8-bit value that you like.
Each clock pulse from the prescaler increments the contents of the TMR0 register. When the value in the TMR0 register rolls over from 0xFF to 0x00, the T0IF flag is set (the TMR0 register continues to be incremented on every pulse from the prescaler, though).
INTERRUPT FLAGS:
If the GIE and T0IE flags are set when the T0IF flag is set, an interrupt is generated (the GIE bit is automatically cleared (to temporarily prevent further interrupts while your interrupt routine is executing), and the PIC jumps to the "interrupt vector" at location 0x04. Your interrupt-service routine at that location should check the T0IF flag to determine the source of the interrupt, then must clear the T0IF flag to prevent the PIC from immediately jumping back to the interrupt routine when interrupts are re-enabled.
At this point in the interrupt routine, you can re-load the RTCC with any appropriate value.
When you're finished handling the interrupt, your code should execute a RETFIE instruction, which will automatically set the GIE bit to re-enable interrupts and return to your main program.
Luis F says:
If you want the delay in seconds:Delay = (256 - InitTMR0 * prescaler) ----------------------------------------- Frequency / 4Or if you want the value to put in TMR0 to get a determinate DELAY
InitTMR0 = 256 - ( DELAY * Frequency ) / ( 4* Prescaler)
Bob Ammerman or RAM Systems says:
What we really need is a way to ensure that Timer 1 interrupts every 5000 instructions or 1 millisecond.The problem is that there can be jitter on reaching the interrupt handler for the timer. This jitter is caused by 2-cycle instructions, other interrupt handlers, and interrupts being disabled at 'task' level.
We can get around the jitter problem by always adding a constant to the timer, rather than trying to set it directly. What we are doing is effectively advancing time forward the rest of the 65536-5000 instructions to get the timer to interrupt again at the right point.
Here is my suggestion (this code would be in the interrupt handler)
fudge = ...number to account for instructions timer is turned off... magic_value = D'65536'-D'5000'+fudge bcf T1CON,TMR1ON ; turn off timer movlw low(magic_value) addwf TMR1L,F btfsc STATUS,C incf TMR1H,F movlw high(magic_value) addwf TMR1H,F bsf T1CON,TMR1ON ; turn it back on
Dan Michaels of Oricom Technologies says:
With Timer1, try using the "special event trigger" interrupt mode - selected by CCP1CON = xxxx1011. This way you initialize Timer1 once, and the value acts as the interrupt "period".I assume '87x work the same as older '7x chips.
Josef of Snail Instruments [snail at IOL.CZ] says:
Using the compare register is the way to go. Set no prescaler on TMR1, set the CCP module for the special event and load CCPxL & CCPxH register pair with the desired period _MINUS ONE_. Just make sure you substitute CCPxIF for TMR1IF (TMR1IF never gets set, since TMR1 never overflows). Both CCP1 and CCP2 work equally well.
Interested:
Questions:
how to program the timer1 to get 50us interrupt with the PIC16F616?when i set the TMR1L and TMR1H closed to the 0xFFFF, the timer1 interrupt is unstable.How to get a stable 50us interrupt. Thanks.
sir, i just want to know that how to measure the period of incoming pulse,for that i am pasting the code which i have written.List p=18F452;, f =inhx32 #includeREG0 EQU 0x00 REG1 EQU 0x01 REG2 EQU 0x02 REG3 EQU 0x03 ORG 0x00 GOTO MAIN org 0x20 MAIN: BSF TRISC,2 ;Set up CCP1 (RC2) pin as input MOVLW B'10000001' ;Select Timer1 as clock for CCP1-Bits<6-3> 00 MOVWF T3CON,0 ;Timer3 on in 16-bit mode MOVLW B'10000001' ;Enable Timer1 in 16-bit mode, set prescaler =1, MOVWF T1CON,0 ; use instruction cycle clock MOVLW B'00000101' ;Set CCP1 to capture on every rising edge MOVWF CCP1CON,0 BCF PIE1,CCP1IE,0 ;Disable CCP1 capture interrupt as a precaution CALL PULSE MOVFF CCPR1L,REG0 ;Save Timer1 at arrival of first rising edge MOVFF CCPR1H,REG1 CALL PULSE CLRF CCP1CON ;Disable further captures MOVFF CCPR1L,REG2 ;Save Timer1 at arrival of second rising edge MOVFF CCPR1H,REG3 CALL RESULT ;Get period in clock cycles HERE GOTO HERE PULSE: BCF PIR1,CCP1IF,0 ;Clear the CCP1IF flag CHECK BTFSS PIR1,CCP1IF,0 ;Is there a rising edge? GOTO CHECK ;If not, wait in loop RETURN RESULT: MOVF REG0,W,0 ;Get first low reading in W SUBWF REG2,1 ;Subtract W from second low reading - Save in REG2 MOVF REG1,W ;Get first high reading in W SUBWFB REG3,1,0 ;Subtract W from second high reading - Save in REG3 RETURN END
i am constructing a clock using pic 16f84. should i use internal timer ,like TIME0 or can i make a 1sec time delay program? should i use intrrupts for the adjustments?
I have a complex question. How is carried out increment TMR1 at its work from internal source of a clock signal with the switched - off prescaler: I ask a explanation for case if the increment of value TMR1L is doing by command addwf TMR1L, F at the active timer. Will increments "are missed" from Internal clock signal? Shall I lose in a result value which were at first, or is wrote in TMR1? It is supposed, that small enough number (e.g. 5) is in TMR1L before command and also increases small it (e.g. 30).
Encoder miscounts
I hope you will be able to make a suggestion to help solve our current problem. The application concerned is very similar to AN696 'PIC18CXXX/PIC16CXXX DC Servomotor Application'. The problem is a drift in the measured position. As a test case, the motor runs forward about 10 revs, backward about 10 revs and then tries to hold position at zero for 0.6 seconds. There is no load attached to the motor. A line drawn on the output shaft is compared visually to a stationary pointer. These two are lined up before the test is run and the measured position is zeroed.
At first everything seems fine. The output shaft comes back to zero after each excursion. The problem only becomes apparent after leaving the test running for a few hours. The 'zero' position is no longer against the pointer. The amount it has shifted is typically 2 to 4 mm on the periphery of a pulley which is about 40 mm diameter. This is much more than the backlash in the system and also bigger than the normal position error when stationary. The drift seems random. It may be in either direction and it increases and decreases.
Tests have exonerated the command position which reliably returns to zero. The trouble is that the controller thinks it is back at zero. Measured position has 'slipped' or drifted.
The same symptoms have appeared with two different motor types (Pittman and Mitsubishi).
As a test, we went back to the original program from AN696. A couple of small changes were needed to suit our circuit but UpdPos() was unchanged. Clock speed and RS232 baud rate were both as in the Application Note. The test was started with the command L,12,13 which causes the command to execute segment 12, then 13, then 12, then 13, and so on. This is the test which gives the results mentioned above.
If it is any help, I could email you the exact code used.
In trying to search for a cure, the 56pF capacitors in Figure 1 of AN696 were increased in value but the misreading continued.
Do you have any knowledge of this or similar problems ?
Do you have any suggestions of changes which might improve the situation ?
Do you have any idea where we should be looking for the causes ?
Any help you can offer would be gratefully received. This is a serious problem for us.
Dr. George T. Rooney
MicroAxes Ltd.
I have a simple question. How would I configure the TMR0 to run on an external clock (3.72kHz). eventhough the chip will be running at 4MHz? regards shanth
Comments:
Hi, I think your first equation is wrong. Is
Delay = (256 - InitTMR0)* prescaler
-----------------------------------------
Frequency / 4
See you
If you want the delay in seconds: Delay = (256 - InitTMR0) * prescaler ----------------------------------------- Frequency / 4
Archive:
Code: