For 20mS timing, you can do it with a single interrupt with any of the 3 timers on the PIC16F887.
Timer0 - Set prescaler to 1:256
Timer1 - As shown above by Bruce
Timer2 - Set prescaler to 1:16, set postscaler to 1:16
For 20mS timing, you can do it with a single interrupt with any of the 3 timers on the PIC16F887.
Timer0 - Set prescaler to 1:256
Timer1 - As shown above by Bruce
Timer2 - Set prescaler to 1:16, set postscaler to 1:16
It seems to me that the most important feature that must be continuously timed in my RC car in autonomous control is the 50 pulses per second Pulse Width Modulated simulation of the RC Receiver to Electronic Speed Control signal. Doing this job in background with one Interrupt sounds correct.
The oscillator seen by TMR0 with pre-scaler runs at 1000000Hz
The pre-scaler 1:256 cuts that down to 3906.25. ie 4kHz.
A post-scaler of 1:64 cuts this down to 61.035Hz. Close enough is my guess. I don't have a grip on how to code this yet. Do I at least understand the concept?
-----------------------another way---------------
Bruce suggests counting up to 20,000 in bits of 1 microsecond. That should be easy enough with a 16 bit register built from TMR1H and TMR1L.
------------now how do I get only one PWM pulse?----------------
Page 135 of the PBP manual seems to indicate that the command:
PWM Pin,Duty,Cycle
will produce "Cycle" number of pulses. It says, "This PWM cycle is repeated "Cycle" times." It also says that, "If a 4mHz oscillator is used, each "Cycle" is about 5ms long."
This seems to mean that the following command:
PWM 1, 75, 1
would produce one pulse about 1.5msec long. This is the neutral pulse for a ESC.
If this is true then writing a routines to control the drive wheels and the steering servo will not be difficult at all.
What do you think?
Ken
I can count up to 60,000 micro seconds using Bruce's mechanism. This is long enough to make the LED on PORTD.0 blink visibly!
Next step is to add the PWM command and connect the output to my RC car's ESC box.
Thanks again, All
Ken
This is pretty crude, but see if it does what it should when changing to Forward, Back, etc
with your ESC.
Code:DEFINE OSC 4 Match VAR WORD Forward CON 1000 ' ~1mS pulse Neutral CON 1500 ' ~1.5mS pulse Back CON 2000 ' ~2mS pulse Match = 20000 ' 20,000 * 1uS = 20mS until compare match CCPR1H = Match.HighByte' Load compare register high CCPR1L = Match.LowByte ' Load compare register low CCP1CON = %00001011 ' Compare mode, auto reset Timer1 '/ TRIS & Port Setup PORTB.0=1 TRISB = $FE ' PORTB.0 output, rest inputs '/ disable interrupts INTCON.7 = 0 ' Disable global ints INTCON.6 = 0 ' Disable peripheral ints PIE1.0 = 0 ' Disable Timer1 int PIE1.2 = 0 ' Disable CCP1 int T1CON = %00000000 ' Timer1 off, internal clock, 1:1 prescale TMR1H = 0 ' Clear Timer1 high TMR1L = 0 ' Clear Timer1 low T1CON.0 = 1 ' Turn on Timer1 LOOPS: ' NOTE: PIR1.2 is the CCP1IF compare interrupt flag bit. ' this bit is set when Timer1 reaches the value in ' CCPR1L & CCPR1H IF PIR1.2 = 1 THEN ' If CCP1 to TMR1 compare match occured HIGH 0 PAUSEUS Forward ' change this to Neutral, Back, Forward to see effect LOW 0 PIR1.2 = 0 ' Clear compare interrupt flag bit ENDIF GOTO LOOPS END
Not only does your code work (with a couple of adjustments specific to my PICkit 2 setup) but it also makes my car go not-so-fast, faster, and fastest.
It also successfully drives the steering servo left, center and right. This validates the rumors that I was getting from the RC people about the shape and timing of their PWM signals.
GREAT!! Now on to bigger and better stuff like light sensing and proximity sensing. First I need to write some car control routines
FORWARD speed,duration
BACKWARD speed, duration
STEER_RIGHT ?
STEER_LEFT ?
Ken
Am I correct in thinking that PAUSEUS stops the PIC.
To run my car the PIC must control steering and wheel rotating. It also monitors whether channel 3 from the RC receiver is calling for a return to RC control.
Meanwhile the car must be able to sense and react to light, ultra sound proximity, and other timers. It has to find its way to a destination.
The PWM pulses are generated at 50 per second. That is 20ms between clock matching interrupts. The longest PAUSEUS is 1.75ms which is 8.75% of total time. Steering concurrent with wheel rotation could consume 17.5% of compute time.
Is this a problem? I just don't know enough about real time PIC coding to know the answer. What do you all think?
Ken
PAUSE puts the code into a loop for a certain amount of instructions. It does not stop the hardware interrupts.
This is what a PAUSE in ASM looks like. Just a routine to eat some time.
Code:; Delay = 0.1 seconds ; Clock frequency = 4 MHz ; Actual delay = 0.1 seconds = 100000 cycles ; Error = 0 % Delay ;99993 cycles movlw 0x1E movwf d1 movlw 0x4F movwf d2 Delay_0 decfsz d1, f goto $+2 decfsz d2, f goto Delay_0 ;3 cycles goto $+1 nop ;4 cycles (including call) return
Dave
Always wear safety glasses while programming.
Bookmarks