/* Kode für mfv2d: 425-Hz-Messung mittels Analogvergleicher an PB1 = AC- = Pin6
und Nulldurchgangs-Abstandsmessung.
Genauso wie beim CLIP-Empfang, nur mit freigegebenen Interrupts
und (damit) ohne ISR. Und das andere Pin.
Erfordert Schutzwiderstand an nsi+nsa.
Einzige exportierte Funktion ist „bool mess425()“,
die bis zum Watchdog-Interrupt (Flags&0x80) = 16 ms arbeiten darf.
220411 erstellt
*/
#include <avr/io.h>
#include <avr/sleep.h>
typedef unsigned char byte;
typedef unsigned short word;
constexpr char LOG2(unsigned v) {return 15-__builtin_clz(v);}
constexpr char CLOG2 = LOG2(F_CPU/1000000);
#define Flags GPIOR0 // Bits für NSK() u.a.
//extern void eechange(byte); // Debug
// Wahlweise kann (0) PB0 fixiert und PB1 detektiert werden
// oder (1) PB1 fixiert und PB0 detektiert werden.
#define FIX 0
// (0): + Keine Störung beim Sprechen
// - Langer Einschwingvorgang
// + Funktioniert besser: Weniger Störungen festgestellt
// - Widerstand 10 kΩ zur Wählscheibe erforderlich
// (1): + Funktion wie CLIP-Empfang
// + Kurzes Einschwingen
// - Kann Sprechen stören (hörbare Amplitudenmodulation)
// - Funktioniert irgendwie schlechter, DC-Versatz?
bool mess425() { // Messung 425 Hz mit Analogvergleicher
if (!(PINB&1)) return false; // Wählscheibe blockiert Empfang (zurzeit!)
if (DDRB&2) return false; // Tonausgabe läuft: Messung sinnlos + Timer0 blockiert
if (PB5DEBUG&3) DDRB|= 0x20;
// Hier steht als Zeitbasis ein freier Timer0 zur Verfügung
TCCR0B = 0x03; // Vorteiler 64
ACSR = 0x03; // Nur steigende Flanke erfassen, unterdrückt tieffrequente Überlagerungen
PORTB |= 0x02;
DDRB |= 1<<FIX;
byte zc=0xFF, tic=0, zcok=0;
ACSR |= 0x10;
do{
if (PB5DEBUG&2) {
if (ACSR&0x20) PORTB|=0x20;
else PORTB&=~0x20;
}
if (ACSR&0x10) { // Interrupt?
// Das Signal hat an PB0 oder PB1 eine Amplitude von 150 mVss
// und ist von nadelartigen Störungen überlagert.
// Deshalb zu kurze Abstände ausblenden.
byte dt=TCNT0-tic;
constexpr byte EL=F_CPU/(1<<CLOG2)/64/3400; // Etwas höheres als 3,4 kHz kommt nicht; EL = 4,6
if (dt>=EL && ACSR&0x20) { // Lang genug und immer noch High? Low ignorieren, war Nadelimpuls
if (PB5DEBUG&1) PINB|= 0x20; // Toggeln
tic+=dt;
if (++zc) { // Beim nicht-ersten Nulldurchgang Zeit bewerten
constexpr byte DT=F_CPU/(1<<CLOG2)/64/425; // Gesuchte Frequenz; SA = 36,8
constexpr byte DW=0;
if (DT-DW<=dt && dt<=DT+DW+1) {
++zcok;
if (PB5DEBUG&1) PORTB|= 0x20;
}else if (PB5DEBUG&1) PORTB&=~0x20;
}
}
ACSR |= 0x10; // Interruptflag (jetzt erst!) löschen
}
}while(!(Flags&0x80) && PINB&1);
DDRB &=~(1<<FIX);
PORTB &=~0x02;
ACSR = 0x80;
TCCR0B = 0;
if (PB5DEBUG&3) {
DDRB &=~0x20;
PORTB|= 0x20;
}
return zc>=4 && zcok>=zc-1;
}
Detected encoding: UTF-8 | 0
|