![]() | ![]() | ![]() |
| | #16 |
|
Very nice Mike (Pommie). Again, excellent comments for newcomer and veteran alike. The 18F1320 Data Sheet seems to indicate that the CCP/ECCP module "special event trigger" mode automatically starts an ADC acquisition and conversion by setting the ADCON0bits.GO bit for you if the ADC module is turned on. Does that mean you could eliminate setting the ADCON0bits.GO bit? Would that require moving the ADC conversion into the ISR (to avoid timing problems)? Would there be any advantage doing it that way (in the ISR)? Code: void ccp1_isr()
{ if(ServoPin = !ServoPin) // if toggled ServoPin = 1
CCPR1 = ServoPos; // setup "on" time match value
else // else
CCPR1 = 20000 - ServoPos // setup "off" time match value
while(ADCON0bits.GO); // wait for ADC conversion
ServoPot=ADRES+1000; // <-- new variable
PIR1bits.CCP1IF=0; // clear CCP1 interrupt flag bit
}
Last edited by Mike, K8LH; 10th February 2008 at 11:36 PM. | |
| |
| | #17 |
|
I hadn't realised that the ADC would automatically be triggered. On the 16 series this only happens on CCP2 (when 2 CCP modules are available) and I had assumed it would be the same for the 18 series. I just commented out the setting of the Go bit and it still works. The "special event trigger" does start the conversion. Mike. | |
| |
| | #18 |
|
The 18 series also supports an automatic acquisition delay. Such nice PICs.
| |
| |
| | #19 |
|
I know, I set it to 16 Tad. Mike. | |
| |
| | #20 | |
| Quote:
Here's an asm port of Pommie's first posted program: Code: list p=18F1320 include <p18F1320.inc> CONFIG OSC=INTIO2,WDT=OFF,MCLRE=ON,LVP=OFF cblock 0x00 ServoPosH,ServoPosL,src1,src2,dst1,dst2 endc org 0x0000 init movlw 0x70 movwf OSCCON ;Osc=8MHz movlw b'00000101' ;A2D on and select AN1 movwf ADCON0 movlw b'01111101' ;A1 = analog movwf ADCON1 movlw b'10110101' ;Right justify - Fosc/16 movwf ADCON2 bcf TRISB,3 ;make servo pin output bcf LATB,3 ;Servo output off movlw b'00001011' ;Special event trigger movwf CCP1CON movlw b'10010001' ;Timer 1 on with Pre=2 movwf T1CON movlw 0x05 ;set servo to mid position movwf ServoPosH movwf CCPR1H ;and set CCP initial value movlw 0xdc movwf ServoPosL movwf CCPR1L main btfss PIR1,CCP1IF ;wait for CCP interrupt bit goto main bcf LATB,3 ;end pulse movlw 0x4e ;Off time = 20ms - Servo Time movwf src1 movlw 0x20 movwf src2 movff ServoPosH,dst1 movff ServoPosL,dst2 call sub16 movff dst1,CCPR1H movff dst2,CCPR1L bcf PIR1,CCP1IF ;clear int flag bsf ADCON0,GO ;start conversion conv btfsc ADCON0,DONE ;Wait for it to complete goto conv movff ADRESH,src1 ;Pos will be 1ms to 2.023ms movff ADRESL,src2 movlw 0x03 movwf dst1 movlw 0xe8 movwf dst2 call add16 movff dst1,ServoPosH movff dst2,ServoPosL wait btfss PIR1,CCP1IF ;wait for int flag goto wait bsf LATB,3 ;start pulse movff ServoPosH,CCPR1H ;Servo time in uS movff ServoPosL,CCPR1L bcf PIR1,CCP1IF ;clear int flag goto main sub16 movf src2,W subwf dst2,F movf src1,W btfss STATUS,C incf src1,W subwf dst1,F return add16 movf src2,W addwf dst2,F movf src1,W btfsc STATUS,C incf src1,W addwf dst1,F return end
__________________ ========================= Futz's Microcontrollers & Robotics ========================= Last edited by futz; 10th February 2008 at 12:57 AM. | ||
| |
| | #21 |
|
Nicely done Futz. Are you going to do the interrupt version as well? One little suggestion to make it more readable. Use word variables with Lo and Hi on the end instead of 1 & 2, use the . with decimal numbers and make use of the low and high directives. Code: ;so this movlw 0x03 movwf dst1 movlw 0xe8 movwf dst2 call add16 ;becomes movlw low(.1000) movwf dstLo movlw high(.1000) movwf dstHi call add16 | |
| |
| | #22 | |||
| Quote:
Quote:
Quote:
If so, I sure didn't mean to. I usually think in hex. ![]() EDIT: Ah, I see what you're talking about. Good stuff. I'll put those suggestions into future programs. Thanks!
__________________ ========================= Futz's Microcontrollers & Robotics ========================= Last edited by futz; 10th February 2008 at 02:14 PM. | ||||
| |
| | #23 | |
| Quote:
Code: list p=18F1320 include <p18F1320.inc> CONFIG OSC=INTIO2,WDT=OFF,MCLRE=ON,LVP=OFF cblock 0x00 Mode,Keys,OldKeys,Edges,ServoPosH,ServoPosL srcH,srcL,dstH,dstL endc org 0x00 goto init org 0x18 isr btfss PORTB,3 ;the ISR goto else1 bcf LATB,3 ;turn off servo output movlw high(.20000) ;Off time = 20ms - Servo Time movwf srcH movlw low(.20000) movwf srcL movff ServoPosH,dstH movff ServoPosL,dstL call sub16 movff dstH,CCPR1H movff dstL,CCPR1L goto isr_done else1 bsf LATB,3 ;turn on servo output movff ServoPosH,CCPR1H ;On time movff ServoPosL,CCPR1L isr_done bcf PIR1,CCP1IF ;clear int flag retfie FAST init movlw 0x70 movwf OSCCON ;Osc=8MHz movlw b'00000101' ;A2D on and select AN1 movwf ADCON0 movlw b'01111101' ;A1 = analog movwf ADCON1 movlw b'10110101' ;Right justify - Fosc/16 movwf ADCON2 bcf TRISB,3 ;make servo pin output bcf LATB,3 ;Servo output off movlw b'00001011' ;Special event trigger movwf CCP1CON movlw b'10010001' ;Timer 1 on with Pre=2 movwf T1CON movlw high(.1500) ;set servo to mid position movwf ServoPosH movwf CCPR1H ;and set CCP initial value movlw low(.1500) movwf ServoPosL movwf CCPR1L bsf PIE1,CCP1IE ;enable CCP1 interrupt bsf INTCON,PEIE ;enable peripheral interrupts bsf INTCON,GIE ;enable global interrupts bcf INTCON2,RBPU ;enable PORTB weak pullups main btfss PORTB,3 ;Wait for start of servo pulse goto main wait2 btfsc PORTB,3 ;wait for end - makes for good debounce goto wait2 movff Keys,OldKeys ;make a copy of keys movf PORTB,W ;get switch state andlw b'00100101' movwf Keys movlw b'00100101' ;make pressed keys = 1 xorwf Keys,F movlw b'00100101' ;all 3 pressed? cpfseq Keys goto not3 clrf Mode ;yes, set to use ADC input not3 movf Keys,W ;keep only keys that have changed xorwf OldKeys,W movwf Edges andwf Keys,W ;keep only new key presses - not key releases movwf Edges tstfsz Mode ;are we using the pot? goto nomode bsf ADCON0,GO ;yes, start conversion waitcv btfsc ADCON0,DONE ;wait for it to complete goto waitcv movff ADRESH,srcH ;Pos will be 1ms to 2.023ms movff ADRESL,srcL movlw high(.1000) movwf dstH movlw low(.1000) movwf dstL call add16 movff dstH,ServoPosH movff dstL,ServoPosL nomode tstfsz Edges ;any key pressed goto mode1 ;go switch to fixed mode goto mode0 mode1 movlw 1 ;switch to fixed mode movwf Mode mode0 movlw 1 subwf Edges,W ;key 1 pressed btfss STATUS,Z goto key2 movlw high(.1000) ;set servo fully left movwf ServoPosH movlw low(.1000) movwf ServoPosL goto again key2 movlw 0x04 ;key 2? subwf Edges,W btfss STATUS,Z goto key3 movlw high(.1500) ;set center movwf ServoPosH movlw low(.1500) movwf ServoPosL goto again key3 movlw 0x20 ;key 3? subwf Edges,W btfss STATUS,Z goto again movlw high(.2000) ;set fully right movwf ServoPosH movlw low(.2000) movwf ServoPosL again goto main sub16 movf srcL,W subwf dstL,F movf srcH,W btfss STATUS,C incf srcH,W subwf dstH,F return add16 movf srcL,W addwf dstL,F movf srcH,W btfsc STATUS,C incf srcH,W addwf dstH,F return end Code: list p=18F1320 include <p18F1320.inc> CONFIG OSC=INTIO2,WDT=OFF,MCLRE=ON,LVP=OFF cblock 0x00 ServoPosH,ServoPosL,srcH,srcL,dstH,dstL endc org 0x0000 init movlw 0x70 movwf OSCCON ;Osc=8MHz movlw b'00000101' ;A2D on and select AN1 movwf ADCON0 movlw b'01111101' ;A1 = analog movwf ADCON1 movlw b'10110101' ;Right justify - Fosc/16 movwf ADCON2 bcf TRISB,3 ;make servo pin output bcf LATB,3 ;Servo output off movlw b'00001011' ;Special event trigger movwf CCP1CON movlw b'10010001' ;Timer 1 on with Pre=2 movwf T1CON movlw high(.1500) ;set servo to mid position movwf ServoPosH movwf CCPR1H ;and set CCP initial value movlw low(.1500) movwf ServoPosL movwf CCPR1L main btfss PIR1,CCP1IF ;wait for CCP interrupt bit goto main bcf LATB,3 ;end pulse movlw high(.20000) ;Off time = 20ms - Servo Time movwf srcH movlw low(.20000) movwf srcL movff ServoPosH,dstH movff ServoPosL,dstL call sub16 movff dstH,CCPR1H movff dstL,CCPR1L bcf PIR1,CCP1IF ;clear int flag bsf ADCON0,GO ;start conversion conv btfsc ADCON0,DONE ;Wait for it to complete goto conv movff ADRESH,srcH ;Pos will be 1ms to 2.023ms movff ADRESL,srcL movlw high(.1000) movwf dstH movlw low(.1000) movwf dstL call add16 movff dstH,ServoPosH movff dstL,ServoPosL wait btfss PIR1,CCP1IF ;wait for int flag goto wait bsf LATB,3 ;start pulse movff ServoPosH,CCPR1H ;Servo time in uS movff ServoPosL,CCPR1L bcf PIR1,CCP1IF ;clear int flag goto main sub16 movf srcL,W subwf dstL,F movf srcH,W btfss STATUS,C incf srcH,W subwf dstH,F return add16 movf srcL,W addwf dstL,F movf srcH,W btfsc STATUS,C incf srcH,W addwf dstH,F return end
__________________ ========================= Futz's Microcontrollers & Robotics ========================= Last edited by futz; 11th February 2008 at 12:19 AM. | ||
| |
| | #24 | |
| Quote:
| ||
| |
| | #25 | |
| Quote:
![]() I have another wish also. Center position with middle button, small steps left/right with button 1 & 3. Could be used to test the resolution of the servos. I'll have a go at it later. I don't expect you to write the code for me, but if you find it interresting, please do. I program pics partly for learning, partly for practical use. Like most, I guess. | ||
| |
| | #26 |
|
The really nice thing about having a Junebug is that you can flip a couple of switches and instantly try a bit of code. It's really easy to do. If you want to have a go yourself then stop reading now. To do what you ask simply needs this change, Code: if(Edges==0b00000001 //Key 1 pressed
&&ServoPos>1000) //and servo not fully left
ServoPos-=100; //move servo a bit left
if(Edges==0b00000100) //key 2?
ServoPos=1500; //set center
if(Edges==0b00100000 //Key 3 pressed
&&ServoPos<2000) //and servo not fully right
ServoPos+=100; //move a bit right
Edit, you probably want to experiment with the endstop values (1000 and 2000) as I believe most servos go beyond the 1-2mS range. Just tried my Futaba S3003 and the endstops seem to be 600 and 2400. That code is a little confusing, the lines are actaully, Code: if(Edges==0b00000001 && ServoPos>600)
{
ServoPos-=100;
}
Mike. Last edited by Pommie; 13th February 2008 at 10:44 AM. | |
| |
| | #27 |
|
Wow, Mike made a day... Many posts in this thread in less time.. Regards, Simran..
__________________ Simran.. 8051 Specialist.. | |
| |
| | #28 |
|
I just googled for "junebug c18 servo example" and it took me to a forum I frequent anyway, how convienient is that? Thanks for the code Pommie. I'll be making use of this when i get home. I've got a question already, where did you find out all the system variables your setting and what they do? such as "ADCON0bits.GO" I'm just starting on C18, and with 18F chips. I'm going to look through some of the microchip PDFs and see if I can find it. Last edited by Triode; 15th June 2009 at 02:41 PM. | |
| |
| | #29 | |
| Quote:
Mike. | ||
| |
| | #30 |
|
Thanks, I see a lot of the variables you used, but with "bits" at the end, what does that do?
| |
| |
|
| Tags |
| c18, code, junebug, servo |
| Thread Tools | |
| Display Modes | |
| |
Similar | ||||
| Title | Starter | Forum | Replies | Latest |
| MP Lab Program Help | bamafan54 | Micro Controllers | 5 | 7th January 2009 03:16 PM |
| servo motor program code | basf_12 | Electronic Projects Design/Ideas/Reviews | 8 | 31st October 2006 03:57 AM |
| Tough assembly program for the PIC16F84 | asmpic | Micro Controllers | 34 | 3rd December 2004 07:50 PM |
| how to understand this code!!! | indie | Electronic Projects Design/Ideas/Reviews | 3 | 11th September 2004 08:39 PM |
| An error in pic16f84a, why? | Zener_Diode | Micro Controllers | 6 | 11th April 2004 03:55 AM |