;******************************************************************
;
ISR movwf W_ISR ; save W-reg |B?
swapf STATUS,W ; doesn't change STATUS bits |B?
movwf S_ISR ; save STATUS reg |B?
clrf STATUS ; force bank 0 |B0
bcf PIR1,TMR2IF ; clear TMR2 interrupt flag |B0
;
; PWM00 1-msec period = 100% duty cycle
; PWM01 1-msec period = variable (000..250 4-usec steps)
; PWM02..PWM19 period = 000% duty cycle
;
ISR_Servo
movlw d'000' ; assume next cycle PWM02-PWM19 |B0
movwf CCPR1L ; set 000% duty cycle |B0
ISR_Counter
incf PWMCTR,f ; inc our 00..19 counter |B0
movf PWMCTR,W ; |B0
xorlw d'20' ; count within 00..19? |B0
bnz ISR_PWM01 ; yes, branch, else |B0
ISR_PWM00
movwf PWMCTR ; reset counter to 00 (PWM00) |B0
movlw d'250' ; get value for 100% duty cycle |B0
movwf CCPR1L ; set 100% duty cycle |B0
ISR_PWM01
movf PWMCTR,W ; |B0
xorlw d'01' ; PWM01 next cycle? |B0
bnz ISR_XIT ; no, branch, else |B0
movf Pulse,W ; get Pulse width variable |B0
movwf CCPR1L ; set variable duty cycle |B0
;
ISR_XIT swapf S_ISR,W ; |B0
movwf STATUS ; restore STATUS |B?
swapf W_ISR,f ; don't screw up STATUS |B?
swapf W_ISR,W ; restore W-reg |B?
retfie ; return from interrupt |B?
;
;******************************************************************
if (PIR1bits.TMR2IF) // if the timer interrupt bit is set...
{
{
LATCbits.LATC0 = 1; // output high voltage to pin
Delay100TCYx( delay ); // wait the desired pulse width
LATCbits.LATC0 = 0; // output 0 voltage to pin
count = 4; // reset the pulse counter
// oscillate between max and min angular displacement of servo
delay += incr;
if (delay > 254)
incr = -incr;
if (delay < 70)
incr = -incr;
PIR1bits.TMR2IF = 0; // reset the interrupt bit
}
TRISCbits.TRISC0 = 0; //output pin c0
// Timer2 prescale = 16
T2CONbits.T2CKPS0 = 0;
T2CONbits.T2CKPS1 = 1;
// Timer2 postscale = 16
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2OUTPS1 = 1;
T2CONbits.T2OUTPS2 = 1;
T2CONbits.T2OUTPS3 = 1;
// Timer period = maximum
PR2 = 0xFF;
// Timer2 is on
T2CONbits.TMR2ON = 1;
// Enable Timer2 interrupt
PIE1bits.TMR2IE = 1;
HakBot said:Mike,
I checked the specs of the pic **broken link removed**
and it says: 48 MHz performance (12 MIPS).
Since I have a 20MHz external clock and a 48MHz internal, how do I set the bits above to do this?
Again, you might want to consider a shorter interrupt and a simple counter mechanism in your interrupt handler code to signal the beginning/end of the 20-msec period. Or, a slower clock?
Mike said:Nigel,
Table 2-3 in the '2550/'4550 Data Sheet clearly shows how to derive an Fosc 48-MHz clock from a different crystal frequency to drive the processor core at an Fcyc of 12-MHz (12-MIPS). Very cool.
If you set it up to generate the pulse every other interrupt then the interrupt period would be 10-msecs, as you said.
Fosc = core oscillator frequency.HakBot said:Mike,
I’m a bit of a noob but what does Fosc stand for? The external crystal?
No, a slower Fosc. With this PIC you can divide the the crystal frequency by 5 to provide the 96-MHz PLL with the required 4-MHz input and then divide the 96-MHz PLL output to some other frequency for the core.Are you saying that the only way I can get the 20ms interrupt is to use a slower crystal?
Tosc (oscillator period) is the riciprical of Fosc (1/8000000)=125-nsecs. Tcyc (instruction cycle period) is Tosc*4=500-nsecs.You say that an 8MHz crystal will produce a 500ns cycle time. How are you calculating this time based on the MHz of the crystal?
Yes, this would provide something close to a 20-msec overall period, provided you're really using a 20-MHz core frequency.Can't I just set the following data to obtain a 10ms period and then set it so it only sends the pulse every other interrupt? (200-nsecs * prescale 16 * postscale 16 * PR2 195) = 9.9ms * 2(every other interrupt) = 20ms
This would allow me to use my existing 20MHz crystal.
Let me check out these references. See you soon.Here is the board I'm using: **broken link removed**
I do not really know what frequency I'm running at. I was hoping you guys could help me determine that. The crystal is running at 20MHz and I was just going along with what Nigel said (200ns cycle time)
Im using the example code found here:
**broken link removed**
Direct link to firmware-> **broken link removed**
The author of this code has the timer set to: (200-nsecs * prescale 16 * postscale 16 * PR2 256) which comes out to 13.1-msecs. The code also only allows the 1-2ms pulse to be sent every 4 interrupts. How is he getting away with sending a pulse every 52.5ms instead of 20ms?
No, a slower Fosc. With this PIC you can divide the the crystal frequency by 5 to provide the 96-MHz PLL with the required 4-MHz input and then divide the 96-MHz PLL output to some other frequency for the core.Are you saying that the only way I can get the 20ms interrupt is to use a slower crystal?
I've been referring to Fosc as the oscillator frequency available to the core.HakBot said:Mike,
I'm gettting confused. Can you clear up a few things for me? First what is the difference between the external crystal and the Fosc? Also, how can I determine what my Fosc is on the pic18f4550? I've searched thru the example code in the links I posted and I dont see any bits set to determine it. Thats why I just assumed it was running at 48MHz. The crystal is 20MHz, this I know for sure.
Normally that's the case. But with the diverse set of oscillator options on the '4550 it seems you can use just about any standard crystal and twiddle options in the oscillator chain to come up with the same frequency (grin) or a different frequency.Isnt the Fosc determined by the speed of the crystal? So wont a slower crystal effect the fosc?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?