(O)lustig bugg i 16F84A-kod

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31440
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

(O)lustig bugg i 16F84A-kod

Inlägg av MadModder »

Har byggt en frekvensräknare, som bygger på den här sidan.
Den fungerar bra, förutom en sak. Vissa värden visas som något annat.

255 visas som 511
511 visas som 767
767 visas som 1023
1023 visas som 1279
1279 visas som 1535
1535 visas som 1791
1791 visas som 2047
2047 visas som 2303 (dock inte alltid)
2303 visas som 2559
2559 visas som 2815
2815 visas som 3071
osv.

Kod: Markera allt

 255:      11111111 
 511:    1 11111111 
 767:   10 11111111 
1023:   11 11111111 
1279:  100 11111111 
1535:  101 11111111 
1791:  110 11111111 
2047:  111 11111111 
2303: 1000 11111111 
2559: 1001 11111111 
2815: 1010 11111111 
3071: 1011 11111111 
Det händer exakt varje gång minsta byten är 255. Det blir då ett för mycket på nästa byte.

Jag använder den här koden.
Inte så vacker, och knapert kommenterad.
Jag kan inte lista ut var detta händer. Kanske i add-rutinen, eller nånstans under count, eller... Är väl i princip första gången jag har med assembler att göra... :P

Hjälp! :pray:
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Åh... vilken kod. Jag fattar inte ens HUR du räknar. Att använda en F84 är dessutom nära nog under spöstraff ;-)

Men allvar: hade du valt en annan PIC med fler timers kunde du ha använd en timer som counter och en annan som timebase, det hade hjälpt avsevärd.

Vad som dock händer är att lägsta byten hinner "flippa över" och det bryts innan MSB uppdateras.

Jag ser att du gör vissa kapitalfel som mycket väl kan vara en del av problemen: du adresserar minneslokationer direkt utan deklarationer! Detta är kanske inte felet här och nu men är likaväl ett allvarligt problem!

Kod: Markera allt

cnvt1	call	sub		;subtract number from count
	incf	19	,f		;increment 1,000,000's register <<== UJ UJ UJ
	movlw	0x3A
	xorwf	19,w
Fler av liknande fel finns längre nere i programmet. Detta FÅR EJ FÖREKOMMA!!!!
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31440
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

Inlägg av MadModder »

Skyll inte på mig. ;)
Koden är från sidan jag länkade till, med vissa modifikationer för att funka på F84A, och sen har jag bara lagt till lite presentationstext i början...
Jag tycker också det är jätterörigt. Databladet säger ingenting om att det ens går att skriva på det där sättet.
Liksom, vad är 19?
v-g
EF Sponsor
Inlägg: 7875
Blev medlem: 25 november 2005, 23:47:53
Ort: Kramforce

Inlägg av v-g »

19 är talet som de kör XOR(exklusivt eller) på. Men man FÅR/bör inte skriva sådär.

Man kan skriva på ett par olika (men mer rätta) sätt. Nr ett är: 0x19 och två: H'19' Detta för att tydligt visa att man vill använda hexadecimala tal. Detta gäller i MPLAB (sök på "Numeric Constants and Radix" så hittar du rätt sida i ASM hjälpen).
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31440
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

Inlägg av MadModder »

Nu har jag ändrat lite. T.ex bytt ut 19 mot en konstant, eller vad man ska kalla det för. Kollade koden som en person gjort om till en 16F628, och lade till banksel och kommenterade bort ett par rader som inte fanns med längre.

ny kod

Men det är fortfaranda samma fel. Det är inte särskilt mycket jag ändrat på, så jag trodde väl inget annat heller.
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Kod: Markera allt

incf   19   ,f      ;increment 1,000,000's register <<== UJ UJ UJ
   movlw   0x3A
   xorwf   19,w 
Madmodder > Liksom, vad är 19?

v-g > 19 är talet som de kör XOR(exklusivt eller) på.

NEJ NEJ NEJ !!

Det är INC*F* och en XORW*F* (*inte* "literal" instruktioner) så "19" är
*ADRESSEN* till registret som innehåller "talet" som ökas resp görs
XOR på !! Det är en jäkla stor skillnad.

Men visst, det är helt korrekt assembler syntax !

Jag såg att du nu har gjort en EQU av "digits" till h'19'.
Sedan används "digits" både i "literal" och i "file" instruktioner
vilket är lite förvillande, men naturligstvis (om det är "by-design")
mycket väl ändå kan vara "rätt"... :-)

Hur som helst, nog om det...

Problemet med att beräkningen alltid går fel när låga byten är
h'FF' är ju ett ganska tydligt tecken.

Jag skulle köra koden i MPSIM och sätta värdet till något med h'FF'
i låga byten, sedan sätta "watch" på lämpliga register, singel steppa
och se var det går snett.

Alternativt, om det är en viss liten snutt som man misstänker, "köra"
koden med papper och penna...

Det borde vara en miss i en "noll-koll", en miss vid hanteringen av
Carry-flaggan eller något liknande.

> med vissa modifikationer för att funka på F84A,

Vad kördes koden på från början ?
v-g
EF Sponsor
Inlägg: 7875
Blev medlem: 25 november 2005, 23:47:53
Ort: Kramforce

Inlägg av v-g »

sodjan:Som vanligt tittade jag för snabbt och blandade samman :oops:
Dock är det inte särskilt snyggt att skriva registren på det där sättet hursom helst.

Lite annat i koden som kanske gör det lättare att förstå är detta:

Kod: Markera allt

   movlw   0x4d		;M
   call	lcd_out
   movlw   0x61		;a
....
Där kan du istället skriva

Kod: Markera allt

   movlw   'M'		;M
   call	lcd_out
   movlw   'a'		;a
....
Kommentarer överflödiga :wink:

Snyggast vore dock om du tittade på sodjanssida hur man "snyggare" lagrar text.
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31440
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

Inlägg av MadModder »

Koden är från början skriven för F84. Ska tydligen vara skillnad på option_reg, trisa mm. Men efter att jag testade originalkoden så gick den också bra. Eller iaf lika dåligt :D

Nu har jag hittat lite mer. Den visar inte alltid fel. Det är främst om den räknat till en högre frekvens precis innan.
Visas en lägre frekvens precis innan kan det stå rätt, ibland.

Felet visas inte när byte nummer två 255. 65535 visas som 65535 ibland och 65791 ibland.

Det där med f W och literal har jag inte satt mig in i riktigt... :oops:
Men literal är väl då man räknar med det värde man skriver där, och det andra vad som finns på den adressen...
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

:-)

Personligen föredrar jag att alltid ange konstanter med rätt radix. T.ex :

a'A'
d'125'
o'177'
h'EC'
b'10010011'

Jag undviker formatet 0xEC eftersom det inte finns motsvarigheter
för de andra radixen i detta format. Att utlämna radix är en
"bug waiting to happen"... :-)

Jag är lite osäker på vad som händer om man bara skriver
movlw 'A', det finns en risk att det tolkas som movlw h'0A'.
Så sett gärna ut radix överallt så blir det inga dolda och
svårhittade buggar...
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Men literal är väl då man räknar med det värde man skriver där, och det andra vad som finns på den adressen...

Korrekt !
De är väldigt tydligt separerade som "file operations" resp "literal operations"
i samanfattningen över instruktioner i databladet för F84A.

> Det är främst om den räknat till en högre frekvens precis innan.

OK. Det låter som om man inte rensar upp eller initierar något register
innan konverteringen görs.
Kan vara något temp regoster som används under konverteringen
eller liknande. Eller att man gör en ADD eller SUB som inkluderar C
flaggen, men inte nollar C innan (om det inte *ska* vara med i beräkningen
alltså). Då blir resultatet beroende på hur C-flaggen sattes innan...
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31440
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

Inlägg av MadModder »

Heh... nudå :D

kod med radix
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Tja, vadå "nudå" ?
Fungerar det bättre ?
Har du hittat buggen ?
Jag tänker inte titta på koden utan att veta vad jag ska titta efter/på....
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31440
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

Inlägg av MadModder »

Nej, ingen skillnad. mpsim går inge vidare. Satte in en stimuli så den skulle ta sig förbi busy-flag-kollen till displayen, men hela skiten kraschade. Tog 10 minuter att stänga ner mplab... :P
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Nu har jag kört det i SIM.
Fixade "Count" så att cnt1,2,3 laddades med d'255'.
Kommenterade bort läsningen av busy från LCDn.

Stegade genom "cnvt", och fick ascii "0000255" i digits.
Så jag är lost, jag vet inte varför du får 511 istället för 255...

En sak som jag dock skulle fixa som är riktigt ful i koden...
Notera OVRFLW och hur den mappas till bit 7 i STATUS som enligt
databladet är "undefined" och som inte ska/bör användas.

Det är inte alls omöjligt att processorn själv ändrar denna bit
utan att man har kontroll över det och ställer till det för koden.

Flytta OVRFLW till ett vanligt register (d.v.s lägg till en variabel med
EQU på en ledig adress) och ändra alla STATUS, OVRFLW till detta register.

Det måste inte vara detta som "spökar", men det bör fixas
i alla fall...

EDIT: Eftersom bit 6 och 7 i STATUS är "undefined", så kan det mycket
väl gå bra i SIM men inte i den riktiga processorn...
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31440
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

Inlägg av MadModder »

Tack för det.
Gjorde en status2 equ 17h
Men det blev tyvärr ingen skillnad.
255 visas alltid som 511, men ju högre talet blir ju oftare visas det rätt. T.ex 10239 visas ganska ofta som 10239, men ibland som 10495. Riktigt skumt är det.
Fattar inte riktigt hur han byggt in hysteres i det hela. När man ökar frekvensen, byts det t.ex från Hz till kHz vid 20kHz, men minskar man frekvensen, byts det från kHz till Hz vid 10kHz.
Kanske har nåt med det att göra, då det oftast visar rätt åt ena hållet så att säga.
Skriv svar