Skriva till eeprom minne

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Skriva till eeprom minne

Inlägg 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 :-)
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 47013
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Skriva till eeprom minne

Inlägg 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.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Skriva till eeprom minne

Inlägg 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
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Re: Skriva till eeprom minne

Inlägg 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å :-)
Senast redigerad av slatte 20 februari 2009, 12:41:32, redigerad totalt 1 gång.
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Re: Skriva till eeprom minne

Inlägg av vfr »

Har du dom värdena för bitnummerna definierade då?
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Re: Skriva till eeprom minne

Inlägg 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 !
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Re: Skriva till eeprom minne

Inlägg 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!
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Skriva till eeprom minne

Inlägg 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.
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Re: Skriva till eeprom minne

Inlägg 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

     asm("BSF         EECON1,WREN");

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");
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Skriva till eeprom minne

Inlägg av sodjan »

Och du har självklart testat med asm("BSF _EECON1, WREN");, eller hur ??

Hur ser definitionerna ut för EECON1 resp WREN ?
Användarvisningsbild
BER
Inlägg: 399
Blev medlem: 9 mars 2005, 00:02:10
Ort: Östergötland

Re: Skriva till eeprom minne

Inlägg 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.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 47013
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Skriva till eeprom minne

Inlägg 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.
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Skriva till eeprom minne

Inlägg av Icecap »

EEPROM-skrivning är INTE en "tidskritisk" operation, det är en sekvenskritisk.
Användarvisningsbild
BER
Inlägg: 399
Blev medlem: 9 mars 2005, 00:02:10
Ort: Östergötland

Re: Skriva till eeprom minne

Inlägg 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]
Skriv svar