Koleżankom i Kolegom Radioamatorom, Krótkofalowcom,
Konstruktorom i Waszym Rodzinom – w tych trudnych czasach –
po dotkliwej awarii naszego forum
Pogodnego czasu po Bożym Narodzeniu,
Dosiego Nowego Roku
oraz Radosnych Trzech Króli

Życzy Zespół Home Made

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Programowanie w języku C w środowisku AVR Studio4
(07-06-2012, 8:57)SP3GTG Wrote: „Własna” synteza z AD 9951 bardzo cieszy, choć
trzeba ją jeszcze rozbudować o różne funkcje niezbędne
w TRx-ie.
Nie ma sprawy tak tez zrobimy. Jednak z obsługą encodera będzie problem gdyż go nie posiadam - jeśli ktoś ma na zbyciu solidny, najlepiej z jakiejś obrabiarki CNC za niewielkie pieniądze to mogę kupić.
Tym razem proponuję opracować "normalne" wyświetlanie częstotliwości - w postaci xxx.xxx.xxx ( np. 3.710.000 ) Oto moja propozycja funkcji wys_freq()
Code:
void wys_freq(unsigned long int freq)
{
    unsigned long int LL, ff, zero;
    LL=0;
    ff=freq;
    LCD_PORT = LCD_PORT|(1<<LCD_RS);

    while(ff >= 100000000)
        {
          ff = ff-100000000;
          LL+=1;
         }
    if (LL!=0)                 //wyťwietl rz?d 100M
        {
          bajt_lcd(LL+48);
          zero=1;
         }
    else
        {
          bajt_lcd(LL+32);
          zero=0;
         }
    LL=0;
    while(ff >= 10000000)
         {
        ff = ff-10000000;
           LL+=1;
         }
    if (LL!=0)                 //wyťwietl rz?d 10M
        {
          bajt_lcd(LL+48);
          zero=1;
         }
    else
         {
          if(zero==0)
              {
               bajt_lcd(32);
               zero=0;
              }
          else
              {
             bajt_lcd(LL+48);
               zero=1;
              }
         }
    LL=0;
    while(ff >= 1000000)
        {
        ff = ff-1000000;
           LL+=1;
         }
    if (LL!=0)             //wyťwietl rz?d 1M
        {
          bajt_lcd(LL+48);
          bajt_lcd(46);
          zero=1;
         }
    else
        {
          if(zero==0)
              {
               bajt_lcd(32);
               bajt_lcd(32);
               zero=0;
              }
          else
              {
            bajt_lcd(LL+48);
            bajt_lcd(46);
            zero=1;
            }
         }
    LL=0;
    while(ff >= 100000)
        {
        ff = ff-100000;
           LL+=1;
         }
    if (LL!=0)                 //100k
        {
        bajt_lcd(LL+48);
        zero=1;
        }
    else
         {
          if(zero==0)
              {
               bajt_lcd(32);
               zero=0;
              }
          else
              {
               bajt_lcd(LL+48);
               zero=1;
              }
         }
    LL=0;
    while(ff >= 10000)
        {
        ff = ff-10000;
           LL+=1;
         }
    if (LL!=0)                 //10k
        {
          bajt_lcd(LL+48);
          zero=1;
         }
    else
        {
          if(zero==0)
              {
               bajt_lcd(32);
               zero=0;
              }
          else
              {
               bajt_lcd(LL+48);
               zero=1;
              }
         }
    LL=0;    
    while(ff >= 1000)
        {
        ff = ff-1000;
           LL+=1;
         }
    if (LL!=0)             //1k
        {
        bajt_lcd(LL+48);
        bajt_lcd(46);
        zero=1;
        }
    else
        {
          if(zero==0)
              {
              bajt_lcd(32);
               bajt_lcd(32);
               zero=0;
              }
          else
              {
               bajt_lcd(LL+48);
               bajt_lcd(46);
               zero=1;
              }
         }
    LL=0;
    while(ff >= 100)
        {
          ff = ff-100;
          LL+=1;
         }
    bajt_lcd(LL+48);                //100
    LL=0;
    while(ff >= 10)
        {
          ff = ff-10;
          LL+=1;
         }
    bajt_lcd(LL+48);                //10
    bajt_lcd(ff+48);                //1
}
Opracowałem ją kiedyś - nie miałem jeszcze na tyle doświadczenia żeby zrobić krótki kod - zresztą to nie ważne ( moim zdaniem) żeby mało było kodu w oknie kompilatora tylko ważne żeby program wykonywał się szybko a ten sposób wyświetlania jest szybszy niż ten który mieliśmy do tej pory.
Z pliku main.c usuwacie całą funkcję wys_freq() i na jej miejsce wsadzacie tą którą podałem w tym poście. Działa - sprawdzałem... lecz ciągle jest coś nie tak Smile i to jest zadanie dla Was:
Jak zrobić żeby częstotliwość nie wychodziła poza wyświetlacz ?? Pogłówkujcie , jeśli nie dacie rady podam rozwiazanie. Podpowiedź: Wystarczy zmienić (tylko) góra dwa znaki.
Reply
Witam
Zadanie zaliczone, plik ze zmianami w załączniku. Nadto zamiast kropki między MHz a setkami kHz jest puste miejsce, co w/g mnie poprawia czytelność czętotliwości.
Pozdrawiam
Andrzej
Reply
Witam
Zadanie rozwiązane, plik w załączniku. Nadto zlikwidowałem kropkę między MHz a
setkami kHz, co w/g mnie poprawia czytelność czętotliwości
Pozdrawiam
Andrzej


Attached Files
.zip   nowy.zip (Size: 1.25 KB / Downloads: 994)
Reply
Well Done Andrzej! Chodziło właśnie o zmianę adresu miejsca na wyświetlaczu, od którego zacznie się "rysowanie" częstotliwości. Czyli zmianę wartosci zaznaczonej na czerwono ( prawie na samym końcu pliku nowy.c ):

LCD_PORT &= (~1<<LCD_RS);
bajt_lcd(0x85);
wys_freq(frequency);

Na miejsce tej wartości powstawiajcie np. 0x83, 0x81, ... itd żeby zobaczyć co to zmienia.
Dobra, mamy "ładne" wyświetlanie częstotliwości teraz przydałoby sie sensowne wyświetlanie kroku - ja do tego wykorzystam pomysł z CB-radia LINCOLN w którym pod cyfrą jedności, dziesiątek, setek , itd ... ustawiany jest kursor. ( np. Jeśli kursor jest pod cyfrą reprezętującą dziesiątki Herców, oznacza to że krok wynośi 10 Hz. )
Wyświetlacz którym sie bawimy może wyświetlać kursor, może być nawet migający. Wykorzystam to, oto gotowiec :
.zip   nowy.zip (Size: 63.5 KB / Downloads: 1,050)
Zwróćnie uwagę ile miejsca zyskaliśmy na wyświetlaczu - można w miejsce wyświetlania kroku wsadzić np. drugą częstotliwość.
Pobawcie się tez opóźnieniem o którym napisałem w środku pliku nowy.c - dostosujcie szybkość zmian częstotliwosci do własnych preferencji.
Acha, zmiana jeszcze jest w pliku lcd_alfanum.c w funkcji:
Code:
void bajt_lcd(unsigned char znak)
{    
    LCD_PORT = (LCD_PORT & 15)|(znak&240);            
    LCD_PORT |= (1<<LCD_E);                 
    LCD_PORT &= (~1<<LCD_E);                 
    LCD_PORT = (LCD_PORT & 15)|(znak<<4);            
    LCD_PORT |= (1<<LCD_E);                 
    LCD_PORT &= (~1<<LCD_E);                 
    _delay_ms(1);             // było _delay_ms(10) czyli 10 ms opóźnienia
}
zmniejszyłem te opóźnienie żeby nie marnować cennego czasu mikrokontrolera.
Reply
Witam
Podobnie o dwa miejsca w lewo, został przesunięty początek "rysowania" kroku,
aby był we właściwym miejscu. Zresztą jest to w pliku zaznaczone, podobnie jak zmiana kropki na puste pole
LCD_PORT &= (~1<<LCD_RS);
bajt_lcd(0xc1); //0xc3
napis_lcd("krok");
wys_freq(krok);
}
Pozdrawiam
Andrzej
może być z kursorem lecz daj do wyboru mrygający i nie

Witam
Napis jest Ok. z tym, że we fragmencie kodu:
_delay_ms(1); // było _delay_ms(10) czyli 10 ms opóźnienia,
opóżnienie zmieniłem na 2 ms, gdyż przy 1ms
po wyłączeniu napięcia zasilania sterownika i ponownym
włączeniu LCD był pusty.
Pozdrawiam
Andrzej

Reply
BArdzo dobrze, klonów tych wyświetlaczy jest dużo, wiele firm to produkuje, jedne są szybsze drugie wolniejsze. Widocznie twój wyświetlacz nie daje sobie rady z tak szybkim sygnałem, jakim ja traktuje swój LCD. Ale fajnie że doszedłeś do tego że trzeba go zwolnić poprzez to opóźnienie.
Reply
Do 7 sierpnia mam dodatkową prace za dobre pieniądze więc wątpię żebym coś tu nabazgrał, więc ... SORRY za tak długa przerwę ...
Reply
Witam wszystkich po długiej przerwie. Przedstawię wam przykład kodu obsługującego przetwornik Analog-Digital.
Wykorzystałem do tego celu ostani projekt syntezy z postu #163
-> http://sp-hm.pl/thread-1161-post-13736.html#pid13736
Zmmieniłem tylko zawartość pliku nowy.c !!!
Wyprowadzenie PA0 jest wejściem naszego ADC. Przetwornik jest 10-bitowy, a więc wartość jaka możemy uzyskać zawiera sie w zakresie 0 - 1023.
I takie wartości będą wyświetlane na LCD. Jeśli odkomentujecie odpowiednią linijkę (zaznaczyłem ją komentarzem) w pliku nowy.c to otrzymacie watrość napięcia czyli wskazania na LCD będą w zakresie 0 - 5V.
Dl tych , którzy wypadli trochę z "obiegu" przypominam, że te dziwne napisy:
ADMUX , ADCSRA, ADCL, ADCH to rejestry na których pracujemy (w tym przypadku rejestru ADC). Ich znaczenie jest wyjaśnione w necie więc nie będę tu tego opisywał. Poprostu wklejam plik z projektem i poeksperymentujcie. Czekam na pytania jeśli ktoś nie rozumie czegoś.


Attached Files
.zip   ADC.zip (Size: 29.71 KB / Downloads: 979)
Reply
(26-01-2012, 19:32)SQ6ADE Wrote: A gdzie R/W w sterowaniu wyświetlacza Smile Smile
Dzięki niemu można więcej....

W związku ze słuszną uwagą Krzyśka zamieszczam biblioteczkę dla tych którzy potrzebują OBSŁUGI LCD z linią RW (dwa pliki .h i .c) :

.zip   nowy-pp.zip (Size: 2.13 KB / Downloads: 1,006)
Oraz "wykastrowany" projekt naszej syntezy (z zawartą już tą biblioteką), który testuje działanie wyświetlacza.
.zip   nowy-pp-test.zip (Size: 32.45 KB / Downloads: 982)
Jedyne co musicie zrobić aby skonfigurować LCD - to wpisać odpowiednie literki portów i symbole wyprowadzeń w plik lcd_alfanum.h ... Poniżej część tego pliku będąca zarazem przykładem
Code:
#define    LCD_Dx_P        D        //wpisujemy, który port ma wysyłać dane do wyświetlacza - 4 starsze bity portu (7,6,5,4) */
                                //podłączamy odpowiednio do wyjść D7, D6, D5, D4 wyświetlacza */

#define    LCD_RS_P        D        //na którym porcie będzie linią RS
#define LCD_RS             PD3        //na którym wyprowadzieniu portu będzie linią RS

#define    LCD_E_P            D        //na którym porcie będzie linia E
#define LCD_E             PD2        //na którym wyprowadzieniu portu będzie linią E

#define    LCD_RW_P        C        //na którym porcie będzie linia RW
#define    LCD_RW            PC2        //na którym wyprowadzieniu portu będzie linią RW
Reply
Wiem że rzadko tu pisuję ale priorytety mi się przestawiły na doskonalenie mojego HOME-MADA wieczorami a nie na siedzenie w AVR-C. Mimo to będę czasami tu pisał i wsadzał przydatne dla początkujących kody. Tym razem coś dla ludzi którzy chcą powalczyć z zapisem i odczytem do pamięci Eprom, która jest na większości płyt ewaluacyjnych wmontowana. Jeśli ktoś ma płytkę bez pamięci może za kilka złotych kupić ośmionóżkowy scalaczek i dokleić go do swojej płytki. Załączam bibliotekę zawierającą jak zwykle pliknagłówkowy .h i źródło w .c . Potrzebna jest znajomość mechanizmu działania magistrali I2C, jeśli ktoś nie wie o czym mowa to niech poszuka w google "jak działa magistrala I2C"...
Zanim zaczniecie używać I2C należy zainicjalizować port TWI w Atmedze funkcją:
Code:
    TWI_init();
Przykład zapisu do pamięci (począwszy od adresu 0x0005) zmiennej freq (czyli 4 bajtów) - np. częstotliwości z naszej syntezy
Code:
    zap_pam(0x0005, freq);
Przykład przypisania zmiennej papparara wartości odczytanej z pamięci (4 bajty) począwszy od komórki o adresie 0x0005
Code:
papparara=odcz_pam(0x0005);
Spróbujcie sami zrobić kod który będzie zapisywał i odczytywał do eprom. Najlepiej dorobić przycisk uruchamiający w naszej syntezie tryb Memory Smile guzikami góra dól (tam gdzie zmieniało się częstotliowość) wykonywać można by zapis i odczyt, a guzikami lewo prawo (tam gdzie zmieniało się krok) można by przeglądać komórki pamięci. Dziś już nie zrobię gotowca. Postaram się wyrobić z tym do końca tygodnia, dodam stosowny kod do naszej syntezy aby to było możliwe. Następnie zaprezentuję Wam obsługę enkodera. Powodzenia. Czekam jak zwykle na pytania od tych jednostek które się zmuszą do działania Wink


Attached Files
.zip   I2c.zip (Size: 1.29 KB / Downloads: 1,101)
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)