Hjälp med kod 16F84 (nybörjare)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Icecap skrev:Nämen... *suck*

OK, vi tar det tydligt och lugnt: (utklipp med pseudoadressor)
...
Ser ni felet?

Det ÄR $-2 som gäller!!!

Exile: din kod representerar INTE korrekt holta's. Hans kod är..
Hmm... fösökt tyda koden innan du dumförklara folk?
holta
Inlägg: 10
Blev medlem: 8 september 2005, 10:25:39
Ort: Borensberg
Kontakt:

Inlägg av holta »

Ska titta på andra kretsar i framtiden, var bara det att jag har haft F84:an liggandes ett tag. Jag ser fram imot att lära mig mera :)
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

exile: har DU tydat koden innan? Återkom när du har det.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Tja här min tydning av coden, och MPLAB verkar hålla med mej så var har jag fel?
eller tål du inte du har fel :?:

Kod: Markera allt

	DELAY1
0001		MOVLW   D'7'
0002		MOVWF   TIMER1		;Timer1 = 7

0003		MOVLW   D'47'
0004		MOVWF   TIMER2		;Timer2 = 47

0005		MOVLW   D'3'
0006		MOVWF   TIMER3		;Timer3 = 3

	DELAY_1						  ;while(1) {
0007		DECFSZ  TIMER1,F	 ;	if(Timer1-- ==0) {
0008		GOTO    $+2			;	om vilkoret inte är uppfylt hoppa till 0010
0009		DECFSZ  TIMER2,F	 ;		if(Timer2-- == 0) {
0010		GOTO    $+2			;		om vilkoret inte är uppfylt hoppa till 0012
0011		DECFSZ  TIMER3,F	 ;			if(Timer3-- == 0) break;
0012		GOTO    DELAY_1	  ;			om vilkoret inte är uppfylt hoppa till 0007
						            ;		}
						            ;	}
						            ;}
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Tyvärr för dig gör koden vad den är programmerat till men det är inte den funktion som eftersträvs.

DECFSZ x,y betyder: decrement register, skip if zero. För att göra en delayloop med det gör man såhär:

Kod: Markera allt

  movlw d'100' ; Sätter något värde som beror på delayen man vill ha
  movwf Variabel ; Våra räknevariabel
DelayLoop
  decfsz Variabel,f ; Det är vi nog överens om vad den gör
  goto DelayLoop ; Annars upprepas delayen ju inte!!!
Så MPLAB kan hålla med dig allt du vill, det är fel för det! Jag påstår inte att ditt program är felkonstruerat, jag påstår bara att det INTE motsvarer den delay som önskas då $+2 hoppar förbi den.

Då 'goto' måste hoppa TILLBAKA för att upprepa till 'Variabel' är räknat ner till noll måste den "rätta lösningen" vara "$-2".

Att det sedan är ytterst dumt att skriva så då det mycket lätt kan skapa förvirring (se bara denna tråd) är ytterligare en anledning till att _aldrig_ ange adressor på det vis men _alltid_ ange hopp till labels.

Så jo, jag tål att ha fel men när jag har rätt, ska jag då ge mig?

Att hela delayen i grunduppsättningen är felskrivet hjälper ju inte just.
Det RÄTTA sätt att göra delay med dessa upprepningar är:

Kod: Markera allt

Delay1
  movlw d'7'
  movwf Timer1
Delay_Sub1
  movlw d'47'
  movwf Timer2
Delay_Sub2
  movlw d'3'
  movwf Timer3
Delay_Sub3
  decfsz Timer3,f
  goto Delay_Sub3
  decfsz Timer2,f
  goto Delay_Sub2
  decfsz Timer1,f
  goto Delay_Sub1
  return
I din kod hopper den från adress 0008 till adress 0010 och vidare till 0012 men du har ju animerat det i MPLAB eller hur?
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Det finns säkert 100 olika sätt att göra en delay loop och många är säkert dåliga men den här algoritmen anser jag är bra skriven då den tar 7cycklar i en loopen oavset vilket tal som matas in Det inbär att lätt räkna ut hur lång tid det tar delvis 7 * loop - 1, där loop är antalet vill att loopar man vill att delayen ska göra.. loop är i det här fallet en 24bitars variabel som består av Timer1, Timer2 och Timer3 vilket är helt linjärt
Att hela delayen i grunduppsättningen är felskrivet hjälper ju inte just.
Det RÄTTA sätt att göra delay med dessa upprepningar är:

Kod: Markera allt

    Delay1
      movlw d'7'
      movwf Timer1
    Delay_Sub1
      movlw d'47'
      movwf Timer2
    Delay_Sub2
      movlw d'3'
      movwf Timer3
    Delay_Sub3
      decfsz Timer3,f
      goto Delay_Sub3
      decfsz Timer2,f
      goto Delay_Sub2
      decfsz Timer1,f
      goto Delay_Sub1
      return
Där imot ditt exempel varierar exekverings tiden beronde på vilket tal som matas in, desutom är den icke linjär delvis tiden ~ (variation beronde på vilket tal som körs) * Timer1 * Timer2 * Timer3 vilket är allt annat än roligt...

Det finns många sätt att skriva en delay loop men ditt sätt är klart sämmre...
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Öhhh... har du inte läst att det som var grundidéen var att den skulle räkna upp med ca: 1 sek (nåja, synbart utan fladder antar jag) och det är just grejen med att delayen ska vara olinjär: höga tal ger långt delay, små tal ger korta.

"Din" version med $+2 fungerar helt enkelt inte, simulera den i MPLAB (det har jag gjort) och du vill se att TIMER1 är den _enda_ variabel som räknas ner.

Att det inte är lätta att räkna delayen på så stora delays är helt OK, börjar man med långa delay på detta sätt är man på fel spår hur som helst men faktum kvarstår: det ska INTE vara $+2!

Jag vill dessutom påstå att en funktion som består av Timer1 * Timer2 * Timer3 är ganska lätt att beräkna och ganska linjär också.

Jag undrar lite över hur du kan utlåta dig om att min kod är sämre när "din" inte ens fungerar :?:

Så simulera i MPLAB och håll ett koll på TIMER1, TIMER2 och TIMER3 och återkom sedan.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Om jag inte minns fel så är delay rutinen genererad från en av de kodgeneratorer som
finns på www.piclist.com, eller hur ?

Om de kan man generellt säga att då är konstruerade av några av de
"vassaste" PIC porogrammerna i världen, i det här fallet Nikolai Golovchenko
vilken har skrivet flera av kodgeneratorerna där. Jäkligt duktig kille.

Koden är inte alltid den mest lättlästa, men ofta effektiv och "smart" på andra sätt.
Sånt som man kan läsa för nöjes skull i sängen... :-)

Och det finns *i allmänhet* ingen anledning att tro att koden inte gör det den ska.
Dock, jag ska köra i MPSIM som Icecap bara för att jag är nyfiken, förden ger ju
faktiskt 1 sek delay (vid 4 Mhz).

Notera också att koden är genererad för att ge just *1 sek*, generatorn
ger lite olika lösningar beroende vilket delay man anger...

Icecap, kolla gärna sidan och prova själv !
http://www.piclist.com/techref/piclist/ ... /delay.htm
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Icecap skrev:Öhhh... har du inte läst att det som var grundidéen var att den skulle räkna upp med ca: 1 sek (nåja, synbart utan fladder antar jag) och det är just grejen med att delayen ska vara olinjär: höga tal ger långt delay, små tal ger korta.

"Din" version med $+2 fungerar helt enkelt inte, simulera den i MPLAB (det har jag gjort) och du vill se att TIMER1 är den _enda_ variabel som räknas ner.

Att det inte är lätta att räkna delayen på så stora delays är helt OK, börjar man med långa delay på detta sätt är man på fel spår hur som helst men faktum kvarstår: det ska INTE vara $+2!

Jag vill dessutom påstå att en funktion som består av Timer1 * Timer2 * Timer3 är ganska lätt att beräkna och ganska linjär också.

Jag undrar lite över hur du kan utlåta dig om att min kod är sämre när "din" inte ens fungerar :?:

Så simulera i MPLAB och håll ett koll på TIMER1, TIMER2 och TIMER3 och återkom sedan.
Har du kört koden i MPLAB? iså fall hade du sett att Timer1,Timer2 och Timer3 ändras...

Angånde linjäriteten så menar jag att du kan öka delay loopen med 1 i hela området vilket inte du kan göra...

exempel:
936 = 39 * 3 * 8
937 = går inte att lösa pgrund av att det är ett primtal...
771 = är inte ett primtal med kan endast fakoriseras med 3 och 257 men 257 ryms inte i en byte vilket gör att det inte går välja
osv...
Delvis finns det värden som inte kan uppnås med T1*T2*T3 vilket innebär att den inte är linjär, där imot (T1+T2<<8+T3<<16) vilket är helt linjärt...

Så antigen har du inte kört koden i mplab eller så vågar du inte erkänna att du har fel
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Icecap: Variablerna slår ju runt i exiles kod, därför kommer alla räknare att användas flera gånger. Och när pekaren hoppar frammåt kommer ju pekaren till slut till GOTO DELAY_1 så att den hoppar bakåt.

Dock stämmer inte exile's tolkning av koden
if(Timer--==0) ska bytas ut mot if(--Timer==0)

Jag måste också ifrågasätta ditt påstående om upplösningen exile. Om du ändrar T1 med 1 kommer ju rutinen öka fler än 1 cykel eftersom loopen tar längre än 1 cykel.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Bering:
Givet viss kommer den ta fler cykler närmare bestämd 7st
vilket ger 7*(T1+T2<<8+T3<<16)+k så men jag kan inte se att jag har påstått något annat...

och if(Timer--==0) var en tabbe från min sida... men det sådant som händer :)
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Det har du rätt i. Jag tolkade " öka delay loopen med 1" som att 1 var en cykel, men du menar så klart ett varv i loopen.
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Kan vi få ett moget "Jag hade fel" från Icecap nu. :wink:
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

exile> Givetviss kommer den ta fler cykler närmare bestämd 7st

Notera dock att kodgeneratorn som den aktuella koden kommer från
kan ge en rutin för vilket antal instruktionscykler som helst, inte bara multiplar av 7.

T.ex så ger DELAY rutinen i holta's kod *inte* 1 sekunds delay (= 1.000.000 cykler
vid 4 Mhz) utan 999.994 cyckler, vilket tillsammans med de 6 cyckler
som det tar att göra "CALL L1", CALL L2" o.s.v ger exakt 1.000.000
cykler mellan varje ändring av PORTB. Snyggt !

Kör gärna generatorn och ange 1 sek (eller 1000000 cykler) och
notera skillnaden !

Det är alltså inte alls meningen att man ska fippla med värderna
för de tre räknarna, utan man fixar en ny kod från generatorn om
man behöver en annan delay. Sen kan man verifiera i MPSIM,
men det är en annan fråga...
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Då så, en god natts sömn och lite eftertanke kan vara en bra sak. Jag har kollat igenom koden, simulerat en del mer och den fungerar tamigfan rätt!

Så ja: jag ska inte vara så enveten men det ligger i min diagnos tyvärr, oftast har jag faktisk rätt (!;-)) men i detta har jag faktisk fel.
(jepp, jag är himla enkel att leva med :roll:)

Jag vill dock fortfarande fasthålla att det är en oskick att hoppa med "$±x", det ska alltid vara labels, jag kan dock förstå att det kan vara praktisk när man anger kodsnudder som räknas ut på detta sätt. Jag tycker dock att det åligger användaren att införa labels, detta för att man då får tydliggjort för sig att det faktisk är med flit och att man har förstådd det hela.

Då jag förstår på sodjan att delayet inte blir exakt i med annat än 7 cycles mellan vill jag ju även påpeka att den rutin jag gav med uppslagstabellen har fler cycles än 7 men är mindre i kodstorlek när man "byggar ut" den fullt.

Nu förstod jag att det inte är så himla viktigt, det rör sig ju bara om att räkna fram i lagom takt och då spelar ett par steg mer eller mindre ingen större roll.
Skriv svar