Instantly share code, notes, and snippets.
Created
August 6, 2018 05:43
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save speters/583fcf2e1852f3eb1f7a178a84620cce to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Einfacher Navtex-Empfaenger | |
* | |
* von Martin Kuettner <[email protected]> 03/2016 | |
* | |
* | |
* Portierung des 80C51 Assembler Programms aus "A NAVTEX Receiver for the DXer": | |
* | |
* Klaus Betke, Am Entengrund 7, D-26160 Bad Zwischenahn, Email: [email protected] | |
* 11-AUG-00 / 01-OCT-00 | |
* | |
* Die Portierung in C lauffaehig auf einem ATmega32U4 (Arduino Mirco). Andere Arduino Modelle, | |
* welche auf dem ATmega32U4 basieren sollten das Programm auch verarbeiten koennen. | |
* Bitte auf eventuelle andere Konfiguration der Ausgangspins achten. | |
* | |
* Entwicklungsumgebung: Arduino v1.67 | |
* | |
* Entfernt: Uhrzeitanzeige | |
* Da der ATmega32U4 keine Echtzeituhr besitzt und die Auswertung auf einem Raspberry PI mit GPS Modul | |
* geschieht, wird keine Uhr auf dem ATmega32U4 benoetigt. | |
* | |
* Das Programm ist optimierungsfaehig, ich habe es so geschrieben, dass ich den Quelltext auch | |
* ohne Kommentare verstehe. Deshalb wurde auch an einigen Stellen bewusst geschrieben (if ((byte & 0b111100) > 0)) | |
* bzw. auf Verkuerzungen, wie i += 5 verzichtet! | |
* | |
* Wer moechte kann das alles gern optimieren :) | |
* | |
*/ | |
// zum Copy&Paste fuers debugging | |
/* | |
digitalWrite(DebugPin, HIGH); | |
delayMicroseconds(100); | |
digitalWrite(DebugPin, LOW); | |
*/ | |
/* | |
tobinstr(sirawdata,8,uart); | |
sprintf(uart,"%s\n",uart); | |
Serial1.write(uart); | |
*/ | |
#include <EEPROM.h> | |
// Pin Definitionen | |
const byte DebugPin = 13; // Pin mit eingebauer LED auf dem Micro | |
const byte DataPin = 7; // Datenpin vom Empfaenger | |
const byte ErrorLEDPin = 12; // Wenn Error gesetzt wird | |
const byte SyncLEDPin = 11; // Wenn Daten empfangen werden | |
const byte Do518kHzLEDPin = 10; // Wenn auf 518kHz empfangen wird (Standard) | |
const byte Do518kHzSetPin = 8; // Ausgang fuer Teiler nach der PLL | |
const byte DataLEDPin = 9; // Daten LED .. zum blinkern... | |
const byte UpperLowerInPin = 4; // Eingangspin fuer Ausgabe Gross oder Klein | |
const byte FrequenzInPin = 6; // Eingangspin Umschaltung 490/518kHz | |
// Datenport - internes Register | |
bool InPort; // interne Datenvariable zur uebergabe | |
// Arbeiter | |
byte AA; // Arbeitsregister fuer externe Requests | |
unsigned int AB; // Arbeitsregister fuer DataPin Interrupt | |
byte AC; // Arbeitsregister fuer Puffer beim Bitholen | |
byte AD; // Arbeitsregister fuer Bitschieben bei Byteabholen | |
bool debug = LOW; | |
bool FF = LOW; | |
bool InWait; | |
// Sync & Clock | |
byte loopadjust = 255; // Zaehler zum Clockschieben-Ausloeser | |
byte loopgain = 128; // Regler, wie oft nachgeregelt werden soll | |
byte clock3200 = 0b00100000;// Taktgeber fuer 10ms Takt (3,2kHz / 32) | |
// Laufvariablen | |
byte i; // Runner fuer loops | |
// Daten | |
byte sirawdata; // rohdaten, die in Timerinterrupt geholt werden | |
byte bitsavailable; // Zaehler wie viel Bits verfuegbar sind (max 8) | |
byte error; // Fehlerzaehler fuer Empfang | |
byte RingBuffer[3]; // 3 Byte Ringpuffer zur Fehlervorwaertskorrektur | |
byte RXByte; // Empfangenes Byte auf dem RX Kanal | |
byte CharRingBuffer; // Zeichen, welches aus dem Ringbuffer stammt (zur Fehlerkorrektur) | |
byte CharRX; // Zeichen, welches empfangen wurde | |
char ReceivedChar; // Zeichen, was an die UART ausgegeben wird | |
// Konstanten, Steuerzeichen aus dem SITOR Code (alles, wo "1" in der LUT steht) | |
// diese Zeichen werden nicht ausgegeben, dienen nur zur internen Steuerung | |
const byte ALPHA = 0x0F; | |
const byte ALPHAUP = 0x7F; | |
const byte REP = 0x66; | |
const byte LRTS = 0x5A; | |
const byte FIGS = 0x36; | |
const byte LF = 0x6c; | |
const byte CR = 0x78; | |
const byte CHAR32 = 0x6A; | |
const byte SPACE = 0x5C; | |
const byte BETA = 0x33; | |
const byte BEL = 0x17; | |
const char errsymbol = '~'; // Fehlerzeichen ("0" in der LUT) | |
// Statusbits | |
bool Shifted = LOW; // Zahlen oder Buchstaben LUT nutzen? | |
bool Frequenz = HIGH; // Abbruchvariable, wenn Frequenz umgeschaltet wird | |
bool UpperLower = HIGH; // Abbruchvariable, wenn LUT umgeschaltet wird | |
bool sync = LOW; // Pruefvariable ob gueltige Sequenz ALPHA-REP-ALHPA ampfangen wurde | |
bool NotLostSync = HIGH; | |
// UART Puffer | |
char uart[255]; // Ausgangs Puffervariable fuer UART | |
// Es gibt verschiedene Zuordnungen - das ist die Europaeische Variante (ausser 0xd3 - da hab ich das $ gelassen) | |
// LUT - in Kleinbuchstaben | |
static const uint8_t lutLOWER[256] = | |
//0 1 2 3 4 5 6 7 8 9 a b c d e f | |
{ | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0 | |
0, 0, 0, 0, 0, 0, 0, 'j', 0, 0, 0, 'f', 0, 'c', 'k', 0, // 1 | |
0, 0, 0, 0, 0, 0, 0, 'w', 0, 0, 0, 'y', 0, 'p', 'q', 0, // 2 | |
0, 0, 0, 1, 0, 'g', 1, 0, 0, 'm', 'x', 0, 'v', 0, 0, 0, // 3 | |
0, 0, 0, 0, 0, 0, 0, 'a', 0, 0, 0, 's', 0, 'i', 'u', 0, // 4 | |
0, 0, 0, 'd', 0, 'r', 'e', 0, 0, 'n', 1, 0, ' ', 0, 0, 0, // 5 | |
0, 0, 0, 'z', 0, 'l', 1, 0, 0, 'h', 1, 0, 1, 0, 0, 0, // 6 | |
0, 'o', 'b', 0, 't', 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 7 | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 8 | |
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, '!', 0, ':', '(', 0, // 9 | |
0, 0, 0, 0, 0, 0, 0, '2', 0, 0, 0, '6', 0, '0', '1', 0, // a | |
0, 0, 0, 1, 0, '&', 1, 0, 0, '.', '/', 0, '=', 0, 0, 0, // b | |
0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '\'', 0, '8', '7', 0, // c | |
0, 0, 0, '$', 0, '4', '3', 0, 0, ',', 1, 0, ' ', 0, 0, 0, // d | |
0, 0, 0, '+', 0, ')', 1, 0, 0, '#', 1, 0, 1, 0, 0, 0, // e | |
0, '9', '?', 0, '5', 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 // f | |
}; | |
// LUT - in Grossbuchstaben | |
static const uint8_t lutUPPER[256] = | |
//0 1 2 3 4 5 6 7 8 9 a b c d e f | |
{ | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0 | |
0, 0, 0, 0, 0, 0, 0, 'J', 0, 0, 0, 'F', 0, 'C', 'K', 0, // 1 | |
0, 0, 0, 0, 0, 0, 0, 'W', 0, 0, 0, 'Y', 0, 'P', 'Q', 0, // 2 | |
0, 0, 0, 1, 0, 'G', 1, 0, 0, 'M', 'X', 0, 'V', 0, 0, 0, // 3 | |
0, 0, 0, 0, 0, 0, 0, 'A', 0, 0, 0, 'S', 0, 'I', 'U', 0, // 4 | |
0, 0, 0, 'D', 0, 'R', 'E', 0, 0, 'N', 1, 0, ' ', 0, 0, 0, // 5 | |
0, 0, 0, 'Z', 0, 'L', 1, 0, 0, 'H', 1, 0, 1, 0, 0, 0, // 6 | |
0, 'O', 'B', 0, 'T', 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 7 | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 8 | |
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, '!', 0, ':', '(', 0, // 9 | |
0, 0, 0, 0, 0, 0, 0, '2', 0, 0, 0, '6', 0, '0', '1', 0, // a | |
0, 0, 0, 1, 0, '&', 1, 0, 0, '.', '/', 0, '=', 0, 0, 0, // b | |
0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '\'', 0, '8', '7', 0, // c | |
0, 0, 0, '$', 0, '4', '3', 0, 0, ',', 1, 0, ' ', 0, 0, 0, // d | |
0, 0, 0, '+', 0, ')', 1, 0, 0, '#', 1, 0, 1, 0, 0, 0, // e | |
0, '9', '?', 0, '5', 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 // f | |
}; | |
// Initiales Setup der Register | |
void setup() { | |
// Pin als Interrupt, sfallende Flanke auf der Datenleitung | |
attachInterrupt(digitalPinToInterrupt(DataPin), EventOnInput, FALLING); | |
// Pin 13 (der mit LED) als Ausgang (zum Debug) | |
pinMode(DebugPin, OUTPUT); | |
// 2 Eingangspins fuer Frequenz und Zeichensatz | |
pinMode(UpperLowerInPin, INPUT); | |
pinMode(FrequenzInPin, INPUT); | |
// weitere Pins als Ausgang konfigurieren | |
pinMode(ErrorLEDPin, OUTPUT); | |
pinMode(SyncLEDPin, OUTPUT); | |
pinMode(Do518kHzLEDPin, OUTPUT); | |
pinMode(Do518kHzSetPin, OUTPUT); | |
pinMode(DataLEDPin, OUTPUT); | |
// Spielerrei... | |
for (i=0; i<5; i++) { | |
digitalWrite(Do518kHzLEDPin, HIGH); | |
delay(50); | |
digitalWrite(DataLEDPin, HIGH); | |
delay(50); | |
digitalWrite(SyncLEDPin, HIGH); | |
delay(50); | |
digitalWrite(ErrorLEDPin, HIGH); | |
delay(50); | |
digitalWrite(Do518kHzLEDPin, LOW); | |
delay(50); | |
digitalWrite(DataLEDPin, LOW); | |
delay(50); | |
digitalWrite(SyncLEDPin, LOW); | |
delay(50); | |
digitalWrite(ErrorLEDPin, LOW); | |
delay(50); | |
} | |
// UART - 9600 BAUD | |
Serial1.begin(9600); | |
//letzte Einstellungen aus dem EEProm holen | |
Frequenz = EEPROM.read(0); | |
UpperLower = EEPROM.read(1); | |
if (UpperLower == LOW) { | |
Serial1.write("---Lowercased---\n"); | |
} else { | |
Serial1.write("---Uppercased---\n"); | |
} | |
if (Frequenz == LOW) { | |
Serial1.write("---490kHz---\n"); | |
digitalWrite(Do518kHzLEDPin, LOW); | |
digitalWrite(Do518kHzSetPin, LOW); | |
} else { | |
Serial1.write("---518kHz---\n"); | |
digitalWrite(Do518kHzLEDPin, HIGH); | |
digitalWrite(Do518kHzSetPin, HIGH); | |
} | |
// Interrupt Timer Setup | |
DDRC |= (bit(7) | bit(6)); | |
TCCR1A = 0; | |
TCCR1B = (1 << WGM12) | (1 << CS10); // Timer 1 ohne prescale (laeuft auf 16MHz) | |
OCR1A = 5000; // Nach 5000 Taktzyklen (also alle 312,5us | 16MHz) Interrupt ausloesen | |
TIMSK1 |= (1 << OCIE1A); | |
} | |
// Hauptprogramm | |
void loop() { | |
Serial1.write("---Loop Start---\n"); | |
// wenn aenderung an Frequenz- oder Zeichensatz-Pin | |
if (AA > 0) { | |
if ((AA & 0b01) == 0b01) { // Zeichensatz umschalten | |
if (UpperLower == LOW) { | |
Serial1.write("---Lowercased---\n"); | |
EEPROM.write(1, 0); | |
} else { | |
Serial1.write("---Uppercased---\n"); | |
EEPROM.write(1, 1); | |
} | |
} | |
if ((AA & 0b10) == 0b10) { // zu empfangende Frequenz umschalten | |
if (Frequenz == LOW) { | |
Serial1.write("---490kHz---\n"); | |
digitalWrite(Do518kHzLEDPin, LOW); | |
digitalWrite(Do518kHzSetPin, LOW); | |
EEPROM.write(0, 0); | |
} else { | |
Serial1.write("---518kHz---\n"); | |
digitalWrite(Do518kHzLEDPin, HIGH); | |
digitalWrite(Do518kHzSetPin, HIGH); | |
EEPROM.write(0, 1); | |
} | |
NotLostSync = HIGH; // verhindern, dass Error LED angeht | |
} | |
AA = 0; | |
} | |
/* | |
* Error LED schalten, wenn kein EOT empfangen wurde. | |
* bleibt an, bis naechster Sync erreicht wurde. | |
* evtl. mal umbauen und ueber Bitclock einen int16 Zaehler runterlaufen lassen, | |
* der dann die LED nach einer gewissen Zeit abschaltet... | |
*/ | |
if ((error > 16) || (NotLostSync == LOW)) { | |
digitalWrite(ErrorLEDPin, HIGH); | |
} else { | |
digitalWrite(ErrorLEDPin, LOW); | |
} | |
digitalWrite(DataLEDPin, LOW); | |
loopgain=96; // so lange kein Sync - oft nachregeln! | |
loopadjust=255; // Zaehler zuruecksetzen | |
Shifted = LOW; // Auf Buchstaben LUT stellen | |
NotLostSync = LOW; | |
sync = LOW; // kein sync | |
InWait = HIGH; | |
while (sync != HIGH) { // uC bleibt in dieser Schleife, bis ALPHA-REP-ALPHA kommt | |
while (GetOneBit() != ALPHA) { // Bitweise schauen, ob ALPHA empfangen wurde | |
CheckInput(); // Pruefe, ob sich an Zeichensatz-/Frequenz-Pin was geaendert hat | |
if (AA > 0) { | |
break; | |
} | |
} | |
InWait = LOW; | |
if (AA == 0) { // ueberspingen, wenn Konfig anders werden soll! | |
sync = HIGH; // sync high, wird low, wenn die naechsten Zeichen nicht passen | |
if (Get7Bits() != REP) { // 7 Bits abholen und auf REP Pruefen | |
sync = LOW; | |
} else { | |
RingBuffer[0] = REP; // Falls wahr, Ringpuffer befuellen | |
} | |
if (Get7Bits() != ALPHA) { // 7 Bits abholen und auf ALPHA Pruefen | |
sync = LOW; | |
} | |
} | |
if (AA > 0) { // while beenden, wenn Konfig anders werden soll! | |
break; | |
} | |
} | |
if (AA == 0) { | |
Serial1.write("\n---InSync---\n"); // Debug String | |
loopgain=8; // Sync da -> Reglung entschaerfen | |
error = 0; // Fehlerzaehler auf 0 | |
digitalWrite(ErrorLEDPin, LOW); // Error aus | |
digitalWrite(SyncLEDPin, HIGH); // Sync LED an | |
RingBuffer[1] = 0; // Ringbuffer[1] leeren, damit evtl. altes Zeichen uebertragung nicht abbrechen laesst | |
/* | |
// debug - nur die Bitfolgen ausgeben - dazu muss der untere while-Teil jedoch auskommentiert werden! | |
tobinstr(CharRX,7,Get7Bits();); | |
sprintf(uart,"%s\n",CharRX); | |
Serial1.write(uart); | |
// debug Ende | |
*/ | |
// ab hier immer 2 Zeichen abholen | |
while (error < 16) { // Schleife laeuft bis Abbuch, oder Fehler >= 32 | |
RingBuffer[2] = RingBuffer[1]; | |
RingBuffer[1] = RingBuffer[0]; | |
RingBuffer[0] = Get7Bits(); // Ringpuffer schieben und mit neuem Zeichen befuellen | |
RXByte = Get7Bits(); // RX Puffer mit neuem Zeichen Fuellen | |
/* | |
* Der Empfang funktioniert so: | |
* Es wird um 3 Zeichen versetzt wiederholt gesendet. | |
* Damit kann man das als 2 ineinander gemultiplexte Kanaele sehen | |
* Trennt man das auf, schaut es so aus: | |
* - Startsequenz - | |
* ALPHA ALPHA ALPHA ALPHA K U T T _ I S | |
* REP REP REP K U T T _ I S T | |
* Der untere Kanal ist der Ringpuffer, der obere der Empfangskanal | |
* Es wird immer ein Zeichen aus dem oberen und unteren geholt und geschaut, was 3 Zeichen | |
* vorher auf dem anderen Kanal empfangen wurde | |
*/ | |
if (RXByte != ALPHA) { // So lange ALPHA auf dem RXbyte steht, wird immer noch Synchronisation gesendet | |
ReceivedChar = ByteToASCII(); // Byte in Char wandeln | |
if ((ReceivedChar != 0) && (ReceivedChar != 1)) { // wenn gueltig .. | |
Serial1.write(ReceivedChar); // ..an UART ausgeben | |
if (FF == LOW) { | |
digitalWrite(DataLEDPin, LOW); | |
FF = HIGH; | |
} else { | |
digitalWrite(DataLEDPin, HIGH); | |
FF = LOW; | |
} | |
} | |
if (RingBuffer[2] == ALPHA) { // Abbruchbedingung, wenn uebertragung zu Ende ist | |
Serial1.write("\n---EOT---\n"); | |
digitalWrite(ErrorLEDPin, LOW); | |
NotLostSync = HIGH; | |
error = 0; | |
break; | |
} | |
} | |
} | |
Serial1.write("\n---OutSync---\n"); | |
digitalWrite(SyncLEDPin, LOW); | |
} | |
} | |
// Wandeln eines Bytes zu Char incl. Fehlerkorrektur und Auswertung von Steuerzeichen | |
char ByteToASCII() { | |
if (UpperLower == LOW) { | |
CharRX = lutLOWER[RXByte | (Shifted << 7)]; // RX Puffer in Char wandeln unter Beachtung des zu verwendeten Zeichensatzes | |
CharRingBuffer = lutLOWER[RingBuffer[2] | (Shifted << 7)]; // RingPuffer in Char wandeln unter Beachtung des zu verwendeten Zeichensatzes | |
} else { | |
CharRX = lutUPPER[RXByte | (Shifted << 7)]; // RX Puffer in Char wandeln unter Beachtung des zu verwendeten Zeichensatzes | |
CharRingBuffer = lutUPPER[RingBuffer[2] | (Shifted << 7)]; // RingPuffer in Char wandeln unter Beachtung des zu verwendeten Zeichensatzes | |
} | |
if ((CharRX == 0) && (CharRingBuffer == 0)) { // beide ungueltig :/ | |
error++; | |
return errsymbol; // error erhoehen und Fehlerzeichen ausgeben | |
} else if ((CharRX == 0) && (CharRingBuffer != 0)) { // RX ungueltig aber RingBuffer OK | |
CharRX = CharRingBuffer; // Zeichen umkopieren | |
RXByte = RingBuffer[2]; // RXByte umkopieren fuer switch-Abfrage... | |
if (error > 0) { | |
error--; // Fehlerzaehler um eins erringern | |
} | |
} | |
if (CharRX == 1) { // wenn aus der LUT 1 kommt = Steuerzeichen | |
switch(RXByte) { | |
case LRTS: // benutze Zeichen | |
Shifted = LOW; | |
break; | |
case FIGS: // benutze Zahlen (offset 0x80h) | |
Shifted = HIGH; | |
break; | |
case BETA: | |
case ALPHA: | |
case ALPHAUP: | |
case REP: | |
case CR: | |
case BEL: | |
break; // Zeichen fuer Ausgabe irrelevant | |
case LF: | |
return '\n'; // Neue Zeile | |
break; | |
case CHAR32: | |
case SPACE: | |
return ' '; // Leerzeichen | |
default: | |
sprintf(uart,"Unknown: 0x%x\n",RXByte); | |
Serial1.write(uart); | |
break; // Zeichen unbekannt = Error | |
return 0; | |
} | |
} else { | |
return CharRX; | |
} | |
} | |
byte GetOneBit() { | |
while (bitsavailable == 0) { | |
delay(1); | |
} | |
if (AA == 0) { | |
switch(bitsavailable) { // je nach Puffergroesse Zeichen auswaehlen und zurueckgeben | |
case 7: | |
AC = AC << 1; | |
AC = AC | ((sirawdata & 0b00000001) << 6); | |
bitsavailable--; | |
break; | |
case 6: | |
AC = AC << 1; | |
AC = AC | ((sirawdata & 0b00000010) << 5); | |
bitsavailable--; | |
break; | |
case 5: | |
AC = AC << 1; | |
AC = AC | ((sirawdata & 0b00000100) << 4); | |
bitsavailable--; | |
break; | |
case 4: | |
AC = AC << 1; | |
AC = AC | ((sirawdata & 0b00001000) << 3); | |
bitsavailable--; | |
break; | |
case 3: | |
AC = AC << 1; | |
AC = AC | ((sirawdata & 0b00010000) << 2); | |
bitsavailable--; | |
break; | |
case 2: | |
AC = AC >> 1; | |
AC = AC | ((sirawdata & 0b00100000) << 1); | |
bitsavailable--; | |
break; | |
case 1: | |
AC = AC >> 1; | |
AC = AC | (sirawdata & 0b01000000); | |
bitsavailable--; | |
break; | |
case 0: | |
AC = 0; | |
break; | |
default: | |
bitsavailable = 0; // wenn Pufferueberlauf Puffer zuruecksetzen und Fehler auf UART ausgeben | |
AC = 0; | |
Serial1.write("ERROR! bitsavailable overflow!\n"); | |
break; | |
} | |
AC = AC & 0b01111111; // oberstes BIT weg-und-en, nur fuer den Fall dass es gesetzt ist | |
return AC; | |
} | |
} | |
// 7 Bits in einem Rutsch holen und zurueckgeben | |
byte Get7Bits() { | |
i = 7; | |
AD = 0; | |
while (i > 0) { | |
AD = GetOneBit(); | |
i--; | |
} | |
return AD; | |
} | |
// Interrupt, wenn fallende Flanke an DatenPin | |
void EventOnInput() | |
{ | |
AB = loopadjust + loopgain; // Verstaerkung draufaddieren | |
loopadjust = AB & 0x00FF; // obere 8 Bit loeschen und zurueckschreiben (aus Ermangelung eines Carry-Flags) | |
if ((AB & 0xFF00) > 0) { // wenn ueber 255, dann nachregeln, sonst nicht | |
if (clock3200 < 16) { // wenn Takt zu langsam | |
clock3200++; // Zaehler vorregeln | |
} else if (clock3200 > 16) { | |
clock3200--; // sonst gegenregeln | |
} | |
} | |
} | |
// 3200kHz Timer Interrupt | |
ISR(TIMER1_COMPA_vect) | |
{ | |
clock3200--; // Clock verkleinern .. es wird Faktor 32 ueberabgetastet | |
if (clock3200 == 0) { | |
InPort = digitalRead(DataPin); | |
/* | |
* wenn auf 490kHz, dann ist 1 und 0 vertauscht | |
* das liegt an der Referenzfrequenz, die bei 518kHz mit 518,4kHz leicht ueber, und | |
* bei 490kHz mit 489,6kHz leicht unter der Traegerfrequenz liegt. | |
* Dadurch wird das Signal invertiert (was man auch ueber eine andere LUT ausbuegeln koennte) | |
* geht auch mit InPort = InPort ^ 1; ... was solls ... | |
*/ | |
if (Frequenz == LOW) { | |
if (InPort == LOW) { | |
InPort = HIGH; | |
} else { | |
InPort = LOW; | |
} | |
} | |
clock3200 = 0b00100000; // Zaehler zuruecksetzen | |
// Daten in Ringpuffer schieben und Zaehler erhoehen. Es konnen 8 Bit zwischengelagert werden (80ms) | |
sirawdata = ((sirawdata >> 1) | (InPort << 7)) & 0b11111111; | |
bitsavailable++; | |
} | |
} | |
// debugroutine, um INT zu binaer-String zu wandeln | |
void tobinstr(int value, int bitsCount, char* output) | |
{ | |
int i; | |
output[bitsCount] = '\0'; | |
for (i = bitsCount - 1; i >= 0; --i, value >>= 1) | |
{ | |
output[i] = (value & 1) + '0'; | |
} | |
} | |
// pruefe, ob sich am Frequenz- oder Zeichensatz-Pin was getan hat | |
void CheckInput() { | |
AA = 0; | |
if (digitalRead(UpperLowerInPin) != UpperLower) { | |
UpperLower = digitalRead(UpperLowerInPin); | |
AA = AA | 0b01; | |
} | |
if (digitalRead(FrequenzInPin) != Frequenz) { | |
Frequenz = digitalRead(FrequenzInPin); | |
AA = AA | 0b10; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See YouTube: "Low-Cost NAVTEX Receiver (selfbuild)" by kuttmoped