PIC16F873 vs. SLEEP MODE og wake up

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From Danish to

Threaded View
Hej NG.

Jeg sidder med et projekt, hvor jeg bruger en Pic16F873 til at måle
forbrugsmængden, der løber igennem et vandsystem. For hver liter der løber
igennem, summerer den op i et 2 Line 16 Segment LCD-display. Ved start på
0000h indledes med bla.bla bla bla osv opstartstekst !!
Kredsløbet, hvori Pic-processoren sidder er, er spændingsovervåget af IC2,
jeg ikke husker navnet på. Når forsyningsspændingen forsvinder, detekterer
RC1 en HIGH fra IC2'ens output, som fortæller PIC'en at den skal gå i SLEEP
MODE for at mindske strømforbruget.

Når supply-forsyningen forsvinder, har jeg en 1F / 6,3V-kondensator
siddende, som agerer battery, for at huske de data, som er lagret i PIC'en.

Jeg har fået den til at gå i SLEEP Mode, men når jeg sender en lav på MCLR,
viser den kortvarig opstartsteksten i mit display, hvorefter den ej
fortsætter med at måle forbrugsmængden. JEg har målt direkte på krystallet,
og den starter fint op ved MCLR, hvor efter den forsvinder, når den når til
programstart igen. Når jeg så sluker strømforsyningen og tænder igen,
starter programmet fint op igen.

Jeg undrede mig over, at jeg måtte bruge ASM-commandoer for overhovedet at
kuynne lave et SLEEP-forløb - Er det normalt, at man skal blande ASM med C++
??

Hvordan sætter portene til at bruge mindst mulig strøm ??

Hvordan laver jeg et korrekt SLEEP - Wake UP forløb ??

Hvordan gemmes DATA'er i EEPROM'en ??

Jeg skal nok Copy / paste mit program her i forummet imorn, men dette indlæg
bare for at give en fornemmesle af prblemet jeg sidder med.

mvh
Kenneth Huus



Re: PIC16F873 vs. SLEEP MODE og wake up
Quoted text here. Click to load it

En kort lav puls på MCLR burde starte PIC'en op igen. Hvad sker der hvis
du giver en MCLR puls mens dit program kører normalt (altså ikke når den
er i sleep mode)? Det er faktisk muligt at se forskel på Power On Reset
(POR) og en MCLR during sleep. Det kan ses på bittene POR, BOR, TO og
PD. Se databladet her. Men hvis din kode ikke kigger på disse bit, burde
PIC'en starte normalt.

Måske kan det hjælpe hvis du har følgende allerførst i din kode:
clrf PCLATH

Desuden er det godt at nulstille watchdog'en og lige deaktivere interrupts:
clrwdt
clrf    INTCON    

Når så du igen har nulstillet dine timere, kan du enable interrupts
igen. Noget andet som kan få mystisk konsekvenser er hvis du har en
return eller retfie stående som tilfældigvis køres. Det kan måske
resultere i, at din sleep kommando eksekveres igen. Hvis du har et debug
værktøj (såsom ICD2), så prøv at sætte et break-point før din sleep
kommando.

Quoted text here. Click to load it

Det er helt normalt.

Quoted text here. Click to load it

Det er efter min mening bedst at sætte porte til udgange, da de så ikke
kan opfange støj (som resulterer i at portene skifter state, og bruger
strøm).

Quoted text here. Click to load it

Det burde ikke være noget problem..

Quoted text here. Click to load it

Kig i databladet. Du skal følge en ganske bestemt sekvens, hvor du gør
nogle ting i den rigtige rækkefølge. Det er en sikring mod tilfældig
skrivning. Jeg plejer desuden af have en parameter, som skal have en
bestemt (magisk) værdi før skrivningen kan eksekveres.

Mvh Thomas Jørgensen




Re: PIC16F873 vs. SLEEP MODE og wake up
Quoted text here. Click to load it

Når jeg laver en MCLR under programafvikling, starter den programmet
almindelig vis. Det er kun, når PIC'en går i Sleep, at opstarten er i ged.
Jeg har ingen kode på POR, BOR, TO og PD.

Quoted text here. Click to load it

Hvad er clrf for en kommando ??

Quoted text here. Click to load it

Dette var også mit umiddelbare næste bud, men mente ik, der var nødvendigt.

Quoted text here. Click to load it

Jeg bruger kun Timer0. Jeg har ingen return eller retfie (hvad det nu end
er). Hvor kan man hente et debug værktøj henne ??

Quoted text here. Click to load it

Ja, jeg ved godt at jeg skal sætte dem til output - Men hvilken state Hi, Lo
Three State ??

Quoted text here. Click to load it

Kan du gi et eksempel ??

mvh
Kenneth






Re: PIC16F873 vs. SLEEP MODE og wake up

Quoted text here. Click to load it

Okay.

  Hvad er clrf for en kommando ??

clrf er "clear file". Den lægger blot 0x00 ind i registret.

Quoted text here. Click to load it
 >
Quoted text here. Click to load it

Prøv det alligevel :)

  > Jeg bruger kun Timer0. Jeg har ingen return eller retfie (hvad det
nu end
Quoted text here. Click to load it

Jeg har købt en uoriginal ICD2 til omkring 700 kroner. Den tilsluttes
USB, og så har man direkte adgang til registre og kan single-steppe og
sætte break-points ind i koden. Det er nok mest velegnet til assembler
programmering.

Quoted text here. Click to load it

Three state er jo indgang.. Du skal sætte dem til output. Om de er Hi
eller Lo er ifølge App.note AN606 ikke så vigtigt.


Quoted text here. Click to load it

Ja, sådan gør jeg på 16F874.. det er assembler, og mere eller mindre
kopieret fra databladet :)

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

Skrivning er mere tricky...

WriteEEbyte        ;Skriver til den valgte adresse (i eepromaddr)
    movf    eepromvalue, w
    bsf    STATUS, RP1    ;Bank 2
    bcf    STATUS, RP0    ;
    movwf    EEDATA

    bcf    STATUS, RP1
    movf    eepromaddr, w
    bsf    STATUS, RP1    ;Bank 2
    movwf    EEADR
    clrf    EEADRH
    
    bsf    STATUS, RP0    ;Bank3
    movlw    b'00000100'    ;Sæt op til Data memory
    movwf    EECON1

  waiteeread
    btfsc    EECON1, WR
    goto    waiteeread    ;Make sure EEPR is not writing.
  eeprready
    bcf    INTCON, GIE
    bsf    EECON1, WREN
    movlw    55h
    movwf    EECON2
    movlw    0AAh
    movwf    EECON2
    bsf    EECON1, WR
    bcf    EECON1, WREN        
    bsf    INTCON, GIE

    bcf    STATUS, RP0    ;Back in back0
    bcf    STATUS, RP1    
    return            ;

Mvh Thomas










Re: PIC16F873 vs. SLEEP MODE og wake up
Den Sun, 12 Dec 2004 22:23:47 +0100, Thomas Jørgensen


Quoted text here. Click to load it

Hvis man hellere vil bygge selv så er opskriften her:
http://www.stolz.de.be /

Godtnok kun med serielport, men prisen er ok.

--
Jens   OZ2JP   callto://jensep

There are thinkers and there are doers. I think I need a doer.

Re: PIC16F873 vs. SLEEP MODE og wake up
Tak for svarene - Jeg melder tilbage imorn, når jeg har forsøgt med de nye
tiltag. Desuden får I lige en udskrift af min source-fil !!

Nat nat herfra


Quoted text here. Click to load it




Re: PIC16F873 vs. SLEEP MODE og wake up
Her er selve hovedprogrammet så!!
-------------------------------------------------------------------
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;  //

  bitsum=0;  // Reset bitsum
  TMR0=0;  // Reset 8 bit counter 0
  start=0;  // Reset start

  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)
    {
    // 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();
    }



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



Min SLEEP-routine ser således ud:
-------------------------------------------------------------------
void sleep(void)   // SLEEP-routine
{
  #asm
  sleep
  nop
  nop
  #endasm
}
-------------------------------------------------------------------

Håber der er nogen der kan se hvad der måske mangler !!

mvh
Kenneth Huus



Re: PIC16F873 vs. SLEEP MODE og wake up
Efter lidt nørglen rundt, har jeg med lidt mindre småjusteringer fundet en
løsning. For at nævne et par ting som gjorde udslaget, så kan jeg nævne, at
watchdog'en skulle resettes, return from interupt skulle med i sløjfen,
general interupt enable skulle resettes ligesom det mest væsentlige =
Indgangen hvor mit signal til sleep kommer på, skulle også resettes under
opstart. Ellers aner den jo ikke hvad værdi den har og om den skal resette,
og støjen kunne åbenbart godt få den til at gå i SLEEP mode.

Det eneste jeg stadig ikke helt kan greje, er hvordan man skriver en
doubles-værdi til EEPROM'en !! Jeg synes bestemt ikke de Assamblerkoder til
PIC16f873 ligner de samme, som jeg brugte på min AtMEL89c2056. På en eller
anden måde skal stackpointeren vel have at vide, at nu skal
lagringsprocessen skrive eller læse i EEPROM'en - Kan jeg sgu ikke
umiddelbart greje.

Det færdige stykke kommer her !!



/*----------------------------------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
}



/*----------------------------------Hovedprogram----------------------------
------*/
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;  //
  GIE=0;  //
  bitsum=0;  // Reset bitsum
  TMR0=0;  // Reset 8 bit counter 0
  start=0;  // Reset start

  asambl();  //

  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)  //
    {
    // 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();  //
    }

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



Site Timeline