/***************************************************************************/ /* DB0HGW - RepeaterControl */ /* Autor/s: S. HUEBNER */ /* Date : 05-27-01 */ /***************************************************************************/ /* V1.03 : 07-01-01 : Basisversion, Ruftonerkennung, Squelchauswertung, /* CW-Tonerzeugung, Bake /* 07-04-01 : Wait1750Hz() while(!IN_RUFTON) Warten bis Ende /* Rufton /* 08-06-01 : Frequenzteiler fuer CW - Ton, wieder raus /* 09-24-01 : Implementierung KanalMonitor fuer APRS : RX Siganl (IN_SQL) ODER Relais aktiv (OUT_PTT==0) : bewirken setzen ein Low am P1_5 10-30-01 : KanalMonitor Boolsche Verknuepfung war falsch, be- richtigt und nun ausserhalb der Interruptpolling- funktion 01-07-02 : jetzt Rogerbeep beim Oeffnen des Relais */ #pragma CODE #pragma DEBUG #pragma SYMBOLS #pragma LISTINCLUDE #pragma SMALL #include #ifdef ___80552___ #include "d:\8051\8051c\incl\reg552.h" #else #include "d:\8051\8051c\incl\reg51.h" #endif /* * The following functions are called from the interrupt service routine. This * means that the code must be generated in the same Register Bank as the * interrupt service function. */ /******************************************************************************/ /* Timer0InterruptService */ /******************************************************************************/ Timer0() interrupt 1 using 0 /* Int Vector at 000BH, Reg Bank 0 */ { /* simply toggling port 1 bit4 */ if(Main_bCW) OUT_TON = ~OUT_TON; }/* Timer0 */ /******************************************************************************/ /* Timer1InterruptService */ /******************************************************************************/ Timer1() interrupt 3 using 0 /* Int Vector at 001BH, Reg Bank 0 */ { Main_bT1Int |= 1; if(ps->bCWSpeed) ps->bCWSpeed--; TH1 = 0x30; }/* Timer1 */ /******************************************************************************/ /*************************** MAIN PROGRAM ***************************/ /******************************************************************************/ void Main() { BYTE bNull = 0; BYTE bState = 1; Main_bT1Int &= bNull; /* 7 6 5 4 3 2 1 0 */ PCON &= bNull; /* SMOD - - WLE GF1 GF0 PD IDL */ /* RS1 und RS0 (Registerbank-Selektierung) */ PSW &= bNull; /* InterruptPrioritaet */ #ifdef ___80552___ IP0 &= bNull; #else IP &= bNull; #endif /* Timer0Int hat hoechste Prioritaet, sonst ist der CW-Ton unsauber ! */ PT0 = 1; /* Ports */ P1 &= 0x07; // PIN 1_0, PIN 1_1 und 1_2 auf H P3 &= bNull; /* Initialisierung der globalen Timer1 Elemente */ Init(); ps->wBeaconIntervall = 0; ps->b1750HzSQLWindow = 0; /* generelle Freigabe nur Timer0/1 */ #ifdef ___80552___ IEN0 = 0x8A; IEN1 &= bNull; #else IE = 0x8A; #endif /* Timer0/1-Initialisierung */ TMOD = 0x12; /* Mode 1 fuer Timer1, Mode 2 fuer Timer0 */ TCON &= bNull; Main_bCW = bNull; Main_bOLD_SQL = 1; /* Reload value fuer Timer0; Tonfrequenz */ TH0 = bNull; /* 65ms */ TR1 = 1; /* Timer 1 starten */ /* Scheduler */ while(1) { /* Kanalmonitor */ /* for APRS purpose */ if(OUT_PTT) { /* only if repeater not activ */ if(!IN_SQL) { /* set if signal */ OUT_MONITOR &= bNull; ps->bAPRS |= APRS_DEBOUNCING; } } if(Main_bT1Int) { /* Interruptbearbeitung */ /* Decrementieren aller TimerZaehler */ if((ps->b1750Duration) && (!IN_RUFTON)) ps->b1750Duration--; if(ps->b1750HzSQLWindow) ps->b1750HzSQLWindow--; if(ps->bPTTOn) ps->bPTTOn--; if(ps->wBeaconIntervall) ps->wBeaconIntervall--; if(ps->bAPRS) ps->bAPRS--; /* sign of life */ OUT_CTRL = ~OUT_CTRL; Main_bT1Int &= bNull; /* Kanalmonitor */ /* for APRS purpose */ if(OUT_PTT && IN_SQL) { /* reset if no signal */ if(!(ps->bAPRS)) OUT_MONITOR |= 1; } if(bState & STATE_1750HZ) { if(Wait1750Hz()) { /* APRS blockieren */ OUT_MONITOR &= bNull; /* Sender ein */ OUT_PTT = bNull; /* falls das Relais innerhalb von BEACON_LOCK_TIME geoeffnet wird */ if(ps->wBeaconIntervall) { ps->wBeaconIntervall = BEACON_INTERVALL; } else { /* die Funktion Beacon() wird nach dem PTT ON (Sender ein) fuer die Ausgabe der verzoegerten Ausgabe der Kennung "missbraucht" und mit einem "speziellen" Timerwert geladen und die Funktion Squelch() wird bereits nach PTT ON aktiviert */ ps->wBeaconIntervall = PTT_ON_DURATION - 0x1F; } ps->bPTTOn=PTT_ON_DURATION; bState |= (WAIT_SQUELCH + WAIT_BEACON + PTT_OFF); bState &= ~STATE_1750HZ; Kennung(1,1); } } if(bState & WAIT_SQUELCH) { if(Squelch()) { /* Rauschsperre war offen */ /* Beep senden */ Kennung(1,1); } } if(bState & WAIT_BEACON) { if(!ps->wBeaconIntervall) { /* Kennungsbake */ TH0 = FREQ; Kennung(BULLETIN_LENGTH,bNull); TH0 = bNull; Init(); bState |= PTT_OFF; } } if(bState & PTT_OFF) { if(!ps->bPTTOn) { /* PTT - Haltezeit ist abgelaufen, Sender aus */ OUT_PTT = 1; /* Initialisierung der globalen Timer1 Elemente */ Init(); /* Bakenkennung wird erst nach einer Bakensperrzeit nach dem Oeffnen ernaut gesendet, damit man die Kennung nicht zu oft hoeren muss */ ps->wBeaconIntervall = BEACON_LOCK_TIME; /* nur Ruftonerkennung aktiv */ bState = STATE_1750HZ; } } } }/* while */ } /* Main */ /****************************************************************************/ /* Kennung */ /****************************************************************************/ void Kennung(BYTE bLength, BYTE bFlag) { BYTE bBitC = 0; BYTE bByteC = bLength; /* damit erstes Zeichen auch korrekte Laenge hat */ ps->bCWSpeed = CW_SPEED; /* Tongenerator an */ TR0 = 1; while(bByteC) { /* solange der Inhalt des Bulletins noch nicht vollst. gesendet wurde */ if(!ps->bCWSpeed) { /* Timer ist abgelaufen */ ps->bCWSpeed = CW_SPEED; if(bBitC == 7) { /* Byteende erreicht, naechstes Byte senden */ bBitC = 0; bByteC--; } else { bBitC++; } if(!bFlag) { Main_bCW = ((Main_rgbCWZeichen[bLength - bByteC] >> bBitC) & 0x01); } else { Main_bCW = (BEEP_CHARACTER >> bBitC) & 0x01; } } else { /* Timer noch nicht abgelaufen */ /* weiter warten */ } } /* Tongenerator aus */ TR0 = 0; return; }/* Kennung */ /****************************************************************************/ /* WAIT_FOR_1750HZ */ /****************************************************************************/ BYTE Wait1750Hz() { /* RUFTON - TTLeingang muss softwaremaessig nicht entprellt werden, da die Schalthysterese des NE567 hinreichend gross ist */ if(!IN_RUFTON) { if(!ps->b1750Duration ) { if(!ps->b1750HzSQLWindow) { /* Anfangsbedingung, Messung starten */ ps->b1750Duration = DURATION_1750HZ; ps->b1750HzSQLWindow = WINDOW_1750HZ; } else { /* o.k. Endebedingung, 1750Hz war innerhalb des Zeitfensters hinreichend lange present */ ps->b1750Duration = 0; ps->b1750HzSQLWindow = 0; /* es wird gewartet bis Ende Rufton */ while(!IN_RUFTON); return(STATUS_ACTIV); } } } else { /* ist das Zeitfenster ueberschritten worden */ if(!ps->b1750HzSQLWindow) { /* Zeitfenster fuer die Auswertung der 1750Hz wurde bereits ueberschritten, Messung stoppen, neu anfangen */ ps->b1750Duration = 0; } } return(STATUS_INACTIV); }/* Wait1750Hz */ /****************************************************************************/ /* Squelch */ /****************************************************************************/ BYTE Squelch() { if(!IN_SQL) { /* SQL ist offen */ if(Main_bOLD_SQL) { /* H/L - Flanke erkannt, SQL ging gerade auf */ Main_bOLD_SQL = 0; ps->b1750HzSQLWindow = MAX_SQL_DURATION; } else { /* SQL ist immer noch offen */ if(!ps->b1750HzSQLWindow) { /* Timerwert fuer PTT wieder nachladen */ ps->bPTTOn = PTT_ON_DURATION; /* moeglicherweise hier noch mal den Zeitwert nachladen */ //ps->b1750HzSQLWindow = MAX_SQL_DURATION nicht mit MAX_SQL_DURATION, ist zu lang ; } } } else { /* SQL ist zu */ if(!Main_bOLD_SQL) { /* ging gerade zu */ Main_bOLD_SQL = 1; if(!ps->b1750HzSQLWindow) { /* nur wenn SQL lange genug offen war */ ps->bPTTOn = PTT_ON_DURATION; /* L/H - Flanke erkannt */ return(SQUELCH_CLOSE); } } } return(SQUELCH_OPEN); } /* Squelch */ /****************************************************************************/ /* Init */ /****************************************************************************/ void Init() { ps->b1750Duration=DURATION_1750HZ; //ps->b1750HzSQLWindow=MAX_SQL_DURATION; ps->bCWSpeed=CW_SPEED; ps->bPTTOn=PTT_ON_DURATION; ps->wBeaconIntervall=BEACON_INTERVALL; ps->bAPRS = APRS_DEBOUNCING; }/* Init */