Delay bekymmer

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Markus
Inlägg: 105
Blev medlem: 4 november 2005, 02:35:06
Kontakt:

Delay bekymmer

Inlägg av Markus »

Hej jag har ett litet problem.Det är så att jag har programmerat ett program i mplab till pic 18f452.
När jag simulerar detta program så fungerar det som det ska. Men sedan när jag lör det i verkligheten och kopplar upp det så fungerar det inte alls.

Problemet är att till/ och från slaget av min utgång som går till lysdioder går för fort att blotta ögat hinner inte med. Så då tänkte jag att lägga en delayer i mellan till /och från läget. denna delay subrutin ser ut så här(Bygger på två st loppar, en inre och en yttre).


Delayfunk:
Movlw HFFFF
Movf delay1
Yttre_ loop: Movlw HFFFF
Movf delay2
Inre _loop:
Decfsz delay1
Goto inre_loop
Decfsz delay1
Goto Yttre_loop
Return



Men som ni förstår men inte jag så kommer jag inte få tillräklig fördröjning med denna typen av delayer. Jag behöver att komma upp i en sekund i alla fall. Så man hinner att reagera. När jag kör tid hur länge det tar för picen att köra igenom denna kod så tar det bara 30ms sekunder. Med den hastighet hinner man inte att se någon. Så min fråga är hur man ska skapa en sådan fördöjning som vara i alla fall en sekund?
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Lägg ytterligare en yttre loop så att du har 3 loopar i varandra.

Eller lägg in en några st NOP'ar innuti den inre loopen.

Eller! Nu när jag kollade på din kod så ser jag att du aldrig decrementerar Delay2. Båda Decfsz går på variabeln delay1 - vilket innbär att du inte alls har simuletar koden och fått den att fungera bra i simulatorn ;-) Fixa koden så fungerar den säkert bättre.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Så min fråga är hur man ska skapa en sådan fördöjning som vara i
> alla fall en sekund?

Med en timer. Programvaru-delays är OK för mycket korta delays, kanske
upp till 100 us, sedan är det timers som skall användas.
Du har ju en processor med gott om timers, så det är ett ganska enkelt val... :-)
Markus
Inlägg: 105
Blev medlem: 4 november 2005, 02:35:06
Kontakt:

ok,vist ett exempel på hur man kan skapa timer med delay

Inlägg av Markus »

Hur ser ett delay funktion ut med hjälp av timer.Kan du visa mig ett exempel hur man kan skapa en sådan delay.det har jag haldrig gjort förut.bara andvänt delay enlig föregående kod bit.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Jag stängde just av PC'n där jag har MPLAB och källkoder... :-)

Men i princip står allt du behöver veta i databladet, så
jag föreslår att du börjar där. Du har väl läst databladet
flera gånger, eller hur ?

I princip rör det sig om att :
- Sätta upp en timer med ett lämpligt intervall.
- Sätta upp interrupt från timern.
- Fixa en interruptrutin (ISR) där du togglar LED'en.

Sedan kommer allt att nästan gå av sig självt... :-)

Jag har inte i huvudet just nu vilken av de 4 timers som
är lämpligast, du får kolla lite i databladet vilken som ger
längst intervall.

Slutligen, koden som du har postat fungerar *inte* i MPLAB/MPASM,
eftersom allt står i position 1. Se till att din kod är korrekt
formatterad och använd "code" taggarna
Användarvisningsbild
klasg
Inlägg: 187
Blev medlem: 29 juni 2005, 21:12:24

Inlägg av klasg »

En label får inte innehålla mellanslag. (kan den inte heller....så det är konstigt att du kan simulera din kod...). Ett av flera fel i din kod.

Hur vet du att det är 30ms? Vad går PICen i för hastighet? Kör du i 4MHz så behöver du 1 miljon cyklar för att få 1 sekunds fördröjning...

Men timer är nog bättre iofs, men ska du bara blinka med en diod så spelar det ingen roll. Testa båda sätten.
Markus
Inlägg: 105
Blev medlem: 4 november 2005, 02:35:06
Kontakt:

Jag har nu läst i genom databladet

Inlägg av Markus »

Får igen riktig kontroll över hur jag ska programmera för att jag ska få en subrutin som ger mig en delay tid på 1 sekund.ingen som kan ge mig ett exempel hur det skulle se ut med timer
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

OK, om du vill ha en *subrutin* där du "ligger kvar" under hela sekunden,
så är det enklast att avlusa dina loopar du hade först. Jag antog att
man vill ha processorn ledig för annat medans man väntar på att
sekunden ska gå...

Men i så fall :

> Movlw HFFFF

W-reg är *en* byte (8 bitar). Alltså MOVLW h'FF'
(Och för max delay kan du skriva MOVLW h'00'...

Den sista decfsz ska vara på delay2.

Sen kommer du sannolikt att behöva en delay3 och en "mellan_loop" också.
Markus
Inlägg: 105
Blev medlem: 4 november 2005, 02:35:06
Kontakt:

nej det vill jag inte utan en subrutin

Inlägg av Markus »

Nej jag vill bara ha en subrutin som ger mig ca 1 sekund i fördröjning alltså. Som jag kan anropa från andra dela i programmet med instruktionen call delay typ. när man behöver en fördröjning mellan vissa saker i koden för att ögat ska hinna och reagera.
koden skulle alltså se ut enligt följande med en delay 3 till:






Movlw HFF
Movf delay3


yttre_loop2: Movlw HFF
Movf delay2

Yttre_ loop: Movlw HFF
Movf delay1
Inre _loop: Decfsz delay1
Goto inre_loop

Decfsz delay2
Goto Yttre_loop

Decfsz delay3
Goto Yttre_loop2



Return


Är det så här du menar. detta skulle bli 256*256'256 instruktioner=16777216 st
Senast redigerad av Markus 14 februari 2006, 10:00:55, redigerad totalt 1 gång.
Användarvisningsbild
klasg
Inlägg: 187
Blev medlem: 29 juni 2005, 21:12:24

Inlägg av klasg »

Vilken hastighet springer processorn i? Det måste du ju veta för att veta hur många cyklar programmet ska köra.

En label kan fortfarande inte innehålla mellanslag.
Dessutom ska du skriva movwf istället för movf.

Har du testat simulera?
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Här http://www.piclist.com/techref/piclist/ ... /delay.htm har du en kodgenerator som gör en fördröjningsrutin åt dig, det är bara att klistra in koden.

Du matar in hur lång fördröjningen ska vara i sekunder typ 0.8, vilken klockfrekvens som din uC kör på tex 12 Mhz och klickar på Generate! så vips har du fått den här koden att klistra in i ditt program.

Kod: Markera allt

; Delay = 0.8 seconds
; Clock frequency = 12 MHz

; Actual delay = 0.8 seconds = 2400000 cycles
; Error = 1.94025536378e-014 %

	cblock
	d1
	d2
	d3
	endc

Delay800mS
			;2399990 cycles
	movlw	0x47
	movwf	d1
	movlw	0x3C
	movwf	d2
	movlw	0x06
	movwf	d3
Delay800mS_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay800mS_0

			;6 cycles
	goto	$+1
	goto	$+1
	goto	$+1

			;4 cycles (including call)
	return
Användarvisningsbild
klasg
Inlägg: 187
Blev medlem: 29 juni 2005, 21:12:24

Inlägg av klasg »

http://www.teknikutbildning.se/default.html finns också, men man lär sig inte mycket på det sättet...
Markus
Inlägg: 105
Blev medlem: 4 november 2005, 02:35:06
Kontakt:

ok,vart är mellan slaget på denna label

Inlägg av Markus »

yttre_loop2 tex igenstans. förstår inte vad du menar. Men har jag rätt om vi bortser från bagateller som mellan slag att detta program kommer att göra ca 256*256*256 instruktioner. Ska bara kolla så jag tänker rätt.Ska simulera senare skulle bara kolla så jag är inne på rätt bana. Så jag fattar sodjan vad han menar med en tredje loop och avlusning av min kod.



är fortfarande bara grönjöling inom micropic prog men vill lära mig.därför frågar jag en del. Tex fattde inte riktig hur sodjan vill att jag kunde göra en delayer av timer. När jag ville bara ha en subrutin som jag kan anropa när jag vill för att skapa en sekunds fördröjning.

Men går det att skapa med timer så är jag mycket intresserad att se hur detta fungerar.
Användarvisningsbild
klasg
Inlägg: 187
Blev medlem: 29 juni 2005, 21:12:24

Inlägg av klasg »

"Yttre_ loop" och "Inre _loop" <-- Ser du nu? ;). Föresten är det ingen bagatell, för koden kommer inte funka.

Du har fortfarande inte svarat på klockhastigheten...

EDIT: Jag roade mig med att skriva om din kod lite. Nu borde den iaf gå igenom MPLAB...Har inte testat än dock.

Kod: Markera allt

delay   movlw   hff
        movwf   delay3

yloop2  movlw   hff
        movwf   delay2

yloop   movlw   hff
        movwf   delay1

iloop   decfsz  delay1,f
        goto    iloop
        decfsz  delay2,f
        goto    yloop
        decfsz  delay3,f
        goto    yloop2
        return
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Nej jag vill bara ha en subrutin som ger mig ca 1 sekund i fördröjning alltså.

OK. det *normala* är att man inte vill "låsa up" processorn under tiden,
utan att den kan göra andra saker under tiden. Det var det jag menade.

> Tex fattade inte riktig hur sodjan vill att jag kunde göra en delayer av timer.

Enkelt, genom att läsa på om timers och interrupt... :-)

Här är en enkel Blink-a-LED som använder en timer.
Koden är för en PIC16, så du får justera lite. Principerna bör du dock
kunna läsa ut. :

Kod: Markera allt

;**********************************************************************
;   Enkelt blink-a-led, 16F870.                                       *
;                                                                     *
;**********************************************************************
;    Files required:  P16F870.INC                                     *
;                     16F870.LNK                                      *
;                                                                     *
;**********************************************************************


	list      p=16f628A
	#include <p16f628A.inc>
	
	__CONFIG   _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT

RESET_VECTOR    CODE    0x000     ; processor reset vector
	    goto    start             ; go to beginning of program


INT_VECTOR      CODE    0x004     ; interrupt vector location
        goto    isr_routine       ; goto main interrupt service routine.
        

MAIN    CODE

start
;        banksel adcon1
;        movlw   h'06'
;        movwf   adcon1            ; Stäng av ADC.

        banksel cmcon
	movlw	h'FF'		; Shut off A/D-stuff value
	movwf	CMCON		; No A/D-stuff

        banksel trisa
        clrf    trisa
        clrf    trisb
;        clrf    trisc             ; Alla pinnar = utgångar.

        banksel t1con
        movlw   b'00110001'
        movwf   t1con             ; Se datablad...
        
        banksel pie1
        movlw   b'00000001'
        movwf   pie1              ; Enable avbrott från TMR1.

        banksel intcon	
        bsf     intcon, peie
        bsf     intcon, gie       ; Enable avbrott...

loop
        goto loop                 ; Vänta på avbrott...
 


ISR_ROUTINE  CODE

isr_routine

        banksel portb
        comf    portb            ; Blinka !!

        banksel pir1
        bcf     pir1, tmr1if     ; clear avbrotts flagga.

        retfie

		END


> Ska bara kolla så jag tänker rätt.Ska simulera senare

Varför inte göra tvärt om ? Simulera först, då kanske du t.o.m inte alls behöver posta den... :-)
Skriv svar