interrupt ger upp.nu behövs nya ide och förslag tror jag

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

"firmware 1.7" ?
Markus
Inlägg: 105
Blev medlem: 4 november 2005, 02:35:06
Kontakt:

Ok sodjan

Inlägg av Markus »

Vet inte men läste någon stans att firmware 1.7 finns på de nyaste programmerarna.Kan vara jag som är ute och cyklar med vet inte läste tror jag på programmeraren hemsida. Den som är hjärna bakom programmeranren .En holländare.

Skit i det Jag köper nog en ovasett får väll programmera om den när den versionen kommer ut.


Tänkte nu sodjan om du kan visa ett snarlikt program som icecap gjorde till min funktionbeskrivning i första inlägget i denna tråd.

Visa om du har lust med hur interrupt och timer ska programmeras. Med hjälp av detta kan jag lära mig och bygga vidare själv. Bara jag får se exemplet i assembler kod.

OBS alla exempel helst i assembler kod.
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Inlägg av Kaggen »

Jag har totat ihop switchsatsen i IceCaps exempel. Jag antar att du lusläst datablad och assemblerinstruktioner vid det här laget så du känner till kommandon som movlw, btfss, btfsc m.fl.

Denna kod tar inte hänsyn till PIC 18-familjens utökade instruktioner, men sodjan kan säkert rätta mig i de små detaljer jag översett.

Kod: Markera allt

VARIABLER	udata_shr
	Rotation	res	1
	Input		res	1


; Definiera upp några konstanter

#define	STOPPA_VARDE		1
#define	RULLA_ENA_HALLET		2
#define	RULLA_ANDRA_HALLET	4


MAIN_code	code

MAIN
	movlw	STOPPA_VARDE	; Rotation = Stoppa_Värde
	movwf	Rotation

MAIN_LOOP
	movfw	RA			; Input = RA & 0x07
	andlw	0x07
	movwf	Input

	; switch(Input)
CASE_1
	btfss	Input,0			; Bit 0 satt?
	goto	CASE_2		; Nix, hoppa vidare
	movlw	RULLA_ENA_HALLET	; Japp! Rotation = Rulla_Ena_Hållet
	movwf	Rotation
	goto	MAIN_LOOP		; break;

CASE_2
	btfss	Input,1			; Bit 1 satt?
	goto	CASE_4		; Nix, hoppa vidare
	movlw	RULLA_ANDRA_HALLET	; Japp!
	movwf	Rotation		; Rotation = Rulla_Andra_Hållet
	goto	MAIN_LOOP		; break;

CASE_4
	btfss	Input,2			; Bit 2 satt?
	goto	MAIN_LOOP		; Nix, hoppa vidare
	movlw	STOPPA_VARDE	; Japp! Rotation = Stoppa_Värde
	movwf	Rotation
	goto	MAIN_LOOP
Det finns en liten skillnad mellan IceCaps och mitt exempel, där jag kollar enbart specefika bitar som är satt, medans IceCap kollar "hela bytens" värde. Detta betyder att i mitt fall kan du ha fler än en knapp intryckt, koden triggar då på det första "caset" som är sant. IceCaps kod ignorerar samtliga tangenttryck om fler än en knapp är nedtryckt.

Mats
Markus
Inlägg: 105
Blev medlem: 4 november 2005, 02:35:06
Kontakt:

interrupt /timer frågor kod

Inlägg av Markus »

När kommer interrupt/timer funktioen in i bilden. Hur ser den koden ut. är det variablen rotation som jag ska skicka ut på utgången till styrningen på rc servot eller?. Var kommer fördröjningen mellan 1- 2 ms från.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Kaggen talar bara om "case" hanteringen vilket du har frågat om.
Koden ser OK ut.
Variablen "rotation" är bara en "flagga" som talar om vilken knapp
som senast trycktes ner, och alltså det aktuella "stautset" för servot.

"Rotation" får sedan användas i koden där själva servo signalen
genereras, alltså för att kortna ner eller öka på pulsen.

> Var kommer fördröjningen mellan 1- 2 ms från.

Den delen finns inte alls med i Kaggens kod, han visade
avkodningen av knapparna.

> Jag köper nog en ovasett får väll programmera om den när den versionen kommer ut.

Visst ha bara en extra 16F648A, så är det inga problem!

> Tänkte nu sodjan om du kan visa ett snarlikt program som icecap gjorde...

Jasså, det tänkte du... :-) :-)
Vi får se lite fram i nästa vecka, efter att en del prioriterade aktiviteter
(läs: kunder som betalar maten på bordet) är avklarade. Sen...
Jag vil inte bara kasta ihop något på en höft, jag vill även testa det på en PIC18.

> OBS alla exempel helst i assembler kod.

Av *mig* kommer du i alla fall aldrig att få något annat än assembler !
Markus
Inlägg: 105
Blev medlem: 4 november 2005, 02:35:06
Kontakt:

OK. uppfattat. Den som väntar på något, väntar aldrig f

Inlägg av Markus »

Någon som jämnt förklara hur jag får en timer som påverkar interrupt.
Hur man bygger upp något sådant. gärna med programmrader gärna i assembler.
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Inlägg av Kaggen »

Markus: Med risk för att låta som en upphakad CD, det mesta du behöver veta om hur man sätter upp interrupt och timers står i databladet för din processor.

Det står vilka bitar som skall sättas och vilka register som skall skrivas i. Jag tror dock du (och exos som skriver i en annan tråd) måste läsa på mer om assembler-programmering generellt, dessutom om bitar, bytes, hexadecimala och binära talsystemet.

När du vet hur register och bitar är ordnade och hur du sätter önskade bitar och kan utföra tester och villkorliga hopp i assembler, kanske det är dags att ge sig på interrupt och större programprojekt.

Testa att slänga ihop ett projekt som testar en bit och utför ett villkorligt hopp beroende på om den är satt eller inte, eller som exos, tänd en diod vid knapptryck. När du fått häng på det och hur assemblerkod exekveras av processorn, så löser sig det mesta.

Mats
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Jag har skrivit en interrupt-rutin som styr ett RC-servo.
Den är bara testad i MPLAB simulator.
Egentligen borde jag inte posta den men jag gör det iaf.

Koden är avsedd för Pic18 40Mhz (10Mhz internt)
Timer0 ska configureras som 16bit med prescaler 1:4
PWM-perioden är 20ms (50Hz). Servosignalen är hög 1-2ms

CurServoPos är nuvarande servoposition. 0 är c:a 2ms. 255 är c:a 1ms.
CurServoPosL är decimaldelen till CurServoPos (används för att servot ska kunna vrida sig långsamt).
DestServoPos är Målpositionen (ändras lämpligtvis från huvudloopen).
ServoSpeed är farten. 1 = ändläge-ändläge på c:a 50sekunder. 255 = ändläge-ändläge på c:a 0.2sekunder (ändras lämpligtvis från huvudloopen).
ServoSpeedL och ServoSpeedH är farten i 16bitar.
PWMtimeHi_L och PWMtimeHi_H är tiden som servosignalen ska vara hög (tiden är i negativ form för att Timer0 räknar upp).
PWMtimeLow_L och PWMtimeLow_H är tiden som servosignalen ska vara Låg (tiden är i negativ form för att Timer0 räknar upp).

I huvudloopen kan man beordra servot att vrida sig till önskad position med önskad fart:

Kod: Markera allt

	clrf	ServoSpeed
	movlw	position
	movwf	DestServoPos
	movlw	fart
	movwf	ServoSpeed

Kod: Markera allt

ISR:
	btfsc	INTCON,TMR0IF	;Timer0 int?
	bra	ServoISR

	retfie	FAST

ServoISR:
	btfsc	ServoPort	;ServoPort låg?
	bra	ServoPortHi

;ServoPortLow:	;ServoPort är låg
	call	CalcPWM

	movf	PWMtimeHi_H,w
	movwf	TMR0H
	movf	PWMtimeHi_L,w
	movwf	TMR0L			;Överför nytt värde till Timer0

	bsf	ServoPort

	bcf	INTCON,TMR0IF	;interrupt flag Timer0
	retfie	FAST

ServoPortHi:	;ServoPort är hög
	bcf	ServoPort
	movf	PWMtimeLow_H,w
	movwf	TMR0H
	movf	PWMtimeLow_L,w
	movwf	TMR0L			;Överför nytt värde till Timer0

;------ Omvandla ServoSpeed till 16bitar med lämplig mult
	movf	ServoSpeed,w
	mullw	.26
	movff	PRODL,ServoSpeedL
	movff	PRODH,ServoSpeedH

;------ Testa vilken som är störst av CurServoPos och DestServoPos
	movf	DestServoPos,w
	subwf	CurServoPos,w

	bz	CurPosPastDest		;Lika
	bnc	ServoDiffNegative	;CurServoPos < DestServoPos
	bc	ServoDiffPositive	;CurServoPos > DestServoPos

ServoDiffNegative:
;------ Addera ServoSpeed till CurServoPos
	movf	ServoSpeedL,w
	addwf	CurServoPosL
	movf	ServoSpeedH,w
	addwfc	CurServoPos
	bc	CurPosPastDest		;Resultatet blev > 255

;------ Testa vilken som är störst av CurServoPos och DestServoPos
	movf	DestServoPos,w
	subwf	CurServoPos,w
	bc	CurPosPastDest		;CurServoPos > DestServoPos
	bra	TimerIntEnd

ServoDiffPositive:
;------ Subtrahera ServoSpeed till CurServoPos
	movf	ServoSpeedL,w
	subwf	CurServoPosL
	movf	ServoSpeedH,w
	subwfb	CurServoPos
	bnc	CurPosPastDest		;Resultatet blev < 0

;------ Testa vilken som är störst av CurServoPos och DestServoPos
	movf	DestServoPos,w
	subwf	CurServoPos,w
	bnc	CurPosPastDest		;CurServoPos < DestServoPos
	bra	TimerIntEnd

CurPosPastDest:
;------ Om CurServoPos gick förbi så sätter vi den = DestServoPos
	movff	DestServoPos,CurServoPos
	movlw	.128		;Decimaldelen = 0.5
	movwf	CurServoPosL

TimerIntEnd:
	bcf	INTCON,TMR0IF	;interrupt flag Timer0
	retfie	FAST

CalcPWM:
;------ Här omvandlar vi CurServoPos till PWM-tider
;------ PWMtimeHi = CurServoPos * 10 - 5000
	movf	CurServoPos,w
	mullw	.10

	movlw	088H		;5000 L
	subwf	PRODL,w
	movwf	PWMtimeHi_L
	movlw	13H		;5000 H
	subwfb	PRODH,w
	movwf	PWMtimeHi_H

;------ PWMtimeLow = 65536 - 50000 - PWMtimeHi
	movf	PWMtimeHi_L,w
	sublw	0B0H		;65536-50000 L
	movwf	PWMtimeLow_L
	movlw	03CH		;65536-50000 H
	subfwb	PWMtimeHi_H,w
	movwf	PWMtimeLow_H
	return

Kod: Markera allt

Init:
	bcf	ServoPort
	clrf	CurServoPos
	clrf	CurServoPosL
	clrf	DestServoPos
	clrf	ServoSpeed
Markus
Inlägg: 105
Blev medlem: 4 november 2005, 02:35:06
Kontakt:

sorry chribbe76

Inlägg av Markus »

detta var lite för mycket för mig att förstå. Kan du bara visa själva timer interrupt funktionen. Resten med delay och fördröjningar hit och dit det fixar jag tror jag.Det är bara hur man får en interrupt att gå på en timmer. Så när det har gått 50 ms eller vad man vill ställa in så bryter huvudprogrammet och kör en intterupt subrutin. Bara detta skulle vara intressant att se. Men Chribbe76 tack ändå. Blev lite för mycket kod för mig.
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Du är rolig du markus.

Självklart är det för mycket kod för dig att förstå(just nu) men jag tänkte att du skulle bli inspererad och försöka förstå hur min kod fungerar tillsammans med simulatorn och datablad.

Att göra ett tidsinterrupt borde du klara vid det här laget men ok.
När timer0 (som i exemplet är 16bitar) slår runt får du ett interrupt.
Prescaler 1:4 betyder att den räknar 1 steg på 4 klockcycler(interna).

Kod: Markera allt

Init:
	movlw	b'10000001'	;Timer0 16bit prescaler 1:4
	movwf	T0CON
	clrf	TMR0H		;Denna instruktion förändrar inte timerns värde
	clrf	TMR0L		;Låga delen av timer0 blir 0 och höga delen uppdateras samtidigt
	bsf	INTCON2,TMR0IP	;Timer0 Hög prio int
	bcf	INTCON,TMR0IF	;Timer0 int flagga
	bsf	INTCON,TMR0IE	;Timer0 int på
	bsf	RCON,IPEN	;Hög och låg prio int används
	bsf	INTCON,GIEL	;Enable låg prio int
	bsf	INTCON,GIE	;Enable Hög och låg prio int
Jag hoppas att du tycker att programmering är roligt för det är en förutsättning för att man ska kunna lära sig något.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Markus > detta var lite för mycket för mig att förstå.

Hur lång tid har du lagt ner på att studera koden?
Kan inte vara speciellt mycket...

Markus> Kan du bara visa själva timer interrupt funktionen.

**LÄS** databladet och återkom sedan med frågor kring det som du inte förstog !
Allt är mycket tydligt beskrivet där.
När det gäller Chibbes76's kod så är den antagligen OK, jag har inte kollat i detalj.
Bara ett par mindre saker (det skall alltid vara nått... :-) )...

Personligen föredrar jag att ha *en* utgång från ISR'en. D.v.s bara en RETFIE.
Det blir rörigt med flera RETFIE och dessutom blir den kod som man vill köra
direkt föra RETFIE dubblerad ("bcf INTCON,TMR0IF" i detta fall).
Det är även lite otydligt var ISR'en "slutar" i källkoden. D.v.s att ISR'en borde
alltid avslutas vid "TimerIntEnd:".

Som jag förstår det, så beräknas både 1-2 ms pulsen och 20 ms pausen dynamiskt.
Jag skulle sätta en fast 20 ms pause för att slippa en del beräkningar, för
servot spelar det ingen roll. "CalcPWM" skulle bli lite enklare.
D.v.s att "PWMtimeLow_L" och "PWMtimeLow_H" kan ha fasta hårdkodade värden.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

En liten detalj bara...

> Koden är avsedd för Pic18 40Mhz (10Mhz internt)

Snarare "PIC18 med 10 Mhz kristall och PLL (40 Mhz internt)". Eller kanske:
"PIC18 40 Mhz (10 mips)", men 10 mips är ju inte helt sant...

> Prescaler 1:4 betyder att den räknar 1 steg på 4 klockcycler(interna).

"Klockcycler" och "instruktionscycler" inte samma sak.

1 instruktionscycel ("Tcy" i databladet) = 4 klockcycler ("Tosc" i databladet).

Så det ska vara antingen :
"Prescaler 1:4 betyder att den räknar 1 steg på 16 klockcycler (interna, "Fosc")."
eller (och bättre och i linje med hur databladet benämner det) :
"Prescaler 1:4 betyder att den räknar 1 steg på 4 instruktionscycler ("Tcy" eller "Fosc/4")."

Jag håller med om att databladet inte är helt tydligt på denna punkt,
ibland skriver de "Tcy", ibland "Tosc/4", vilket ju i och för sig betyder samma sak... :-)
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Visst, det är lite klurigt att beskriva vissa saker ibland, det blev tydligare med din beskrivning.

Jag kan hålla med om att det blir mindre stökigt med bara en RETFIE, men om det är väldigt tidskritiskt så kan det vara att föredra.

Ja, jag beräknar 20ms tiden dynamiskt, servot kräver det inte så man kan skippa den beräkningen men resultatet av att utesluta det blir att servot kommer vrida sig olika snabbt beroende på var på rörelsen den befinner sig (gillas icke av mig).

(Jag vet att min kod innehåller lite "onödiga" saker, såg det först efter att jag postat den men det är småsaker så jag bryr mig inte om att ändra det).

[edit] skrev på brottom inte bra.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Angående en eller flera RETFIE,
Jo, det kan vara en poäng, men å andra sidan, om man inte "har tid" med
en extra GOTO i sin ISR, så har man sannolikt betydligt större problem väntande
"om hörnet", och det är hög tid att fundera på om designen är riktigt "sund".
Marginalerna är ju redan helt borta och det kan vara en anledning till lite oro...

Det är också sant att man, men den fasta 20 pausen, får en variation på
+/- 2,5% i hur fort servot rör sig, beroende på var man är "på skalan".
Om det är ett problem, så behövs (t.ex) din lösning.

En annan lösning skulle kunna vara att använda en helt separat timer
för att ge intervallet mellan up/ner räkningen av 1-2 ms pulsen. Den
blir då oberoende av 20 ms pulsen...

Slutligen, en *helt* felfri kod är ju ingen utmaning, eller hur ? :-)
Markus
Inlägg: 105
Blev medlem: 4 november 2005, 02:35:06
Kontakt:

Tack ska ni ha.speciellt chribbe76 och sodjan

Inlägg av Markus »

Tack så mycket för hjälpen angående timer/interrupt. Bu förstod jag med en gång. Fan så härligt. Nu ska jag försöka att bli klar med mitt project. I dag till och med.
Alien puffran ska bara fungera så klockrent efter detta.


Fan i dag ska ni veta att jag kom över ett goulden advance oscilloskop med manualer för 500 kr. Visst det är jävligt gammalt men fan det fungerar för det lilla jag kommer att göra.


Sedan pratade jag mer service killen jag känner att han skulle kolla åt mig om han kunde hitta en funktiongenerator och likspänningsagreggat åt mig med billigt. Hadde möjligheter att importera från kina.Dom var lite billigare där sa han.


Du sodjan ursäkta frågan men får känslan att du har stor kunskap och hållit på microprocessor programmering. Vad har du för utbildning om jag får fråga. På din hemsida står det Konsult Jan-erik


Ps: Jämnt nu känns det som jag kunde ger er en riktig microprocessor kram. Så kram i från mig till er. Tack och hej leverpastej :D
Skriv svar