Hej!
jag har ett liknande problem liknande tråden "Problem med PCL och PCLATH (16F767)"
Det hela gäller en liten kodsnutt för att läsa ut serienummer ur flashminnet.
Koden fungerar alldeles utmärkt för pic16f628. Den processorn har en mindre missenarea så jag misstänker att det är PCLATH som spökar till det för 16f648A processorn.
Koden är skriven i C för "bengt knudsen" kompilatorn och ser ut enligt följande:
#pragma cdata[4094] = 0x3444 // RETLV 0x44 på address 0xFFE;
#pragma cdata[4095] = 0x3455 // RETLV 0x55 på adress =0xFFF;
#define SERIAL_START_ADDR 0x0FFE
uns16 SERIAL_NUMBER;
page3 void vGetSerialNumber(void)
{
char temp;
char tempL;
tempL = PCLATH;
PCLATH = 0x08;
#asm
dw (SERIAL_START_ADDR + 0x2000) // CALL 0xFFE:
movwf temp
#endasm
SERIAL_NUMBER.low8 = temp;
PCLATH = 0x08;
#asm
dw ((SERIAL_START_ADDR+1)+0x2000) // CALL 0xFFF
movwf temp
#endasm
SERIAL_NUMBER.high8 = temp;
PCLATH = tempL;
}
void main (void)
{
vGetSerialNumber();
}
Koden skriven ovan fungerar i MPLab simulatorn, men inte på processorn.
Det finns fler rader i main funktionen egentligen, men det spelar egentligen ingen ströre roll för detta problemet, misstänker jag.
Om man försöker köra koden så hänger sig processorn i någon from av konstig loop.
Jag har läst både databladet för 16f648A och AN556 för att förstå vad som kan vara problemet, men lyckas inte lösa det.
Finns det någon som skulle kunna hjälpa mig?
// Mvh Daniel Grafström
CALL problem (pic16f648A)
Alltså, vid CALL's som går över en 2 Kord gräns (uppåt eller neråt)
så måste PCLATH först sättsas så att den "pekar" på rätt page, d.v.s den
där rutinern som ska CALL'as ligger.
Just exakt detta är en av de få fördelarna med HLL's, att kompilatorn själv
tar hand om PCLATH.
Att själv dribbla med PCLATH samtidigt som man inte vet vad kompilatorn
gör själv, kan nog få en hel del intressanta resultat.
Jag utgår från att den använda kompilatorn har fullt stöd för den använda processorn, eller hur !?
Dessutom, om koden ovan är hela programmet, så blir det inte mycket asm kod
att kolla. Det borde gå snabbt att se vad som går snett.
så måste PCLATH först sättsas så att den "pekar" på rätt page, d.v.s den
där rutinern som ska CALL'as ligger.
Just exakt detta är en av de få fördelarna med HLL's, att kompilatorn själv
tar hand om PCLATH.
Att själv dribbla med PCLATH samtidigt som man inte vet vad kompilatorn
gör själv, kan nog få en hel del intressanta resultat.
Jag utgår från att den använda kompilatorn har fullt stöd för den använda processorn, eller hur !?
Dessutom, om koden ovan är hela programmet, så blir det inte mycket asm kod
att kolla. Det borde gå snabbt att se vad som går snett.
Kompilatorn har fullt stöd för den pic-kretsen vad jag förstått eftersom den är till för just pic16 kretsar och finns med i listan över processorer som den stöder.
det finns tyvär mer kod i processorn, det var därför en processor med större minne används eftersom det är över 2K.
Jag vet ju att jag kör mitt call till den näst sissta och sissta adressen i minnet.
enligt AN556 så ligger bitarna 10-0 i OP koden för CALL rutinen och bit 12-11 som bit 5 och 4 i PCLATH registret.
och där löste jag mitt eget problem!!
#define SERIAL_START_ADDR 0x0FFE
Är faktiskt 12 bitar lång, alltså en bit för mycket för CALL rutinen, o därför skiter det sig.
Tack för diskussionen, den var givande!
/Daniel
det finns tyvär mer kod i processorn, det var därför en processor med större minne används eftersom det är över 2K.
Jag vet ju att jag kör mitt call till den näst sissta och sissta adressen i minnet.
enligt AN556 så ligger bitarna 10-0 i OP koden för CALL rutinen och bit 12-11 som bit 5 och 4 i PCLATH registret.
och där löste jag mitt eget problem!!
#define SERIAL_START_ADDR 0x0FFE
Är faktiskt 12 bitar lång, alltså en bit för mycket för CALL rutinen, o därför skiter det sig.
Tack för diskussionen, den var givande!
/Daniel
ja, jag säger serienummer eftersom varje enhet skall ha ett eget nummer.
anledningen att jag lagt det som ett #pragma för tillfället är att jag inte orkar hålla på o klydda med serienummer filer när jag testar programvaran. Och om det inte ligger ett RETLW kommando på rätt adress, så kommer programvaran inte komma längre än till att läsa in serienummret innnan den startar om igen.
Eller var det nått annat du funderade på?
anledningen att jag lagt det som ett #pragma för tillfället är att jag inte orkar hålla på o klydda med serienummer filer när jag testar programvaran. Och om det inte ligger ett RETLW kommando på rätt adress, så kommer programvaran inte komma längre än till att läsa in serienummret innnan den startar om igen.
Eller var det nått annat du funderade på?
Nej, inget speciellt.
Frågan om att serienumrera processorer (eller igentligen oftare de
produkter de sitter i), är ett vanligt problem. En del dyrare programmerare
har inbyggda funktioner för det. En del bygger upp en miljö då man
"bygger" HEX filen inför varje programmeringen och har ett script av något
slag som genererar själva numren. Det var mer hur du tänkt lösa det
som jag var nyfiken på...
Sen är det ju så, naturligtsvis, att kompilatorn har lite svårt att
hantera PCLATH när man gör CALL'er själv från inline asm...
Så jag backer på den punkten...
Frågan om att serienumrera processorer (eller igentligen oftare de
produkter de sitter i), är ett vanligt problem. En del dyrare programmerare
har inbyggda funktioner för det. En del bygger upp en miljö då man
"bygger" HEX filen inför varje programmeringen och har ett script av något
slag som genererar själva numren. Det var mer hur du tänkt lösa det
som jag var nyfiken på...
Sen är det ju så, naturligtsvis, att kompilatorn har lite svårt att
hantera PCLATH när man gör CALL'er själv från inline asm...
Så jag backer på den punkten...
