Sida 1 av 1
Skriva till eeprom minne
Postat: 20 februari 2009, 02:14:33
av slatte
PIC16f648A
Hi tech C compiler
Har lite problem med att skria till eeprom minnet.
Kod: Markera allt
EEADR = eeprom_adress;
EEDATA = eeprom_data;
WREN = 1; //aktiverar skrivnigsläge
while (GIE == 1)
{
GIE = 0; //Inaktiverar Interrups
}
EECON2 = 0x55;
EECON2 = 0xAA;
WR = 1; //påbörjar skrivning
while (WR == 1) //kollar om skrivningen är klar
{
}
GIE = 1; //Aktiverar Interrups igen
WREN = 0; //Stänger av skrivnigsläge
EEIF = 0;
Ser ni något fel i denna koden.
kanske måste jag skriva om (eftersom i databladet står det "The write will not initiate if the above sequence is not
followed exactly")
Men jag tycker min C-kod gör samma sak som assembler koden eller?
Kod: Markera allt
EECON2 = 0x55;
EECON2 = 0xAA;
WR = 1; //påbörjar skrivning
while (WR == 1) //kollar om skrivningen är klar
till
Kod: Markera allt
asm("BSF _STATUS, _RP0");
asm("MOVLW 55h");
asm("MOVWF _EECON2");
asm("MOVLW AAh");
asm("MOVWF _EECON2");
asm("BSF _EECON1,WR");
Jag är inte helt säker på att det är i denna rutinen hela programmet hänger sig men jag är ganska säker.
Ni undrar väll varför jag inte provar att sätta in asemblerkoden men det blev en massa kompilerings errorl det var anledningen. Så jag tänkte kolla om inte C-koden som jag har skrivit borde duga!
men skulle varit tacksam om ni kunde hitta något fel i den första koden

Re: Skriva till eeprom minne
Postat: 20 februari 2009, 02:55:51
av TomasL
Kika på resultatet som kompilatorn skapat (dvs asm-koden) jämför sedan med hur det skall vara.
Oftast är det inte bra att skriva sånt här i C, asm är nästan ett måste.
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 06:50:49
av Swech
En annan sak...
Din rutin sätter alltid på GIE igen. Bör du inte istället
spara vad den var och återställa till origirnalvärdet
Alltid tråkigt med rutiner som gör en sak men även något annat som man senare
glömt och har ett h..vete att hittta om det strular...
I detta falll kanske det inte gör något men så gör du något annat projekt och återanvänder
koden och kanske får svårhittat problenm
Swech
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 12:35:09
av slatte
OK verkar som jag måste försöka få in lite assembler kod.
Jag läste i manualen att man var tvungen att använda "_" tecknet innan en variabel
så jag antar att det är rätt ialf. Men får fortfarande kompileringsfel.
Kod: Markera allt
391: asm("BSF _STATUS,_RP0");
392: asm("BSF _EECON1,_WREN");
393: asm("inter_off");
394: asm("BCF _INTCON,_GIE");
395: asm("BTFSC _INTCON,_GIE");
396: asm("GOTO inter_off");
397: asm("MOVLW 055h");
398: asm("MOVWF _EECON2");
399: asm("MOVLW 0AAh");
400: asm("MOVWF _EECON2");
401: asm("BSF _EECON1,_WR");
402: asm("write_fin");
403: asm("BTFSC _EECON1,_WR"); //när bit = 0 skrivning klar
404: asm("GOTO write_fin");
kompileringsfel:
Kod: Markera allt
Copyright (C) 1984-2008 HI-TECH SOFTWARE
Error [842] ; 0. bad bit number
Error [842] ; 0. bad bit number
Error [842] ; 0. bad bit number
Error [842] ; 0. bad bit number
Error [842] ; 0. bad bit number
Error [842] ; 0. bad bit number
Error [842] C:\Projekt\PIC\main.c; 392. bad bit number
Error [842] C:\Projekt\PIC\main.c; 393. bad bit number
Error [842] C:\Projekt\PIC\main.c; 395. bad bit number
Error [842] C:\Projekt\PIC\main.c; 396. bad bit number
Error [842] C:\Projekt\PIC\main.c; 402. bad bit number
Error [842] C:\Projekt\PIC\main.c; 404. bad bit number
********** Build failed! **************
Läser jag i mannualen så står det under error (842)
(842) bad bit number (Assembler, Optimiser)
A bit number must be an absolute expression in the range 0-7.
Och det verkar ju som felet uppstår bara på de rader där det finns kod som bara sätter en bit eller kollar en bit osv.
EDIT: hmm verkar inte som de godkänder bit variabelnamnen.t ex om jag byter ut _WR emot 0x00h så fungerar det.
Får nog lösa det så

Re: Skriva till eeprom minne
Postat: 20 februari 2009, 12:40:58
av vfr
Har du dom värdena för bitnummerna definierade då?
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 12:43:46
av slatte
vfr skrev:Har du dom värdena för bitnummerna definierade då?
kollade precis i pic16f6x.h filen och de verkar vara deklarerade där.
men det kanske inte räcker?
eftersom jag kan använda bitvariablerna i C-koden och de verkar vara godkända där !
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 12:46:26
av slatte
Swech skrev:En annan sak...
Din rutin sätter alltid på GIE igen. Bör du inte istället
spara vad den var och återställa till origirnalvärdet
Alltid tråkigt med rutiner som gör en sak men även något annat som man senare
glömt och har ett h..vete att hittta om det strular...
I detta falll kanske det inte gör något men så gör du något annat projekt och återanvänder
koden och kanske får svårhittat problenm
Swech
Har jag faktiskt inte tänkt på men det ska jag fixa.
Man är säkert lat nästa gång man ska skriva till eepromet och snor funktionen.

danke danke!
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 12:48:37
av Icecap
På de variabler man deklarerar i C-koden måste man ange en underscore framför när man vill använda dom i ASM, alltså ska du INTE göra det när det är "variabler" som "redan finns" i ASM.
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 13:00:53
av slatte
Icecap skrev:På de variabler man deklarerar i C-koden måste man ange en underscore framför när man vill använda dom i ASM, alltså ska du INTE göra det när det är "variabler" som "redan finns" i ASM.
Men om jag istället skriver såhär:
jag antar att dessa inte deklarerade korrekt då heller ?
Kod: Markera allt
Error [800] ; 0. undefined symbol "EECON1"
Error [800] ; 0. undefined symbol "WREN"
Gör jag så så fungerar kompileringen så. Den accepterar _EECON1 osv
Kod: Markera allt
asm("BSF _STATUS,05h");
asm("BSF _EECON1,02h");
asm("inter_off");
asm("BCF _INTCON,07h");
asm("BTFSC _INTCON,07h");
asm("GOTO inter_off");
asm("MOVLW 055h");
asm("MOVWF _EECON2");
asm("MOVLW 0AAh");
asm("MOVWF _EECON2");
asm("BSF _EECON1,01h");
asm("write_fin");
asm("BTFSC _EECON1,01h"); //när bit = 0 skrivning klar
asm("GOTO write_fin");
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 13:10:29
av sodjan
Och du har självklart testat med asm("BSF _EECON1, WREN");, eller hur ??
Hur ser definitionerna ut för EECON1 resp WREN ?
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 19:29:02
av BER
Denna kod har jag skrivit och använt mig av för att skriva till EEPOROM
Kompilator: C18
Krets: p18f2220
Kod: Markera allt
void eewrite(unsigned char address, unsigned char data)
{
unsigned char avbrott;
avbrott = 0;
if ( INTCONbits.GIEH )
avbrott = 1;
PIR2bits.EEIF = 0;
EEADR = address;
EEDATA = data;
EECON1bits.EEPGD = 0; // EEPROM minne väljs
EECON1bits.WREN = 1; // Skrivningsläge aktiveras
INTCONbits.GIEH = 0; // Inaktiverar global avbrottshantering
EECON2 = 0x55; // Låser upp för skrivning
EECON2 = 0xAA;
EECON1bits.WR = 1; // Starta programering
Nop();
while(!PIR2bits.EEIF);
EECON1bits.WREN = 0; // Skrivningsläge deaktiveras
if ( avbrott )
INTCONbits.GIEH = 1; // Aktiverar global avbrottshantering
}
Den fungerar men är inte granskad... kanske ger en hint i alla fall
Edit:
Såg nu efteråt att det skulle användas till en krets i 16-serien så då stämmer nog inte register uppsättningen.
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 20:02:26
av TomasL
Repeterar ånyo, tidskritiska funktioner med intern hårdvara bör inte skrivas i nått annat än assembler.
Orsaken är tämligen enkel, C-kompilatorn kan hitta på "nästan vad som helst".
Dessutom måste du kontrollera erratorna för just den tidsstämplen ditt exemplar av kretsen har.
Ett exempler var de gamla 18Fxxx tex 18F452, där var det ett silikonfel vid just skrivnng av EEPROMet, vilket fick till följd att man fick sätta in lite NOPar här och där för att få det hela fungera, vill minnas att det tog typ en extra instruktion eller så innan flaggor och dyligt ändrade sig.
Men du kan skriva funktionen i C, kontrollera den genererade ASM-koden, jämför den mot den rekommenderade koden.
Posta gärna C-kompilatorns ASM-resultat här.
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 20:51:56
av Icecap
EEPROM-skrivning är INTE en "tidskritisk" operation, det är en sekvenskritisk.
Re: Skriva till eeprom minne
Postat: 20 februari 2009, 21:06:17
av BER
Här kommer resultatet från list filen...
Kod: Markera allt
00089a cfd9 MOVFF 0xfd9,0xfe6 void eewrite(unsigned char address, unsigned char data) D:\pic_code\firmware\main.c
00089c ffe6
00089e cfe1 MOVFF 0xfe1,0xfd9
0008a0 ffd9
0008a2 52e6 MOVF 0xe6,0x1,0x0
{ D:\pic_code\firmware\main.c
unsigned char avbrott; D:\pic_code\firmware\main.c
0008a4 6adf CLRF 0xdf,0x0 avbrott = 0; D:\pic_code\firmware\main.c
0008a6 aef2 BTFSS 0xf2,0x7,0x0 if ( INTCONbits.GIEH ) D:\pic_code\firmware\main.c
0008a8 d002 BRA 0x8ae
0008aa 0e01 MOVLW 0x1 avbrott = 1; D:\pic_code\firmware\main.c
0008ac 6edf MOVWF 0xdf,0x0
0008ae 98a1 BCF 0xa1,0x4,0x0 PIR2bits.EEIF = 0; D:\pic_code\firmware\main.c
0008b0 0efe MOVLW 0xfe EEADR = address; D:\pic_code\firmware\main.c
0008b2 50db MOVF 0xdb,0x0,0x0
0008b4 6ea9 MOVWF 0xa9,0x0
0008b6 0efd MOVLW 0xfd EEDATA = data; D:\pic_code\firmware\main.c
0008b8 50db MOVF 0xdb,0x0,0x0
0008ba 6ea8 MOVWF 0xa8,0x0
0008bc 9ea6 BCF 0xa6,0x7,0x0 EECON1bits.EEPGD = 0; // EEPROM minne väljs D:\pic_code\firmware\main.c
0008be 84a6 BSF 0xa6,0x2,0x0 EECON1bits.WREN = 1; // Skrivningsläge aktiveras D:\pic_code\firmware\main.c
0008c0 9ef2 BCF 0xf2,0x7,0x0 INTCONbits.GIEH = 0; // Inaktiverar global avbrottshantering D:\pic_code\firmware\main.c
0008c2 0e55 MOVLW 0x55 EECON2 = 0x55; // Låser upp för skrivning D:\pic_code\firmware\main.c
0008c4 6ea7 MOVWF 0xa7,0x0
0008c6 0eaa MOVLW 0xaa EECON2 = 0xAA; D:\pic_code\firmware\main.c
0008c8 6ea7 MOVWF 0xa7,0x0
0008ca 82a6 BSF 0xa6,0x1,0x0 EECON1bits.WR = 1; // Starta programering D:\pic_code\firmware\main.c
0008cc 0000 NOP Nop(); D:\pic_code\firmware\main.c
0008ce a8a1 BTFSS 0xa1,0x4,0x0 while(!PIR2bits.EEIF); D:\pic_code\firmware\main.c
0008d0 d7fe BRA 0x8ce
0008d2 94a6 BCF 0xa6,0x2,0x0 EECON1bits.WREN = 0; // Skrivningsläge deaktiveras D:\pic_code\firmware\main.c
0008d4 50df MOVF 0xdf,0x0,0x0 if ( avbrott ) D:\pic_code\firmware\main.c
0008d6 e001 BZ 0x8da
0008d8 8ef2 BSF 0xf2,0x7,0x0 INTCONbits.GIEH = 1; // Aktiverar global avbrottshantering D:\pic_code\firmware\main.c
0008da 52e5 MOVF 0xe5,0x1,0x0 } D:\pic_code\firmware\main.c
0008dc 52e5 MOVF 0xe5,0x1,0x0
0008de cfe7 MOVFF 0xfe7,0xfd9
0008e0 ffd9
0008e2 0012 RETURN 0x0
[/size]