#ifdef __AVR_ATtiny85__
#include <avr/io.h>
#include <avr/pgmspace.h>
typedef unsigned char byte;
typedef unsigned short word;
#define NOINIT __attribute__((section(".noinit")))
#define SINTAB __attribute__((section(".sintab")))
// Sinustabelle, Amplitude 127
extern const struct Sinus127{
char a[256] {};
constexpr Sinus127() {
constexpr float PI=__builtin_atan(1)*4;
for (size_t x=0; x<256; x++)
a[x]=__builtin_round(__builtin_sin(x*PI/128)*127);
}
}sinus127 SINTAB;
const Sinus127 sinus127 SINTAB;
// Fensterfunktion für 256 Samples: Bei 8 MHz und 9,6 kSa/s sind das 26,6 ms
// Ein langes Fenster wird benötigt,
// um die Frequenzdifferenzen von nur 80 Hz klar zu unterscheiden.
extern const struct Fenster127{
char a[256] {};
constexpr Fenster127() {
constexpr float PI=__builtin_atan(1)*4;
for (size_t x=0; x<256; x++) {
auto si=__builtin_sin(x*PI/256);
a[x]=__builtin_round(si*si*127);
}
}
}fenster127 SINTAB;
const Fenster127 fenster127 SINTAB;
constexpr word ADCDIV = 64*13; // 832 Takte pro Sample
// DftScan-Struktur, jede Zahl 16 Bit
// * DC-Summe (alles nach Begrenzung und Fensterung)
// * Betragssumme
// * Für jede Suchfrequenz (maximal 7):
// * Addierwerte entsprechend Suchfrequenz (Konstanten)
// * Phasenwerte (variabel)
// * Addierwerte Sinus (Imaginärteil)
// * Addierwerte Kosinus (Realteil) => Wird zum Betrag der komplexen Zahl
extern struct DftScan{ // sizeof = 4 + 7×8 = 60 Byte RAM
struct{
private: word sum; int dcs; public:
int dc() const {return dcs;}
word volt() const {return sum;} // Gesamtspannung
}sum;
struct{
word add;
private: word pha; int im,re; public:
word volt() const {return re;} // Spektralspannung
}f[7];
void operator()(byte fsize,byte angleadd=1,int mean=0x380);
}dftScan NOINIT;
DftScan dftScan NOINIT;
constexpr word FREQ(float x) {return x*65536*ADCDIV/F_CPU+0.5;}
byte dtmfScan() {
// DDS-Inkremente = Additionswerte auf Phasenwert alle F_CPU/T0DIV
static PROGMEM const word FSearch[8] = {
FREQ( 697),
FREQ( 770),
FREQ( 852),
FREQ( 941),
FREQ(1209),
FREQ(1336),
FREQ(1477),
FREQ(1633),
};
for (byte i=0; i<7; i++) dftScan.f[i].add=pgm_read_word(FSearch+i);
ADCSRA=0xF6; // Start; ADC-Taktteiler stets 64
dftScan(7,F_CPU>=8000000?1:2);
byte r=0;
for (byte i=0, m=1; i<7; i++,m<<=1) if (dftScan.f[i].volt()>1000) r|=m;
if (dftScan.sum.volt()>1000) r|=0x80; // TODO: Schwellen festlegen
return r; // TODO: Auswerten (2 Linien)
}
byte freiScan() {
dftScan.f[0].add=FREQ(425)/2;
ADCSRA=0xF5; // Start; ADC-Taktteiler hier 32
dftScan(1);
byte r=0;
if (dftScan.f[0].volt()>1000) r|=0x01; // TODO: Schwellen festlegen
if (dftScan.sum.volt()>1000) r|=0x80;
return r;
}
#endif
Detected encoding: UTF-8 | 0
|