/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
EEPROM skrivning og læsning
Fra : Kenneth Huus


Dato : 20-12-04 08:48

Yo NG.

Jeg har siddet og rodet i lang tid nu med mit program, og forsøger stadig at
gemme og læse fra Eeprom'en. Når jeg prøver at compilere mit program, giver
MPLAB mig denne fejlmeddellelse. Programkoden er copy / paste fra
PIC16f873-manualen.

Building FINAL.HEX...

Compiling FINAL.C:
Command line: "C:\HT-PIC\BIN\PICC.EXE -E -16F873 -IC:\HT-PIC\INCLUDE -lF
P:\MYDOCU~1\DOKUME~1\FLOWML~1\PICPRO~1\NEWCOM\FINAL.C"
Enter PICC -HELP for help
p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 456: undefined
identifier: BSF (error)
p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 456: expression
syntax (error)
p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 465: ; expected
(error)
p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 474: undefined
identifier: BSF (error)
p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 474: expression
syntax (error)
p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 477: illegal
character (044) (error)
p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 498: ; expected
(error)

MPLAB is unable to find output file "FINAL.HEX". This may be due to a
compile, assemble, or link process failure.

Build failed.


/*----------------------------------READ-routine----------------------------
------*/
/* Her beskrives hvordan man læser data i EEprom */
/*--------------------------------------------------------------------------
------*/
void read(void) // Read-routine
{
BSF STATUS, RP1
BCF STATUS, RP0 //Bank 2
MOVF ADDR, W //Write address
MOVWF EEADR //to read from
BSF STATUS, RP0 //Bank 3
BCF EECON1, EEPGD //Point to Data
BSF EECON1, RD //Start read operation
BCF STATUS, RP0 //Bank 2
MOVF EEDATA, W //W = EEDATA
}



/*----------------------------------WRITE-routine---------------------------
------*/
/* Her beskrives hvordan man skriver data i EEprom */
/*--------------------------------------------------------------------------
------*/
void write(void) // Write-routine
{
BSF STATUS, RP1
BSF STATUS, RP0 //Bank 3
BTFSC EECON1, WR //Wait for
GOTO $-1 //write to finish
BCF STATUS, RP0 //Bank 2
MOVF ADDR, W //Address to
MOVWF EEADR //write to
MOVF VALUE, W //Data to
MOVWF EEDATA //write
BSF STATUS, RP0 //Bank 3
BCF EECON1, EEPGD //Point to Data memory
BSF EECON1, WREN //Enable writes
//Only disable interrupts
BCF INTCON, GIE //if already enabled,
//otherwise discard
MOVLW 0x55 //Write 55h to
MOVWF EECON2 //EECON2
MOVLW 0xAA //Write AAh to
MOVWF EECON2 //EECON2
BSF EECON1, WR //Start write operation
//Only enable interrupts
BSF INTCON, GIE //if using interrupts,
//otherwise discard
BCF EECON1, WREN //Disable writes
}



 
 
Troels Thomsen (20-12-2004)
Kommentar
Fra : Troels Thomsen


Dato : 20-12-04 10:03

> p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 456: undefined
> identifier: BSF (error)

På en måde er svaret jo givet:
undefined identifier: BSF
altså den kan ikke finde ud af hvad BSF er for noget.

Nok har du taget eksemplet fra et datablad, men det er vel ikke sikkert at
din compiler bruger samme syntax for inline assembler som den i databladet
benyttede.

Ofte skriver man _asm foran hver linie, eller asm { bla bla }

Prøv at se om du et sted under din compiler installation kan finde et c
eksempel hvori der benyttes inline assembler. Måske findes også compiler
switche / project settings a'la "enable inline assembler"

tpt



Kenneth Huus (20-12-2004)
Kommentar
Fra : Kenneth Huus


Dato : 20-12-04 11:20


"Troels Thomsen" <troels.thomsen@mailteledk> wrote in message
news:41c6957e$0$233$edfadb0f@dread11.news.tele.dk...
> > p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 456: undefined
> > identifier: BSF (error)
>
> På en måde er svaret jo givet:
> undefined identifier: BSF
> altså den kan ikke finde ud af hvad BSF er for noget.
>
> Nok har du taget eksemplet fra et datablad, men det er vel ikke sikkert at
> din compiler bruger samme syntax for inline assembler som den i databladet
> benyttede.
>
> Ofte skriver man _asm foran hver linie, eller asm { bla bla }
>
> Prøv at se om du et sted under din compiler installation kan finde et c
> eksempel hvori der benyttes inline assembler. Måske findes også compiler
> switche / project settings a'la "enable inline assembler"
>
> tpt
>
>


Hej Troels.

Jeg må være dig svar skyldig, men jeg har altså i min source tekst #asm
skrevet. Vedlægger lige dokumentation herunder, fra et tidsligere eksempel
jeg har leget med.
Jeg kunne godt regne mig frem til, at det var BSF der var galt med, men jeg
kunne ikke se HVAD der var galt. Undrer mig bare, at alle de andre
#asm-commands er understøttet af HIGHTECH-compileren.

/*----------------------------------READ-routine----------------------------
------*/
/* Her beskrives hvordan man læser data i EEprom */
/*--------------------------------------------------------------------------
------*/
void read(void) // Read-routine
{
#asm
ReadEEbyte // Læser fra adresse i eepromaddr register
movf eepromaddr, w
bsf STATUS, RP1 // Bank 2
bcf STATUS, RP0
movwf EEADR
clrf EEADRH
bsf STATUS, RP0 // RAM-BANK3
movlw b'00000000' // Sæt op til Data memory
movwf EECON1
bsf EECON1, RD
bcf STATUS, RP0 // RAM-BANK2
bcf STATUS, RP0 // Bank2 igen
movf EEDATA, w
bcf STATUS, RP1
movwf eepromvalue // Her ligger den læste byte
return
#endasm
}



Uncle (20-12-2004)
Kommentar
Fra : Uncle


Dato : 20-12-04 19:45


"Kenneth Huus" <bashuus@tiscali.dk> skrev i en meddelelse
news:41c683a6$0$33649$edfadb0f@dread16.news.tele.dk...
> Yo NG.
>
> Jeg har siddet og rodet i lang tid nu med mit program, og forsøger stadig
at
> gemme og læse fra Eeprom'en. Når jeg prøver at compilere mit program,
giver
> MPLAB mig denne fejlmeddellelse. Programkoden er copy / paste fra
> PIC16f873-manualen.
>
> Building FINAL.HEX...
>
> Compiling FINAL.C:
> Command line: "C:\HT-PIC\BIN\PICC.EXE -E -16F873 -IC:\HT-PIC\INCLUDE -lF
> P:\MYDOCU~1\DOKUME~1\FLOWML~1\PICPRO~1\NEWCOM\FINAL.C"
> Enter PICC -HELP for help
> p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 456: undefined
> identifier: BSF (error)
> p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 456: expression
> syntax (error)
> p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 465: ; expected
> (error)
> p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 474: undefined
> identifier: BSF (error)
> p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 474: expression
> syntax (error)
> p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 477: illegal
> character (044) (error)
> p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: 498: ; expected
> (error)
>
> MPLAB is unable to find output file "FINAL.HEX". This may be due to a
> compile, assemble, or link process failure.
>
> Build failed.
>
>
>
/*----------------------------------READ-routine----------------------------
> ------*/
> /* Her beskrives hvordan man læser data i EEprom */
>
/*--------------------------------------------------------------------------
> ------*/
> void read(void) // Read-routine
> {
> BSF STATUS, RP1
> BCF STATUS, RP0 //Bank 2
> MOVF ADDR, W //Write address
> MOVWF EEADR //to read from
> BSF STATUS, RP0 //Bank 3
> BCF EECON1, EEPGD //Point to Data
> BSF EECON1, RD //Start read operation
> BCF STATUS, RP0 //Bank 2
> MOVF EEDATA, W //W = EEDATA
> }
>
>
>
>
/*----------------------------------WRITE-routine---------------------------
> ------*/
> /* Her beskrives hvordan man skriver data i EEprom */
>
/*--------------------------------------------------------------------------
> ------*/
> void write(void) // Write-routine
> {
> BSF STATUS, RP1
> BSF STATUS, RP0 //Bank 3
> BTFSC EECON1, WR //Wait for
> GOTO $-1 //write to finish
> BCF STATUS, RP0 //Bank 2
> MOVF ADDR, W //Address to
> MOVWF EEADR //write to
> MOVF VALUE, W //Data to
> MOVWF EEDATA //write
> BSF STATUS, RP0 //Bank 3
> BCF EECON1, EEPGD //Point to Data memory
> BSF EECON1, WREN //Enable writes
> //Only disable interrupts
> BCF INTCON, GIE //if already enabled,
> //otherwise discard
> MOVLW 0x55 //Write 55h to
> MOVWF EECON2 //EECON2
> MOVLW 0xAA //Write AAh to
> MOVWF EECON2 //EECON2
> BSF EECON1, WR //Start write operation
> //Only enable interrupts
> BSF INTCON, GIE //if using interrupts,
> //otherwise discard
> BCF EECON1, WREN //Disable writes
> }

Hej

Prøv med disse funktioner istedet.....:

Læse : variabel = eeprom_read(x); x = eepromadresse

Skrive : eeprom_write(x,y); x = eepromadresse, y = data
do{}while(WR= = 1);

De virker på PIC16F876/877, så mon ikke de også vil på en 873.
Jeg har også her brugt MPLAB med HI-TECH compiler..

Jule hilsen
Jens



Ove Kjeldgaard (20-12-2004)
Kommentar
Fra : Ove Kjeldgaard


Dato : 20-12-04 21:00

"Kenneth Huus" <bashuus@tiscali.dk> wrote:

>Yo NG.
>
>Jeg har siddet og rodet i lang tid nu med mit program, og forsøger stadig at
>gemme og læse fra Eeprom'en. Når jeg prøver at compilere mit program, giver
>MPLAB mig denne fejlmeddellelse. Programkoden er copy / paste fra
>PIC16f873-manualen.
>
>Building FINAL.HEX...
>
>>> klip <<<

Det er ikke nødvendig at bruge assembler til at læse/skrive EEPrommen på
PIC16F8xx processoren.

Her er den C kode jeg bruger i forbindelse med HiTech kompileren:


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

uchar ReadParam( uchar Index )
{
   EEPGD = 0; // Point to EE memory

   EEADR = Index;
   RD = 1;
   return( EEDATA );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

void WriteParam( uchar Index, uchar Data )
{
   EEPGD = 0;      // Point to EE memory
   WREN = 1;

   EEADR = Index;

   RD = 1;
   if( EEDATA != Data )   // Er der brug for skrive til EEProm?
   {
      EEDATA = Data;

      GIE = 0;   // Disable all interrupts
      EECON2 = 0x55;
      EECON2 = 0xAA;
      WR = 1;
      GIE = 1;   // Enable all interrupts

      while( WR );
   }

   WREN = 0;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //


Jeg bruger altid at teste om de data der skal skrives til EEPrommen er
forskellig fra de data der ligger i forvejen på pladsen.
Det en beskeden ekstra tid testen tager, og hvis der ikke skal skrives sparer
man masser af tid og "slid" på EEPrommen.

Der er så vidt jeg kan se ikke nogle af mine eksterne #define med i disse to
procedurer.


--
Med venlig hilsen, Ove Kjeldgaard, nospam AT privat DOT dk
Natur og Friluftsliv: <http://hiker.dk>

Kenneth Huus (22-12-2004)
Kommentar
Fra : Kenneth Huus


Dato : 22-12-04 07:03


"Ove Kjeldgaard" <ReadMyEmail@The.Signature> wrote in message
news:l2bes05s99tih0cvkv6r0mpqvmbn6genfk@4ax.com...
> "Kenneth Huus" <bashuus@tiscali.dk> wrote:
>
> >Yo NG.
> >
> >Jeg har siddet og rodet i lang tid nu med mit program, og forsøger stadig
at
> >gemme og læse fra Eeprom'en. Når jeg prøver at compilere mit program,
giver
> >MPLAB mig denne fejlmeddellelse. Programkoden er copy / paste fra
> >PIC16f873-manualen.
> >
> >Building FINAL.HEX...
> >
> >>> klip <<<
>
> Det er ikke nødvendig at bruge assembler til at læse/skrive EEPrommen på
> PIC16F8xx processoren.
>
> Her er den C kode jeg bruger i forbindelse med HiTech kompileren:
>
>
>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
>
> uchar ReadParam( uchar Index )
> {
> EEPGD = 0; // Point to EE memory
>
> EEADR = Index;
> RD = 1;
> return( EEDATA );
> }
>
>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
>
> void WriteParam( uchar Index, uchar Data )
> {
> EEPGD = 0; // Point to EE memory
> WREN = 1;
>
> EEADR = Index;
>
> RD = 1;
> if( EEDATA != Data ) // Er der brug for skrive til EEProm?
> {
> EEDATA = Data;
>
> GIE = 0; // Disable all interrupts
> EECON2 = 0x55;
> EECON2 = 0xAA;
> WR = 1;
> GIE = 1; // Enable all interrupts
>
> while( WR );
> }
>
> WREN = 0;
> }
>
>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
>
>
> Jeg bruger altid at teste om de data der skal skrives til EEPrommen er
> forskellig fra de data der ligger i forvejen på pladsen.
> Det en beskeden ekstra tid testen tager, og hvis der ikke skal skrives
sparer
> man masser af tid og "slid" på EEPrommen.
>
> Der er så vidt jeg kan se ikke nogle af mine eksterne #define med i disse
to
> procedurer.
>
>
> --
> Med venlig hilsen, Ove Kjeldgaard, nospam AT privat DOT dk
> Natur og Friluftsliv: <http://hiker.dk>

Tak for dit svar - Nå, jeg troede kun det var muligt i Assambler, men det er
jeg da så glad for at du nu ikke er helt enig i.
Jeg vil lige efterprøve dit eksempel med det samme. Nu ser jeg du definerer
uchar data - Tror du det vil give anledning til noget hø, når jeg skal gemme
en double ?? Sagen er den, at det tal jeg skal gemme er incl. titalsdecimal
!!

mvh
Kenneth Huus



Ove Kjeldgaard (22-12-2004)
Kommentar
Fra : Ove Kjeldgaard


Dato : 22-12-04 21:42

"Kenneth Huus" <bashuus@tiscali.dk> wrote:

>Tak for dit svar - Nå, jeg troede kun det var muligt i Assambler, men det er
>jeg da så glad for at du nu ikke er helt enig i.
>Jeg vil lige efterprøve dit eksempel med det samme. Nu ser jeg du definerer
>uchar data - Tror du det vil give anledning til noget hø, når jeg skal gemme
>en double ?? Sagen er den, at det tal jeg skal gemme er incl. titalsdecimal
>!!

Hej Kenneth

Jeg er efterhånden temmelig glad for den kode HiTech's PIC-C laver.
Der er selvfølgelig nogle få ting der driller af og til, men det er vist kun NOP
og CLRWDT at jeg bruger i assembler.

Grunden til at jeg viste en enkeltbyte version, var at du startede tråden med en
uchar
For faktisk har jeg de fleste programmer fat i 16 bits data til og fra
EEPrommen.

Og så ser procedurene sådan ud:

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

sint ReadParam( uchar Index )
{
   sint ScrReturn;

   EEPGD = 0;      // Point to EE memory

   EEADR = Index * 2;   // Udregn start adressen
   RD = 1;
   LO( ScrReturn ) = EEDATA;

   EEADR++;
   RD = 1;
   HI( ScrReturn ) = EEDATA;

   return( ScrReturn );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

void WriteParam( uchar Index, sint Data )
{
   EEPGD = 0;      // Point to EE memory
   WREN = 1;

   EEADR = Index * 2;   // Udregn start adressen

   RD = 1;
   if( EEDATA != LO( Data ))
   {
      EEDATA = LO( Data );

      GIE = 0;   // Disable all interrupts
      EECON2 = 0x55;
      EECON2 = 0xAA;
      WR = 1;
      GIE = 1;   // Enable all interrupts

      WdtFlag   = TRUE;
      while( WR );
   }

   EEADR++;

   RD = 1;
   if( EEDATA != HI( Data ))
   {
      EEDATA = HI( Data );

      GIE = 0;   // Disable all interrupts
      EECON2 = 0x55;
      EECON2 = 0xAA;
      WR = 1;
      GIE = 1;   // Enable all interrupts

      WdtFlag   = TRUE;
      while( WR );
   }

   WREN = 0;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

Men i disse programstumper har jeg fat i nogle af mine uundværlige macroer.

Først er der nogle korte navne til signed/unsigned datatyper:

#define schar signed char
#define uint unsigned int
#define sint signed int
#define ulong unsigned long
#define slong signed long

Dernæst nogle macroer til at få fat i de enkelte bytes i 16 bit data:

#define LO(x) *(((uchar*)(&(x)))+0)
#define HI(x) *(((uchar*)(&(x)))+1)

Som du kan se i læse/skrive rutinerne, så virker disse to macroer på begge sider
af lighedstegnet. Og de kompilerer til simple enkelt bytes flytninger af data
(to instruktiner hvis der ikke skal foretages sideskift)

Og der er ingen problemer med 24 og 32 bits data, for måden at få fat i de
enkelte bytes kan udvides som her:

#define LONG0(x) *(((uchar*)(&(x)))+0)
#define LONG1(x) *(((uchar*)(&(x)))+1)
#define LONG2(x) *(((uchar*)(&(x)))+2)
#define LONG3(x) *(((uchar*)(&(x)))+3)

LONG0 og LONG1 er identiske med LO og HI, men for mig giver det lidt nemmere
læst kode, hvis jeg adskiller 16 bits versioner fra de længere datatyper.


--
Med venlig hilsen, Ove Kjeldgaard, nospam AT privat DOT dk
Natur og Friluftsliv: <http://hiker.dk>

Kenneth Huus (23-12-2004)
Kommentar
Fra : Kenneth Huus


Dato : 23-12-04 11:24

Når jeg følger dit eksempel, og prøver at rette det til, så det passer til
mit software, kommer den med følgende meddellelse. Tilsyneladende kan den
ikke kende kommandoen wdtflag.


Building FINAL.HEX...

Compiling FINAL.C:
Command line: "C:\HT-PIC\BIN\PICC.EXE -16F873 -IC:\HT-PIC\INCLUDE -lF
P:\MYDOCU~1\DOKUME~1\FLOWML~1\PICPRO~1\NEWCOM\FINAL.C"
Enter PICC -HELP for help
p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: write()
429: WdtFlag = TRUE;
^ undefined identifier: WdtFlag
^ undefined identifier: TRUE
446: WdtFlag = TRUE;
^ undefined identifier: WdtFlag
^ undefined identifier: TRUE
p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: main()
496: read();
^ too few arguments
520: write();
^ too few arguments
Exit status = 1

MPLAB is unable to find output file "FINAL.HEX". This may be due to a
compile, assemble, or link process failure.

Build failed.



Ove Kjeldgaard (23-12-2004)
Kommentar
Fra : Ove Kjeldgaard


Dato : 23-12-04 17:57

"Kenneth Huus" <bashuus@tiscali.dk> wrote:

>Når jeg følger dit eksempel, og prøver at rette det til, så det passer til
>mit software, kommer den med følgende meddellelse. Tilsyneladende kan den
>ikke kende kommandoen wdtflag.
>
>
>Building FINAL.HEX...
>
>Compiling FINAL.C:
>Command line: "C:\HT-PIC\BIN\PICC.EXE -16F873 -IC:\HT-PIC\INCLUDE -lF
>P:\MYDOCU~1\DOKUME~1\FLOWML~1\PICPRO~1\NEWCOM\FINAL.C"
>Enter PICC -HELP for help
>p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: write()
> 429: WdtFlag = TRUE;
> ^ undefined identifier: WdtFlag
> ^ undefined identifier: TRUE
> 446: WdtFlag = TRUE;
> ^ undefined identifier: WdtFlag
> ^ undefined identifier: TRUE
>p:\mydocu~1\dokume~1\flowml~1\picpro~1\newcom\final.c: main()
> 496: read();
> ^ too few arguments
> 520: write();
> ^ too few arguments
>Exit status = 1
>
>MPLAB is unable to find output file "FINAL.HEX". This may be due to a
>compile, assemble, or link process failure.
>
>Build failed.
>

Linie 429 og 446 fejlene er mig der ikke fik slettet disse linier (WdtFlag en en
global BIT variabel).

Hvad du har af fejl i main() linie 496 og 520 kan jeg først give et bud på hvis
du poster lidt af den omliggende kode, evt. hele main() hvis den ikke er for
stor.


--
Med venlig hilsen, Ove Kjeldgaard, nospam AT privat DOT dk
Natur og Friluftsliv: <http://hiker.dk>

Kenneth Huus (24-12-2004)
Kommentar
Fra : Kenneth Huus


Dato : 24-12-04 10:24



> Linie 429 og 446 fejlene er mig der ikke fik slettet disse linier (WdtFlag
> en en
> global BIT variabel).
>
> Hvad du har af fejl i main() linie 496 og 520 kan jeg først give et bud på
> hvis
> du poster lidt af den omliggende kode, evt. hele main() hvis den ikke er
> for
> stor.
>
>
> --
> Med venlig hilsen, Ove Kjeldgaard, nospam AT privat DOT dk
> Natur og Friluftsliv: <http://hiker.dk>

OK, det skal du få, men det kan først blive efter nytår, da jeg er gået på
ferie nu.

Glædelig jul og godt nytår herfra !!
mvh
Kenneth Huus



Kenneth Huus (03-01-2005)
Kommentar
Fra : Kenneth Huus


Dato : 03-01-05 07:43

> Linie 429 og 446 fejlene er mig der ikke fik slettet disse linier (WdtFlag
en en
> global BIT variabel).
>
> Hvad du har af fejl i main() linie 496 og 520 kan jeg først give et bud på
hvis
> du poster lidt af den omliggende kode, evt. hele main() hvis den ikke er
for
> stor.
>
>
> --
> Med venlig hilsen, Ove Kjeldgaard, nospam AT privat DOT dk
> Natur og Friluftsliv: <http://hiker.dk>


Jeg kan sgu ikke lige greje, hvad der er galt, så her får du hele softwaren
!! Det jeg stadig ikke lige helt ved, hvordan jeg skal opsætte, er hvorhenne
ejg skal definere, at programmet skal "READ'e" EPROM'ens value, når den går
fra SLEEP til WAKE UP !! Håber du har nogle flere fifs !!

#include <pic.h>
#include <string.h>
#include <stdio.h>
#include "c:\ht-pic\samples\delay.c"
#define schar signed char
#define uint unsigned int
#define sint signed int
#define ulong unsigned long
#define slong signed long
#define LO(x) *(((uchar*)(&(x)))+0)
#define HI(x) *(((uchar*)(&(x)))+1)

bank1 unsigned char text [40]; // Array til tekst på display
double forbrug; // Variabel til forbrug til LCD-udlæsning
// double pga titalsdecimal
int bitsum; // Variabel til bitsum
int in_high, in_low; // Variabel til in_high og in_low
int e, i, q, y; // Variabel til DELAY, lcd, lcdDELAY og
// interval
char flag, status; // Variabel til Flag og status
// initialisering af display og LED
int count_d, count_up; // Variabel til countdown og countup
int a, b; // Variabel til input fra flowmåleren
int start;
void interval(); // Variabel til interval-routinen


void LCDdelay(void) // Delayroutine
{
for (q=0; q<75; q++); // "For"-løkken initialiseres med 0, og gennemløbes
// 75 gange, før løkken afsluttes
}



void DELAY(void) // Delayroutine
{
for (e=0; e<32767; e++); // "For"-løkken initialiseres med 0, og
gennemløbes
// 732767 gange, før løkken afsluttes
}



void lcd(void) // LCD-routine
{
for (i=0; i<strlen(text); i++) // For-løkken initialiseres med 0 som start
// og optælling til længden af strengen
{
PORTB = text[i];
PORTA = 3;
PORTA = 0;
}

for (i=0; i<80-strlen(text); i++) // For-løkken init
{
PORTB = 32; // Fill rest with space
PORTA = 3;
PORTA = 0;
}
}



void input() // Inputroutine
{
a=TMR0; // Værdien af timer0 lægges i a
TMR0=0; // Timer0 resettes

if (a>0) // Tjeck om a > 0
{
if (a<690) // Tjeck om a > 690
{
bitsum=bitsum+a; // Forøg bitsum med indholdet af a

if (bitsum>690) // Tjeck om bitsum > 690
{
bitsum=bitsum-690; // Subtraher 690 fra bitsum
forbrug=forbrug+0.1; // Forøg forbrug med 0.1
} while (bitsum>690); // Kør sløjfen igennem, hvis bitsum > 690
}

if (a==690) // Tjeck om a = 690
{
forbrug=forbrug+0.1; // Forøg forbrug med 0.1
bitsum=0; // Reset bitsum
}

if (a>690) // Tjeck om a > 690
{
do
{
b=a-690; // A subtraheres 690
forbrug=forbrug+0.1; // Forøg forbrug med 0.1
} while (b>690); // Kør sløjfen igennem, så længe b > 690

bitsum=bitsum+b; // Bitsum summeres med indholdet af b

if (bitsum>690) // Tjeck om bitsum > 690
{
bitsum=bitsum-690; // Subtraher 690 fra bitsum
forbrug=forbrug+0.1; // Forøg forbrug med 0.1
} while (bitsum>690); // Kør sløjfen igennem, hvis bitsum > 690
}
}
}



void level(void) // Levelroutine
{
if (forbrug < 200) // Hvis forbrug < 200
{
status='a'; // Status sættes til a
}

if ((forbrug >= 200) && (forbrug <210)) // Hvis 210 > forbrug > 200
{
status='b'; // Status sættes til b
}

if ((forbrug >= 210) && (forbrug <220)) // Hvis 220 > forbrug >= 210
{
status='c'; // Status sættes til c
}

if ((forbrug >= 220) && (forbrug <230)) // Hvis 230 > forbrug >= 220
{
status='d'; // Status sættes til d
}

if ((forbrug >= 230) && (forbrug <240)) // Hvis 240 > forbrug >= 230
{
status='e'; // Status sættes til e
}

if ((forbrug >= 240) && (forbrug <250)) // Hvis 250 > forbrug >= 240
{
status='f'; // Status sættes til f
}

if (forbrug >= 250) // Hvis forbrug > 250
{
status='g'; // Status sættes til g
}
}



void reset(void) // Resetroutine
{
if (RA5 == 1) // Tjeck om RA5 er høj - Forsøges der at resette ?
{
if (forbrug<250) // Tjeck om forbrug > 250 liter
{
flag='c'; // Flag sættes til c
count_d=8; // Med 8 i count_d laves et delay
}

if (forbrug>=250) // Tjeck om forbrug er > 250 liter
{
flag='d'; // Flag sættes til d
count_d=8; // Med 8 i count_d laves et delay

forbrug=0; // Reset forbrug
bitsum=0; // Reset bitsum
in_high=0; // Reset in_high
in_low=0; // Reset in_low
}
}
}



void init_disp(void) // Init_disp-routine
{
if (flag == 'a') // Tjeck om flag a er sat (Introduction)
{
sprintf(text, " Forbrugsmaaler 2004");
// Introhilsen: "forbrugsmaaler, 2004"
lcd(); // Kalder lcd-routinen
DELAY(); // Laver et delay

}

else if (flag == 'b') // Tjeck om Flag b er sat (Default forbrugsvisning)
{
sprintf(text, "Forbrug %3.1f L", forbrug);
// Flyt værdien af "forbrug" over på LCD som (xxx.x L)
lcd(); // Kalder lcd-routinen
}

else if (flag == 'c') // Tjeck om Flag c er sat (Visning ved extern reset
< 250.0 L)
{
sprintf(text, " Reset function Not
accessable!");
// Hvis RA5=1 og forbrug < 250 liter
// skriv "Reset function Not accessable"
lcd(); // Kalder lcd-routinen

if (count_d==0) // Tjeck om count_d er nået til 0
{
flag='b'; // Sæt flag til b
}
count_d--; // Træk 1 fra count_d
}

else if (flag == 'd') // Tjeck om Flag d er sat (Visning ved extern reset
> 250.0 L)
{
sprintf(text, "Clearing memory Please WAIT!
");
// Hvis RA5=1 og forbrug >= 250 liter
// skriv "Clearing memory Please WAIT !"
lcd(); // Kalder lcd-routinen

if (count_d==0) // Tjeck om count_d er nået til 0
{
flag='b'; // Sæt flag til b
}
count_d--; // Træk 1 fra count_d
}
}



void init_led(void) // Init_led-routine
{
if (status == 'a') // Tjeck om status a er sat
{
RC1=0; // Send "0" ud på RC1 (Pin12) på uP - sluk dioden
}


if (status == 'b') // Tjeck om status b er sat
{
y=40; // Y sættes til 40, dvs puls 1 - pause 39
interval(); // Kalder interval-routinen
}


if (status == 'c') // Tjeck om status c er sat
{
y=20; // Y sættes til 20, dvs puls 1 - pause 19
interval(); // Kalder interval-routinen
}


if (status == 'd') // Tjeck om status d er sat
{
y=10; // Y sættes til 10, dvs puls 1 - pause 9
interval(); // Kalder interval-routinen
}


if (status == 'e') // Tjeck om status e er sat
{
y=5; // Y sættes til 5, dvs puls 1 - pause 4
interval(); // Kalder interval-routinen
}


if (status == 'f') // Tjeck om status f er sat
{
y=3; // Y sættes til 3, dvs puls 1 - pause 2
interval(); // Kalder interval-routinen
}


if (status == 'g') // Tjeck om status g er sat
{
RC1=1; // Send "1" ud på RC1 (Pin12) på uP - tænd dioden
}
}



void interval() // Intervalroutine !!
{
count_up++; // Forøg count_up med 1
if (count_up<=y) // Tjeck om count_up er <= y
{
if (count_up<=1) // Tjeck om count_up er <= 1
{
RC1=1; // Send "1" ud på RC1 (Pin12) på uP - tænd dioden
}

else // Hvis y ik er < 1.....
{
RC1=0; // Send "0" ud på RC1 (Pin12) på uP - sluk dioden
}
}

else // Ellers gør følgende
{
count_up=0; // Reset count_up
RC1=0; // Send "0" ud på RC1 (Pin12) på uP - sluk dioden
}
}


/*----------------------------------SLEEP-routine---------------------------
------*/
/* SLEEP-routinen mindsker strømforbruget på processoren, når den ext.
forsyning */
/* mangler. */
/*--------------------------------------------------------------------------
------*/
void sleep(void) // SLEEP-routine
{
#asm
sleep
nop
nop
#endasm
}


/*------------------------------Assambler-kommandoer------------------------
------*/
/* Assambler kommandoen skal slette diverse flags under opstart, for at
sikre */
/* korrekt opstart af Wake up. */
/*--------------------------------------------------------------------------
------*/
void asambl(void) // asambler-routine
{
#asm
clrwdt
retfie
#endasm
}


/*----------------------------------READ-routine----------------------------
------*/
/* Her beskrives hvordan man læser data i EEprom */
/*--------------------------------------------------------------------------
------*/
sint read (uchar Index)
{
sint ScrReturn;

EEPGD = 0; // Point to EE memory

EEADR = Index * 2; // Udregn start adressen
RD = 1;
LO( ScrReturn ) = EEDATA;

EEADR++;
RD = 1;
HI( ScrReturn ) = EEDATA;

return( ScrReturn );
}



/*----------------------------------WRITE-routine---------------------------
------*/
/* Her beskrives hvordan man skriver data i EEprom */
/*--------------------------------------------------------------------------
------*/
void write(uchar Index, sint Data)
{
EEPGD = 0; // Point to EE memory
WREN = 1;

EEADR = Index * 2; // Udregn start adressen

RD = 1;
if( EEDATA != LO( Data ))
{
EEDATA = LO( Data );

GIE = 0; // Disable all interrupts
EECON2 = 0x55;
EECON2 = 0xAA;
WR = 1;
GIE = 1; // Enable all interrupts

WdtFlag = TRUE;
while( WR );
}

EEADR++;

RD = 1;
if( EEDATA != HI( Data ))
{
EEDATA = HI( Data );

GIE = 0; // Disable all interrupts
EECON2 = 0x55;
EECON2 = 0xAA;
WR = 1;
GIE = 1; // Enable all interrupts

WdtFlag = TRUE;
while( WR );
}

WREN = 0;
}


/*----------------------------------Hovedprogram----------------------------
------*/
/* Først sættes portene op til via TRISA, TRISB og TRISC. Hernæst sendes
nogle */
/* kommandoer ud til PORTB, som laver 8-bit interface, display on, curser
off, */
/* blink off og clear displayet. Så skal bitsum, Timer0 og start resettes.
Flag a */
/* sættes for at vise Introhilsen og delay'et sørger for, at vi kan nå at se
*/
/* informationen, inden displayet overskrives og går til sin default
visning. */
/* Programmet tjekker inputroutinen, for at se om det har været et forbrug.
*/
/* Forbruget gemmes i en double. Programmet tjekker nu, hvor meget forbrug
der */
/* har været. Så tjekker programmet, om der har været en reset. Nu kaldes
*/
/* display-routinen, og værdien i doublen vil nu blive vist her. Ligeledes
vil */
/* init_led indikere om forbruget har tangeret 200 liter */
/*--------------------------------------------------------------------------
------*/
void main(void) // Hovedprogram
{
TRISA = 16; // Port A til output an input ("1" input og "0" output)
TRISB = 0; // Port B til output
TRISC = 0; // Port C til output
ADCON1 = 6; // Set Port B til Digital

PORTB = 56; // 8 Bit interface
PORTA = 2; //
LCDdelay(); // Kalder LCDdelayroutine
PORTA = 0; //

PORTB = 12; // Display on, Cursor off, Blink off
PORTA = 2; //
LCDdelay(); // Kalder LCDdelayroutine
PORTA = 0; //

PORTB = 1; // Clear display
PORTA = 2; //
LCDdelay(); // Kalder LCDdelayroutine
PORTA = 0; //

RC2=0; // Reset inputport til SLEEP
GIE=0; // Reset General Interupt Enable
bitsum=0; // Reset bitsum
TMR0=0; // Reset 8 bit counter 0
start=0; // Reset start

asambl(); // Resetkommando til watchdog og return from interupt

read();

flag='a'; // Flag sættes til a - Viser startoptekst
init_disp(); // Kalder init_disp for at tjekke hvilket flag, der er sat
DELAY(); // Lav et delay, så vi kan se udlæsningen på displayet
flag='b'; // Sæt flag b, så displayet viser forbrugsudlæsning

do{
PORTB = 2; // Cursor at home
PORTA = 2; //
PORTA = 0; //

input(); // Læs inputsignalet fra flowmåleren

level(); // Kalder level-routinen til LED-udvisning

reset(); // Kalder reset-routinen fra Extern reset

init_disp(); // Kalder initialisering af display

init_led(); // Kalder initialisering af LED-status

if (RC2==1) // Tjeck om RC2 er High
{
write(); // Programmet skal her gemme double-værdien i EEPROM'en, for
at programmet
// ved næste MCLR fortsætter med det forbrug programmet er kommet
frem
// til ved SLEEP !!

sleep(); // Kør SLEEP-funktionen
}

} while(1); // Kør sløjfen igen og igen ......osv
}




Søg
Reklame
Statistik
Spørgsmål : 177438
Tips : 31962
Nyheder : 719565
Indlæg : 6408040
Brugere : 218879

Månedens bedste
Årets bedste
Sidste års bedste