Hmm... fösökt tyda koden innan du dumförklara folk?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..
Hjälp med kod 16F84 (nybörjare)
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
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
; }
; }
;}
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:
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:
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?
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!!!
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
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
Det finns många sätt att skriva en delay loop men ditt sätt är klart sämmre...
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...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
Det finns många sätt att skriva en delay loop men ditt sätt är klart sämmre...
Ö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.
"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.
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
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
Har du kört koden i MPLAB? iså fall hade du sett att Timer1,Timer2 och Timer3 ändras...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.
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
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.
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.
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...
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...
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
)
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.
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

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.