Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 9th February 2008, 05:12 PM   #16
Default

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.
Mike, K8LH is offline  
Old 9th February 2008, 05:33 PM   #17
Default

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.
Pommie is online now  
Old 9th February 2008, 06:35 PM   #18
Default

The 18 series also supports an automatic acquisition delay. Such nice PICs.
__________________
Bill
Smart Kits build Smart People

http://www.blueroomelectronics.com/
blueroomelectronics is offline  
Old 9th February 2008, 06:51 PM   #19
Default

I know, I set it to 16 Tad.

Mike.
Pommie is online now  
Old 10th February 2008, 12:34 AM   #20
Default

Quote:
Is there really that few people experimenting with the Junebug that nobody found this post interesting?
Work has been hectic lately and I haven't had much time to play. Saw the post, but couldn't do anything with it till today.

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.
futz is offline  
Old 10th February 2008, 07:29 AM   #21
Default

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
Mike.
Pommie is online now  
Old 10th February 2008, 07:43 AM   #22
Default

Quote:
Originally Posted by Pommie
Nicely done Futz. Are you going to do the interrupt version as well?
The port is done, but the buttons aren't working yet. I have to go through it (maybe tomorrow) and see what I did wrong. Most likely I got one of the bit tests backward and it's branching the wrong way. The potentiometer/servo part works fine though.

Quote:
One little suggestion to make it more readable. Use word variables with Lo and Hi on the end instead of 1 & 2,
Those 1 & 2 things came from Chuck McMannis, the guy I stole those 16-bit add/subtract code snips from. I didn't change a thing. I prefer to use H and L suffixes. I'll change that in the second port.

Quote:
use the . with decimal numbers and make use of the low and high directives.
Mike.
I used a decimal number? 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.
futz is offline  
Old 10th February 2008, 11:10 PM   #23
Default

Quote:
Originally Posted by Pommie
Are you going to do the interrupt version as well?
Finally found the problem. Here's the asm port of Pommie's second program:
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
and here's the first one again, modified with the suggestions from a few posts ago:
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.
futz is offline  
Old 13th February 2008, 09:42 AM   #24
Default

Quote:
Originally Posted by blueroomelectronics
Watch out with powering the Servo with your USB port.
Found out the hard way... No damage though. I'm using a separate 5 V powersupply for the servo now.
Odin is offline  
Old 13th February 2008, 09:55 AM   #25
Default

Quote:
Originally Posted by Pommie
Here is a version that will go fully left if button 1 pressed, center if button 2 pressed and fully right if button 3 pressed. If you press all 3 buttons together it will take up the position defined by the pot.
Tested, and it works! Thanks a lot for the code examples. I know 16F-series fairly well, but I'm new to 18Fs. Need some time to learn. I'm to lazy to connect other pic's, now that I have the 18F1320 on the Junebug
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.
Odin is offline  
Old 13th February 2008, 10:23 AM   #26
Default

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
If the steps are too bit change the 100 value.

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;
    }
I just split them so it looked tidy.

Mike.

Last edited by Pommie; 13th February 2008 at 10:44 AM.
Pommie is online now  
Old 13th February 2008, 11:18 AM   #27
Smile Mike made a day...

Wow,

Mike made a day...

Many posts in this thread in less time..

Regards,

Simran..
__________________
Simran..
8051 Specialist..
simrantogether is offline  
Old 15th June 2009, 02:32 PM   #28
Default

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.
Triode is offline  
Old 15th June 2009, 03:32 PM   #29
Default

Quote:
Originally Posted by Triode View Post
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.
They're all listing in the data sheet. Here's the 18F1320 data sheet. If you mean the actual names, they pretty much follow the data sheet but if your unsure they're in the 18F1320.h file in C:\MCC18\h.

Mike.
Pommie is online now  
Old 15th June 2009, 04:27 PM   #30
Default

Thanks, I see a lot of the variables you used, but with "bits" at the end, what does that do?
Triode is offline  
Reply

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



All times are GMT. The time now is 05:58 AM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker