Witam.
Ostatnio w innym dziale prosiłem o pomoc przy prostym kluczu telegraficznym. Klucz już skończony i sprawdzony praktycznie - będzie wykorzystany w mojej Librze. Ponieważ miał być bardzo prosty został zrobiony na 8-nóżkowym ATTiny45 ze zmianą tempa potencjometrem. Wyjście PB3 przez 12kOhm steruje tranzystor kluczujący BC547B. Jest tylko jedna pamięć zapisana na stałe na etapie programowania, bo jakoś nie przywykłem wykorzystywać pamięci klucza. Ale bardzo łatwo można zwiększyć ilość pamięci. Poniżej kod dla chętnych do pobawienia się nim. Pewnie można prościej
, ale dopiero zaczynam zabawę w C/C++.
Pozdrawiam.
Kod:
// main.c
// Created on: 10 sty 2016
// Author: SP6RGB
//Klucz telegraficzny - wyjscie PB4 na wejście KEY TRX
//Podłaczenie klucza do PB0 (kropka) i PB1(kreska)
//Uruchomienie nadawania z pamieci PB3
//Regulacja tempa potencjometrem podlaczonym do PB2
//Wykorzystany pomysł z nadawaniem z pamieci wg Simon Monk
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <avr/pgmspace.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 ) //Wyjscie do sterowania TXa
#define PIN_KEY ( 1<<PB4 ) //Pamiec klucza
//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 );
uint16_t czytajTempo( void );
uint16_t tempo = 80; //Zmienna do ustawiania tempa nadawania
//Im wieksza tym wolniejsze nadawanie
char* litery[] = //Deklaracja liter Morse'a
{
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", // A-I Tylko duze litery bo nadawanie z pamieci.
".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", // J-R
"...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.." // S-Z
};
char* numery[] = //Deklaracja liczb Morse'a
{
"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."
};
char* symbole[] = {"-..-.", "..--.."}; //Tylko dwa symbole "/" i "?" - wiecej sie nie uzywa, a nie sa po kolei ASCII jak dla liter i cyfr i nie mozna analogicznie wybierac
const char pamiec_P[] PROGMEM = "CQ CQ CQ DE SP6RGB SP6RGB SP6RGB CQ CQ CQ DE SP6RGB SP6RGB SP6RGB PSE K";
int main ( void )
{
DDRB &= ~(PIN_KROPKA | PIN_KRESKA | PIN_PAMIEC); //Ustawienie wejsc
DDRB |= PIN_KEY; //Ustawienie wyjsc
PORTB |= PIN_KROPKA | PIN_KRESKA | PIN_PAMIEC; //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)) nadajPamiec(); //Nacisniety pin pamiec to nadaj pamiec
}
}
//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
{
int dlugoscPamieci; //Zmienna lokalna do okreslenia dlugosci tablicy
static char ch; //Zmienna lokalna statyczna do "wyjecia" znaku z tablicy
dlugoscPamieci = __strlen_P( pamiec_P ); //Funkcja wbudowana __strlen_P zwraca dlugosc tabeli
for(int i = 0; i < dlugoscPamieci; i++)
{
ch = (char)(pgm_read_byte(&pamiec_P[i]));//Wyodrebnienie z tabeli Memory* kolejnego znaku do wyslania znakowi do wyslania
znakNaMorse( ch ); //Funkcja przeksztalcajaca znak z tabeli "pamiec" 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 litery
{
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 llitery 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 cyfry
{
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] != NULL ) //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
i++; //Kolejna kropka lub kreska, az do NULL
}
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 ja wysylajaca
{
if ( kropkaLubKreska == '.' )
{
kropkiNadawanie( tempo ); //Uzyte do generowania kropek i kresek te same funkcje co wyzej
}
else
{
kreskiNadawanie( tempo );
}
}