HomeMade

Pełna wersja: Programowanie w języku C w środowisku AVR Studio4
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Stron: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
(07-06-2012 9:57)SP3GTG napisał(a): [ -> ]„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()
Kod:
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.
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
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 : [attachment=5416]
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:
Kod:
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.
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
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.
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ę ...
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ś.
(26-01-2012 20:32)SQ6ADE napisał(a): [ -> ]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) :
[attachment=5955]
Oraz "wykastrowany" projekt naszej syntezy (z zawartą już tą biblioteką), który testuje działanie wyświetlacza. [attachment=5956]
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
Kod:
#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
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ą:
Kod:
    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
Kod:
    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
Kod:
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
Powoli będę robił kod obsługujący przycisk, który dodamy - nazwę go Memory/VFO - będzie zmieniał tryb pracy syntezy z VFO na Memory i odwrotnie. Podłączyc go należy pod wyprowadzenie PA3 i masę (podobnie jak poprzednie przyciski).
Najpierw jednak zrobię trochę porządku w dotychczasowym programie - przełożę funkcję wyświetlającą częstotliwość z pliku głównego programu do pliku-biblioteki obsługi LCD.
Co zatem zrobiłem:
1. Wziąłem projekt z postu #163.
2. Zmieniłem zawartość plików : nowy.c , lcd_alfanum.c , lcd_alfanum.h - zobaczcie co się zmieniło przy przenoszeniu codu funkcji "wys_freq".
3. poprawiłem wartość opóźnienia o którym wspomniał SP3GTG w poście #164 - zamiast 1ms opóźnienia są teraz 3ms (choć SP3GTG napisał że działa z 2ms opóźnienia, ale dałem 1ms więcej na zapas gdyby ktoś miał wolniejszy wyświetlacz)
4. skopiowałem obydwa pliki do obsługi Pamięci przez magistralę I2C do katalogu projektu - jeszcze z nich nie korzystam ale wsadziłem je tam żeby już były gotowe do następnego zabiegu
[attachment=6265]

... Doklepałem trochę kodu który ma zmieniać tryb z VFO na Memory i na odwrót, gdy podamy stan niski na PA3.... i teraz wygląda to tak:
[attachment=6266]
Nie mogę tego kodu teraz sprawdzić pod kontem poprawności działania gdyż nie mam teraz dostępu do swojej płyty ewaluacyjnej ... jeśli ktoś może to proszę o sprawdzenie i napisanie czy jest OK. Ja to sprawdzę dopiero w weekend.
Jak zwykle czekam na pytania, choć widzę że zainteresowanie jest niewielkie Wink
Stron: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Przekierowanie