HomeMade
Elektroniczne klucze CW w wykonaniu HM - Wersja do druku

+- HomeMade (http://sp-hm.pl)
+-- Dział: Forum Praktyczno-Techniczne HomeMade (/forum-1.html)
+--- Dział: Inne urządzenia HM (/forum-2.html)
+--- Wątek: Elektroniczne klucze CW w wykonaniu HM (/thread-135.html)

Strony: 1 2 3


RE: Elektroniczne klucze CW w wykonaniu HM - SP6RGB - 28-09-2019 18:47

Witam.

Ostatnio złożyłem koledze wracającemu po latach do telegrafii klucz wg opisu powyżej. Przy okazji dodałem funkcję nauki - pseudolosowe znaki nadawane typowo w grupach po pięć znaków.
Może się przyda kod komuś uczącemu się C dla AVR .

73! Robert
Kod:
// main.c
// Created on: 10 sty 2016/poprawki 24.09.2019
// Author: SP6RGB
// Wersja 2.0 z nadawaniem treningowym

//Klucz telegraficzny - wyjscie PB4 na wejście KEY TRX (wymagany dodatkowy tranzystor kluczujacy)
//( w oryginale wyjscie PB4 przez rezystor 6,8kOhm steruje BC547B)
//Podłaczenie klucza do PB0 (kropka) i PB1(kreska)
//Krótkie przyciśnięcie PB3 - ruchomienie nadawania z pamieci / przytrzymanie klawisza PB3 - uruchomienie nadawania treningowego
//Regulacja tempa  potencjometrem podlaczonym do PB2
//Wykorzystany pomysł z nadawaniem z pamieci wg Simon Monk

#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <stdlib.h>

#define PIN_KROPKA  ( 1<<PB0 )              //Wejscie PB0jako przycisk kropek
#define PIN_KRESKA  ( 1<<PB1 )              //Wejscie PB1 jako przycisk kresek
#define PIN_PAMIEC     ( 1<<PB3 )                //Pamiec klucza
#define PIN_KEY      ( 1<<PB4 )                //Wyjscie do sterowania TXa
#define PIN_STOP     ( 1<<PB5 )                //Przycisk STOP nadawania z pamięci (reset procesora)

//Deklaracje funkcji

void kropkiNadawanie( uint16_t tempoF );
void kreskiNadawanie( uint16_t tempoF );
void zmienneDelay( uint16_t tempoF );
void nadajPamiec( void );
void znakNaMorse( char ch );
void nadajZnak( char* ktoryZnak );
void nadajKropkaLubKreska( char kropkaLubKreska );
void nadajNauka ( void );
uint16_t czytajTempo( void );

//Deklaracje zmiennych

uint16_t  tempo;                              //Zmienna globalna do ustawiania tempa nadawania
                                            //Im wieksza tym wolniejsze nadawanie
char* litery[]  =                           //Deklaracja liter Morse'a
{ ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",    // A-I Tylko duze litery do nadawanie z pamieci.
  ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.",  // J-R
  "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.." };         // S-Z
char* numery[] =                               //Deklaracja liczb Morse'a
{ "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----." };
char* symbole[] = { "-..-.", "..--.." };     //Tylko dwa symbole "/" i "?" - wiecej sie w praktyce nie uzywa, a nie sa po kolei w ASCII jak dla liter i cyfr i nie mozna analogicznie wybierac
const char trening_P[] PROGMEM = "ABCDEFGHIJKLMNOPQRSTUWVXYZ01234567890/?"; //Tablica do nadawnia przy nauce - 39 znaków
const char pamiec_P[] PROGMEM = "CQ CQ CQ DE SP0XXX SP0XXX SP0XXX CQ CQ CQ DE SP0XXX SP0XXX SP0XXX PSE K"; //Tekst dowolny - DUZE LITERY!!!


int main ( void )
{
  DDRB     &= ~(PIN_KROPKA | PIN_KRESKA | PIN_PAMIEC | PIN_STOP);        //Ustawienie wejsc
  DDRB     |=  PIN_KEY;                                                   //Ustawienie wyjsc
  PORTB |= PIN_KROPKA | PIN_KRESKA | PIN_PAMIEC | PIN_STOP;          //Podciagniecie wejsc
  ADCSRA |= (1<<ADEN);                                                //Zalaczenie przetwornika ADC
  ADMUX  |= (1<<ADLAR)| (1<<MUX0);                                    //Ustawienie prezentacji wyniku od lewej i wejscia PB2
  ADMUX &= ~((1<<REFS0) | (1<<REFS1) | (1<<REFS2));                 //Napiecie odniesienia rowne Vcc

  while( 1 )
  {
      czytajTempo();
      if (!(PINB & PIN_KROPKA))        kropkiNadawanie( tempo );     //Nacisniety pin kropki to kropkiNadawanie
      if (!(PINB & PIN_KRESKA))        kreskiNadawanie( tempo );     //Nacisniety pin kreski to kreskiNadawanie
      if (!(PINB & PIN_PAMIEC))                                    //Nacisniety krótko przycisk PAMIEĆ - nadawanie tekstu z pamięci
      {
          _delay_ms(100);                                        //Przytrzymany chwilę przycisk PAMIEC - nadawanie treningowe losowego tekstu
          if (!(PINB &PIN_PAMIEC))
              nadajNauka();
          else
              nadajPamiec();
      }
  }
}

//Definicje funkcji

void kropkiNadawanie( uint16_t tempoF )
{
    PORTB |= PIN_KEY;                          //Zalaczenie sterowania TRX
    zmienneDelay( tempoF );                 //na czas okreslony przez zmienna tempo
    PORTB &= ~PIN_KEY;
    zmienneDelay( tempoF );                    //czas pomiedzy znakami równy kropce
}

void kreskiNadawanie( uint16_t tempoF )
{
    PORTB |= PIN_KEY;
    zmienneDelay( tempoF*3 );                  //Kreska równa trzem kropkom
    PORTB &= ~PIN_KEY;
    zmienneDelay( tempoF );                    //Przerwa miedzy kreskami rowna kropce
}

void zmienneDelay( uint16_t tempoF )
{
    while( tempoF-- )  _delay_us( 700 );
}

uint16_t czytajTempo( void )                    //uint16_t bo wynik jest mnozony przez 3 i przekracza uint8_t
{                                                //chociaz odczytujemy tylko 8 bitow z ADCH
    ADCSRA |= ( 1<<ADSC );                        //Wyzwolenie jednorazowej konwersji
    while((ADCSRA & ( 1<<ADSC )));                //Oczekiwanie na koniec pomniaru
    tempo = ADCH + 1;                             //Wynik odczytwywany z rejestru ADCH plus 1 (zeby nie bylo 0)
    return tempo;
}

void nadajPamiec( void )                        //Funkcja wysylania danych z pamieci - dane okreslone w tablicach char Memory
{
    int i = 0;
    char ch;
    while (pgm_read_byte(&pamiec_P[i]))            //Petla az do napotkania w lancuchu "\0"
    {
        ch = (pgm_read_byte(&pamiec_P[i++]));    //Wyodrebnienie z tabeli pamiec_P kolejnego znaku do wyslania znakowi do wyslania
        znakNaMorse( ch );                          //Funkcja przeksztalcajaca znak z tabeli "pamiec_P" w grupe "." i "-" do wyslania
    }
}

void znakNaMorse( char ch )                      //Funkcja do wybrania wlasciwej z tabeli litery lub cyfry
{

    if (ch >= 'A' && ch <= 'Z')                  //Jezeli znak miesci sie pomiedzy A a Z to tabela liter
    {
      nadajZnak( litery[ch - 'A'] );             //Wywolanie funkcji wysylajacej wlasciwy znak. Znaki w tabeli opisane w kodzie ASCII podlegaja porownywaniu jak w operacjach
    }                                            //matematycznych. Kod ASCII(ch) - kod ASCII(A) da nam pozycje grupy w " " z tabeli letters do wyslania. Np A-A=0 czyli pierwsza grupa z tablicy.
    else if ( ch >= '0' && ch <= '9' )           //Jezeli znak miesci sie pomiedzy 0 a 9 to tabela cyfr (numbers)
    {
      nadajZnak(numery[ ch - '0'] );             //Tak samo jak dla liter
    }
    else if ( ch == '/' )
    {
      nadajZnak(symbole[0]);
    }
    else if( ch == '?' )
    {
      nadajZnak(symbole[1]);
    }
    else if ( ch == ' ' )                        //Jezeli pobrana zostala z tablicy pamiec_P spacja to generujemy przerwe miedzy slowami rowna dlugosci 4 kropek
    {
    zmienneDelay(tempo * 4);
    }
}

void nadajZnak( char *ktoryZnak )                     //Z tabeli char* [] pobrana zostaje grupa znaków w " " z pozycji okreslonej przez funkcje znakNaMorse
{
    int i = 0;
    while( ktoryZnak[i] )                           //Pobiera kropki i kreski, az natrafi na znak konca lancucha
    {
        nadajKropkaLubKreska( ktoryZnak[i++] );     //Pobrana kropka lub kreska przekazana jest do funkcji generujacej kropki lub kreski
        czytajTempo();                                //W każdej chwili można zmienić tempo nadawania potencjometrem
    }
    zmienneDelay( tempo * 3 );                      //Po NULL jest nowy znak i bedzie pobrana kolejna grupa kropek i kresek. Przerwa pomiedzy znakami rowna trzem kropkom
}

void nadajKropkaLubKreska( char kropkaLubKreska )     //Prosta funkcja identyfikujaca czy przekazano do niej kropke czy kreske i je wysylajaca
{
  if ( kropkaLubKreska == '.' )
  {
      kropkiNadawanie( tempo );                       //Uzyte do generowania kropek i kresek te same funkcje co wyzej
  }
  else
  {
      kreskiNadawanie( tempo );
  }
}

void nadajNauka ( void )
{
    char ch;
    uint8_t i, j;
    srand( tempo );                                //W celu utrzymnania losowości znaków należy zmieniac tempo (pokęcic potencjometrem) przed kolejnmy uruchomieniem nauki
    while( 1 )                                    //i dopasowac tempo do swoich preferencji po uruchomieniu. srand() ustawia dane wejsciowe do generatora liczb pseudolosowych na podstawie wartości tempo.
    {                                            //wywoływanego przez funkcję rand() - generator liczb pseudolosowych nie jest dobry, ale dla tych potrzeb wystarczający.
        for (j = 0; j < 5; j++)                    //nadajemy w grupach po 5 znaków
        {
            i = rand()%38;                        //pseudolosowy wybór liczby od 0 do 38
            ch = pgm_read_byte(&trening_P[i]);    //odczyt losowego znaku z tablicy trening_P[]
            znakNaMorse( ch );                    //nadanie wybranego znaku
        }
        zmienneDelay(tempo * 4);                //spacja - przerwa między grupami równa 4 kropkom
    }
}