PIC16F870 vill inte snurra ordentligt efter sleep.
Postat: 15 maj 2007, 14:53:21
Jag har skrivit ett program för en 16F870. Programmet tar emot ett meddelande på UARTen, kontrollerar meddelandet och räknar ut hur länge den ska ligga i sleep beroende på vad som står i meddelandet. tiden är upp till 2 timmar vilket jag realiserar genom att använda en 32kHz osc till TIMER1. Timeravbrotten väcker µP var 10:e sekund och räknar upp variabeln delay. Allt fungerar bra hit. MEN till problemet:
När delay räknats ned och programmet ska gå ur loopen så väntar den på att ett nytt meddelande tas emot på UARTen men när den gått ur sleep så hinner den bara sätta en utgång hög sen lägger den sig i sleep igen. Det borde enligt mej vara helt omöjligt, men icke! Klipper in Sleep-rutinen och relevanta delar av avbrottsrutinen:
Avbrottsrutinen:
När delay räknats ned och programmet ska gå ur loopen så väntar den på att ett nytt meddelande tas emot på UARTen men när den gått ur sleep så hinner den bara sätta en utgång hög sen lägger den sig i sleep igen. Det borde enligt mej vara helt omöjligt, men icke! Klipper in Sleep-rutinen och relevanta delar av avbrottsrutinen:
Kod: Markera allt
void PWRDown(void)
{
byte temp, CCP1Temp, PIETemp, CCPTempH, CCPTempL, a, b;
PIETemp = PIE1;
temp = T1CON;
CCP1Temp = CCP1CON;
T1OSCEN = 1; //Starta 32kHz-osc.
ms = 103; //OSC-start up delay
RC2 = !RC2;
while(ms>1);
RC2 = !RC2;
TMR1L = TIOSEKL;
TMR1H = TIOSEKH;
CCP1CON = 0x00;
T1CON = 0b00111111; //Prescaler = 1/8, enable ext osc, ej synk, T1 på EXTERN osc, TMR1ON = ON.
Sleep = 1; //Sleepflagga.
PIE1 = 0x00000001; //Endast TIMER1 Overflow Interrupt Enable.
a = 0x35 - CommandBuff[16]; //50 - Min10.
a *= 10;
b = 0x3A - CommandBuff[17]; //10 - Min1.
a += b; //a = Minuter i decimalform.
delay = 0;
delay = (uns16)a * 6; //antal minutrar uttryckt i 10-sekunders enheter.
delay -= 42; //dra ifrån 7 min för DCF och offset.
// if(!(CommandBuff[15] & 0b00000001)) //Om jämn timma, lägg till en timma sleep.
// delay += 360;
// delay = 3; //TEST TEST TEST TEST TEST TEST TEST!????????????????????????????????????????????
PORTB = 0x00;
RC3 = !RC3; //TEST TEST TEST TEST TEST TEST TEST!????????????????????????????????????????????
while(delay >= 1) //Ligg i Sleep tills nästa jämna timmomslag.
{
sleep(); //God natt..
nop(); //Denna rad exekveras ALLTID vid wake up, SEN avbrottet.
}
RC3 = !RC3; //TEST TEST TEST TEST TEST TEST TEST!????????????????????????????????????????????
Sleep = 0; //Nolla Sleep-flaggan.
CCP1CON = CCP1Temp;
T1CON = temp;
PIR1 = 0b00000000;
PIE1 = PIETemp;
DCF = 0; //TEST TEST TEST TEST TEST TEST TEST!????????????????????????????????????????????
}
Kod: Markera allt
//SLEEP-RÄKNAREN
}
if(Sleep)
{
TMR1L = TIOSEKL; //Ladda om TIMER1 för 10sek-avbrott.
TMR1H = TIOSEKH;
if(delay == 0)
return;
delay--; //TEST TEST TEST TEST!!!!!!!!!! 10 sekunder !!!!!!!!!!!!!!!!!!!!!
DCF = !DCF;
}
TMR1IF = 0;