/* Code auf Basis von Harald Peters: https://www.mikrocontroller.net/topic/134862#postform Mit folgenden Modifikationen: https://www.mikrocontroller.net/topic/134862#3991115 Wenn der 328 doppelt so schnell läuft, dann verdoppeln sich auch die Zählerwerte. Für die Dekodierung von DL braucht man hier nur den Timer0. Also bei 16MHz gilt: if (TCNT0>160 || TIFR0 ) // 2048us dann 2x OCR0A = 95; // 1536us und dann OCR0A = 127; // 2048us, für Bits1..8 wirksam Die Werte habe ich hier korrigiert, da ich ursprünglich vergessen hatte, daß die resultierende Frequenz bei CTC (f/OCR0A+1) ist. Aber so kritisch ist das Ganze nicht. Den Timer2 verwende ich nur zur Ausfalloffenbarung. Wenn länger als 5s keine gültige Daten kommen, gilt das als Ausfall. Da gibt es 1000 weitere Methoden das zu machen. Die Initialisierung von Timer0 kann so bleiben, also Vorteiler 1:256. */ #include #include #include #include #include volatile uint8_t tsek, NeuSek; uint8_t h10ms, t10ms, Dauer10msMin = 100; uint8_t OCRdef = 78; uint8_t BitZ, BytZ, DByte, DFert, DAusfall; uint16_t AnzDLFhl, AnzDLges, DAusfallDauer; struct tDL // 65Byte { /* 00 */ uint16_t Kennung; /* 02 */ uint8_t xxx; /* 03 */ uint8_t Min, Std, Tag, Mon, Jhr; /* 08 */ int Temp[16]; /* 40 */ uint16_t Ausg; /* 42 */ uint8_t Drehz[4], WReg, KW100; /* 48 */ int16_t KW1; // max 6553.1KW /* 50 */ uint8_t KW1H; // immer 0 /* 51 */ uint16_t KWh, MWh; /* 55 */ uint32_t KW2, MWh2; /* 63 */ uint8_t PSum; /* 64 */ uint8_t PSumNeu; }; /* Temp-Sensoren: 0: Speicher oben; 1: Warmwasser; 2: Speicher unten; 3: Speicher Mitte 4: Solarvorlauf; 5: Solarrückl.; 6: WW-Rücklauf; 7: Kollektor Ost 8: Kollektor West; 9: Außenfühler; 10: Zirkulation; 11: Hz-Vorlauf 12: Keller; 13: RF I (KS); 14: Vol.-Strom 15: RF II (Wz) */ union tDLPuffer { uint8_t b[65]; struct tDL t; } DLPuffer, DLWerte; ISR(TIMER2_COMPA_vect) // 100/sek, 10ms { h10ms++; t10ms++; if (t10ms==Dauer10msMin) { t10ms = 0; tsek++; // Überwachung DL NeuSek = 1; } } ISR(INT0_vect) // warten auf Startbit DL { if (BytZ==0) // warten auf 16Synchbits { if (TCNT0>160 || TIFR0 ) // TCNT0=64: 64*32us = 2048us (korrigiert von 80 auf 160 für 16MHz) { if (BitZ<12) // Synchrahmen noch nicht gefunden { BitZ = 0; } else // Start nach >11 Einsbits gefunden { BitZ = 0; OCR0A = 95; // 1536us (korrigiert von 48 auf 95 für 16MHz) TIMSK0 |= (1<80) else { BitZ++; } } else // if (BytZ==0) { // Startflanke neues Byte aufgetreten: BitZ = 0; OCR0A = 95; // 1536us -> nur gültig 1.Bit (korrigiert von 48 auf 95 für 16MHz) TIMSK0 |= (1< alle 32us Inkr. // Timer 2 OCR2A = OCRdef; TCCR2A = (1<5) // keine DL-Daten mehr { tsek = 0; if ( (DAusfall&0x01)==0 ) // Beginn Ausfall { DAusfall = 0x01; DAusfallDauer = 0; } } if (DAusfall) { DAusfallDauer++; } } } // for return 0; } // main