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