hallo

ik ben in proton pic basic mijn servo aan te sturen.
maar toen kwam ik er achter dat me pic met een kristal van 20MHz geen 50 Hz kan pulsen uit de ccp uitgang.
dus nu is mijn vraag hoe sturen jullie servo's aan met de ccp uitgang?

en hoe berekenen jullie de duty cycle want ik moe die aan geven met een getal van 0 tot 255.

Robbert

Duty cycle is niet zo moeilijk, als je weet dat je 50 pulsen per seconde hebt dan duurt 1 puls 20ms.

Als je weet dat in neutraal stand van die 20ms puls hij 1.5ms hoog is, volledig achteruit 0.5ms en volledig vooruit 2.5ms. De duty cycle is de lengte dat hij hoog is. Je moet dus gewoon verhoudingen gaan berekenen ofterwijl

1.5ms van 20ms = ..%
..% van 255 =

als je geen 50hz signaal kan maken met de ccp zal je het denk ik anders moeten doen.

voor mijn robot (2 servo motoren als aandrijving) heb ik interrupts gebruikt. TMR0 zo ingesteld dat hij elke 20ms een interrupt veroorzaakt en vervolgens uitgangen even (1-2ms hoog) daarna weer laag maken en uit de interrupt stappen.

succces er mee, ik kan je wel voorbeeldcode geven als je wilt

Willem

jha voorbeeld code is heeel mooi :)

wat is het verschil tussen de ccp en de interrupt?

Robbert

ik ben bezig geweest met het uitzoeken van die interupts in picbasic maar ik begrijp niet wat ze doen en hoe ze werken.
laat staan hoe ik ze moet progameren.

heeft er iemand nog een mooie uitleg :)

Robbert

de handleiding van picbasic misschien?

daar staat simpel in verklaart hoe je interrupts moet gebruiken en programmeren.

hier vind je een voorbeeld van hoe ik een isr voor UART gemaakt heb:

**klikkerdeklik**

een intereupt is dus een signaal op een poort?
en als er een signaal op die poort komt word er iets uit gevoerd?

en als dat is uit gevoerd gaat ie weer verder met het programma?

maar hoe kan ik hier mee dan een servo aan sturen?

Robbert

Op 23 april 2007 16:05:47 schreef Robbertbd:
een intereupt is dus een signaal op een poort?
en als er een signaal op die poort komt word er iets uit gevoerd?

Een interrupt is een onderbreking van het programma waar de PIC mee bezig was.
Er zijn echter verschillende interrupts: timer interrupts, change on portx interrupt, overflow interrupt...

en als dat is uit gevoerd gaat ie weer verder met het programma?

ja

maar hoe kan ik hier mee dan een servo aan sturen?

ik weet niet wat jij wilt

een servo moet iedere 20ms een puls krijgen om zijn stand of snelheid te behouden.(teminste de mijne wel :p).
maar mijn ccp kan geen 50 Hz leveren

dus heb ik rond gevraagt en iedereen zegt dat ik interupt moet gebruiken.

Op 23 april 2007 16:23:35 schreef JuuL:
Er zijn echter verschillende interrupts: timer interrupts, change on portx interrupt, overflow interrupt...

wil je er een paar uitleggen?

en als je hele simpele picbasic voorbeelden hebt zijn die ook welkom wat de meeste brgrijp ik niet. :P

ik ga die van de picbasic help ook nog maar eens door werken.

Robbert

zoek eens in de help file naar "hardware interrupt" daar staat een voorbeeld code. voordat je het helemaal snapt zal je het tog egt een stuk of 5 keer aandachtig moeten doorlezen (gok ik) bij mij ging het in ieder geval niet direct goed.

als je er niet uit komt zal ik vanavond of morge mijn code + complete toelichting + berekeningen voor snelheid en zo posten. als er niemand mij voor is geweest en ik vanavond tijd heb (ga nu weg) post ik t dus

MVG

Willem

oke al vast bedankt.

ik heb het voorbeeld van hardware intrerupt gevonden:


DEVICE 16F84 
 ON_HARDWARE_INTERRUPT GOTO Flash 
 ' Assign some Interrupt associated aliases 
 SYMBOL T0IE = INTCON.5         ' TMR0 Overflow Interrupt Enable 
 SYMBOL T0IF = INTCON.2         ' TMR0 Overflow Interrupt Flag 
 SYMBOL GIE = INTCON.7          ' Global Interrupt Enable 
 SYMBOL PS0 = OPTION_REG.0      ' Prescaler ratio bit-0 
 SYMBOL PS1 = OPTION_REG.1      ' Prescaler ratio bit-1 
 SYMBOL PS2 = OPTION_REG.2      ' Prescaler ratio bit-2  
 SYMBOL PSA = OPTION_REG.3      ' Prescaler Assignment (1=assigned to WDT 0=assigned to oscillator)  
 SYMBOL T0CS = OPTION_REG.5     ' Timer0 Clock Source Select (0=Internal clock 1=External PORTA.4) 
 SYMBOL LED = PORTB.1 
 
 GOTO Over_interrupt            ' Jump over the interrupt subroutine 

 ' Interrupt routine starts here 
Flash: 

 ' XOR PORTB with 1, Which will turn on with one interrupt and turn off with the next the LED connected to PORTB.0 
 PORTB = PORTB ^ 1 
 T0IF = 0                        ' Clear the TMR0 overflow flag 
 CONTEXT RESTORE                 ' Restore the registers and exit the interrupt 
 
Over_interrupt : 
 TRISB = %00000000               ' Configure PORTB as outputs 
 PORTB = 0                       ' Clear PORTB 
 ' Initiate the interrupt 
 GIE = 0                         ' Turn off global interrupts 
 PSA = 0                         ' Assign the prescaler to external oscillator 
 PS0 = 1                         ' Set the prescaler 
 PS1 = 1                         ' to increment TMR0 
 PS2 = 1                         ' every 256th instruction cycle 
 T0CS = 0                        ' Assign TMR0 clock to internal source 
 TMR0 = 0                        ' Clear TMR0 initially 
 T0IE = 1                        ' Enable TMR0 overflow interrupt 
 GIE = 1                         ' Enable global interrupts 
Inf: 
 LOW LED 
 DELAYMS 500 
 HIGH LED 
 DELAYMS 500 
 GOTO Inf

wat ik hier van begrijp is dat als HARDWARE_INTERRUPT pin 1 is dat hij dan flash uitvoert.
en anders hij gewoon het programma draait.

ik begrijp alleen nirt war dit voor is:


  SYMBOL T0IE = INTCON.5         ' TMR0 Overflow Interrupt Enable 
 SYMBOL T0IF = INTCON.2         ' TMR0 Overflow Interrupt Flag 
 SYMBOL GIE = INTCON.7          ' Global Interrupt Enable 
 SYMBOL PS0 = OPTION_REG.0      ' Prescaler ratio bit-0 
 SYMBOL PS1 = OPTION_REG.1      ' Prescaler ratio bit-1 
 SYMBOL PS2 = OPTION_REG.2      ' Prescaler ratio bit-2  
 SYMBOL PSA = OPTION_REG.3      ' Prescaler Assignment (1=assigned to WDT 0=assigned to oscillator)  
 SYMBOL T0CS = OPTION_REG.5     ' Timer0 Clock Source Select (0=Internal clock 1=External PORTA.4) 
 SYMBOL LED = PORTB.1

wat is intcon en hoe weet ik welke ik moet hebben?
en wat is option_reg?
en hoe weet ik op welke poort hij reageert?

Robbert

Dit is dus een voorbeeld van een timer interrupt. En die heb jij idd ook nodig.

wat is intcon en hoe weet ik welke ik moet hebben?
en wat is option_reg?
en hoe weet ik op welke poort hij reageert?

Lees het stuk over interrupts in de datasheet eens een aantal keer door. Hier staat het goed uitgelegt.

ik zie dat timer 0 1 en 2 allemaal andere dingen doen.
en klopt het dat je met intcon de timer selecteerd?

ik ga nu mijn 16F877A datasheet maar weer ens door werken :p

Robbert

[Bericht gewijzigd door Robbertbd op ]

iedereen bedankt voor de hulp.
ik ben gister door willem uitgebreid geholpen op msn (nog maals bedankt :P)

Robbert

ik heb wat gemaakt met interupt alleen zodra ik met mijn interrupt het commando servo uit voer word de rest van het programma niet meer uitgevoerd.
dit is mijn programma:


DEVICE = 16F877a              ; de pic
xtal 20                       ; de klok snelheid
all_digital on                ; alle siganle zijn digitaal
portb_pullups on              ; alle port b pull up weerstanden aan.

ccp1_pin portc.2

clear
cls

ON_INTERRUPT servosub

;        76543210
porta = %00000000             ; zet poort a waarden
trisa = %00110000             ; zet poort a in en uitgangen

;        76543210
porte = %00000000             ; zet poort e waarden
trise = %00000000             ; zet poort e in en uitgangen

; symbol's
symbol IrOutput0 = porta.0
symbol IrOutput1 = porta.1

symbol led0 = porta.2
symbol led1 = porta.3

symbol IrInput0 = porta.4      ; de TSOP
symbol IrInput1 = porta.5      ; de TSOP

symbol Servo1 = porte.0
symbol Servo2 = porte.1

; symbolen voor de timer
symbol TMR1IF  = PIR1.0       ; flag bit die op 1 komt als de timer tot zijn tijd heeft geteld.
symbol TMR1IE  = PIE1.0       ; hier mee kan interupt van TMR1 aan en uit
symbol TMR1ON  = T1CON.0      ; hier mee kanb de timer aan en uit
symbol TMR1CS  = T1CON.1      ; als deze 0 is is tmr1 in timer mode
symbol T1SYNC  = T1CON.2      ; deze heeft geen effect in timer mode
symbol T1OSCEN = T1CON.3      ; timer ocsilator deze doet niks als timer mode is geselecteerd(geen idee)
symbol T1CKPS0 = t1con.4
symbol T1CKPS1 = t1con.5
symbol PEIE    = intcon.6
symbol GIE     = INTCON.7

; instellingen
symbol TPulsTijd = 1000

; dim's
dim pulsen as byte            ; deze telt het aantal cyclesen in de for
dim sigin as bit              ; hier in word het resultaat van de ir ontvanger in op geslagen
dim detectie[2] as byte       ; deze telt het aantal keer "zien" met sensor 2
dim Timer1start AS tmr1l.word

detectie[0] = 0                  ; zet detectie op 0
detectie[1] = 0                  ; zet detectie op 0

goto HoofdProgramma

Servosub:
 servo servo1, 1000
 Timer1start = 40536
 TMR1IF = 0
context restore

; het programma
HoofdProgramma:
gie = 0
T1CKPS1 = 1
T1CKPS0 = 0
T1OSCEN = 0
T1SYNC = 1
TMR1CS = 0
TMR1ON = 1
TMR1IF = 0
TMR1IE = 1
PEIE = 1
gie = 1

while 1 = 1
 ; geeft 64 pulsen van 38000 Hz en iedere puls duurt 1 ms
 for pulsen = 0 to 65
  freqout iroutput0, 1, 38000  ; verzend een puls van 1 ms lang
  sigin = irinput0             ; stelt sigin gelijk aan de waarneming
  if sigin = 0 then inc detectie[0]  ; als er een object word "gezien"
  delayus TPulsTijd
 next
 
 for pulsen = 0 to 65
  freqout iroutput1, 1, 38000  ; verzend een puls van 1 ms lang
  sigin = irinput1             ; stelt sigin gelijk aan de waarneming
  if sigin = 0 then inc detectie[1]  ; als er een object word "gezien"
  delayus TPulsTijd
 next
 
 if detectie[0] > 10 and detectie[1] > 10 then
  led0 = 1
  led1 = 1
 elseif detectie[0] <= 10 and detectie[1] > 10 then
  led0 = 0
  led1 = 1
 elseif detectie[0] > 10 and detectie[1] <= 10 then
  led0 = 1
  led1 = 0
 else
  led0 = 0
  led1 = 0
 endif

 detectie[0] = 0                 ; detecties word weer terug gezet.
 detectie[1] = 0                 ; detecties word weer terug gezet.
wend
; einde porgramma

end 

wat kan ik plaats van Servo gebruiken of hoe kan ik dit anders op lossen?

Robbert

ik heb iets gemaakt wat mijn bij de interupt word uitgevoerd maar werkt niet:


Servosub:
 select servoselect
 case 0
  ServoTijd = 64649
  servo1 = 1
  servo2 = 0
 case 1
  ServoTijd = 64911
  servo1 = 0
  servo2 = 1
 case 2
  ServoTijd = 0;53036
  servo1 = 0
  servo2 = 0
 endselect
 inc Servoselect
 if servoselect > 2 then Servoselect = 0
 TMR1IF = 0
 Timer1start = servotijd
context restore

bijde servo's blijven draaien.

klopen mijn berekeningen wel?

ik heb mijn kristal / 4 gedaan = 5MHz de schaal is 1:8 dus 5M/8 = 625Khz.
1/ 625K = 1.6uS
1,6uS * 625 = 1mS
625 - 16bit (65536) = 64911
dat heb ik dus ingevuld en zou moeten werken toch?

Robbert

[Bericht gewijzigd door Robbertbd op ]