top of page

Budwa transceivera CW, SSB na pasma 50MHz i 70MHz w oparciu o układy Atmega i Cypress oraz programowanie w języku C

Kilka lat temu z nudów zbudowaÅ‚em sobie maÅ‚y prosty transceiver pracujÄ…cy wyÅ‚Ä…cznie na paÅ›mie 50MHz. PomysÅ‚ zbudowania takiego urzÄ…dzenia narodziÅ‚ siÄ™ kiedy staÅ‚em siÄ™ posiadaczem kultowego transceivera FT-1000 MK-V.

Ponieważ FT-1000 nie posiadał właśnie tego pasma, a ja już zasmakowałem w pracy na tej magicznej częstotliwości.

Transceiver który sobie zbudowaÅ‚em to byÅ‚a klasyczna superheterodyna  z podwójnÄ… przemianÄ… czÄ™stotliwoÅ›ci, która pracowaÅ‚a wyÅ‚Ä…cznie emisjami SSB i CW z mocÄ… okoÅ‚o 5W doprowadzonÄ… do anteny. Do budowy urzÄ…dzenia użyÅ‚em filtrów drabinkowych które też sam poskÅ‚adaÅ‚em. Pierwsza przemiana 40MHz na jednym filtre czterokwarcowym i druga przemiana 8MHz na dwóch filtrach oÅ›miokwarcowych. Radio pracowaÅ‚o tylko na górnej wstÄ™dze, a jako VFO użyÅ‚em ukÅ‚adu PLL z mieszaniem czÄ™stotliwoÅ›ci.

Transceiver pracowaÅ‚ bardzo fajnie jednak przepadÅ‚ mi po tym jak pożyczyÅ‚em go jednemu z kolegów który chciaÅ‚ sobie odwzorować to radio. 

​

Teraz kiedy podniosÅ‚em trochÄ™ swojÄ… wiedzÄ™ na temat programowania mikrokontrolerów, przyszedÅ‚ mi pomysÅ‚ zbudowania sobie nowego urzÄ…dzenia o nieco poszerzonym zakresie pracy. ChcÄ™ mieć transceiver który pozwoli mi na swobodnÄ… pracÄ™ na pasmach 50MHz oraz 70MHz emisjami SSB i CW (nie mam w zamiarze używać modulacji FM).

Być może jeżeli nowa konstrukcja okaże się udana, posłużę się nim jako bazą do dobudowania innych pasm.

Na poczÄ…tku jednak skupiam siÄ™  na na podstawowych zaÅ‚ożeniach, czyli pasma 6m i 4m w wykonaniu moduÅ‚owym, co pozwoli mi na ewentualne rozbudowy. 

​

Podstawowe założenia to:

-Podwójna przemiana czÄ™stotliwoÅ›ci 1 P.CZ 38MHz  i 2 P.CZ 8MHz.

SyngaÅ‚ SSB formowany na 8MHz. / filtry kwarcowe w ukÅ‚adzie drabinkowym z ogólnie dostÄ™pnych rezonatorów kwarcowych które można kupować tanio w dowolnych iloÅ›ciach.

 

-UrzÄ…dzenie sterowane mikrokontrolerem z rodziny Cypress Psoc CY8C5888LTI-LP

​

-Jako wspomagajÄ…cy mikroprocesor Atmega 32 lub 128 , jeszcze nie zdecydowaÅ‚em i w chwili obecnej pracujÄ™ nad oprogramowaniem na wszystkie te ukÅ‚ady. Możliwe że w wersji koÅ„cowej zastosujÄ™ wyÅ‚Ä…cznie ukÅ‚ady Cypress jeżeli uda mi siÄ™ opracować software optymalny na ten mikroprocesor. 

​

-Jako wyÅ›wietlacz użyjÄ™ HX8357B sterowany magistralÄ… równolegÅ‚Ä… 16bit. 

-jako VFO oraz generatory fali noÅ›nej użyjÄ™ popularnych ukÅ‚adów DDS AD8951 które w prosty sposób można obsÅ‚użyć sterujÄ…c za pomocÄ… interfejsu SPI zarówno przez ukÅ‚ady Atmega jak i Psoc z rdzeniem ARM.

​

Ponieważ caÅ‚y czas pracujÄ™ nad prototypem transceivera oraz jego oprogramowaniem, sukcesywnie bÄ™dÄ™ dzieliÅ‚ siÄ™ postÄ™pami w pracy i przedstawiaÅ‚ poszczególne moduÅ‚y urzÄ…dzenia wraz z opisem oprogramowania.

ChcÄ™ zaznaczyć że piszÄ™ oprogramowanie wyÅ‚Ä…cznie w jÄ™zyku C. Biblioteki użyte do konstruowania moduÅ‚ów, sÄ… albo napisane w caÅ‚oÅ›ci przeze mnie, albo sÄ… przeze mnie modyfikowane z dostÄ™pnych w sieci bibliotek udostÄ™pnianych przez użytkowników gÅ‚ównie w jÄ™zyku C++ dla Arduino.

Ponieważ nie znam jÄ™zyka C++ ani Arduino, biblioteki te sÅ‚użą mi wyÅ‚Ä…cznie jako wspomaganie dla kodów które staram siÄ™ sam opracować w jÄ™zyku C. Nie jestem programistÄ… dla tego też materiaÅ‚y zaczerpniÄ™te z innych rozwiÄ…zaÅ„ sÄ… dla mnie dużą pomocÄ…. Każde zapożyczenie bÄ™dzie opatrzone stosownym komentarzem w programie źródÅ‚owym z zawartÄ… tam informacjÄ… o jego pochodzeniu.

  

​

​

​

AD9850 oraz AD9851  DDS -  Syntezery czÄ™stotliwoÅ›ci do ukÅ‚adów VFO, BFO 

​

​

Jako pierwsze opiszÄ™ ukÅ‚ady bardzo popularnych, prostych w obsÅ‚udze i niezwykle użytecznych syntezerów DDS AD9850 i AD9851. Oba ukÅ‚ady różniÄ… siÄ™ miedzy sobÄ… zakresem generowanych czÄ™stotliwoÅ›ci oraz czÄ™stotliwoÅ›ciÄ… generatora wzorca. Wyprowadzenia i sposób sterowania obu ukÅ‚adów sÄ… dokÅ‚adnie takie same z jednÄ… maÅ‚Ä… różnicÄ… w sÅ‚owie konfiguracyjnym. Oprogramowanie jakie później przedstawiÄ™, bÄ™dzie uniwersalne dla obu ukÅ‚adów z zaznaczonÄ… różnicÄ… którÄ… należy zmienić w przypadku użycia jednego bÄ…dź drugiego ukÅ‚adu.  

AD9850 - graniczna czÄ™stotliwość jakÄ… wedÅ‚ug noty katalogowej może wygenerować ten ukÅ‚ad to 50MHz, natomiast czÄ™stotliwość taktowania tego ukÅ‚adu to 125MHz. i taki też generator 125MHz jest używany przy tym module.

AD9851 - graniczna czÄ™stotliwość jakÄ… wedÅ‚ug noty katalogowej może wygenerować ten ukÅ‚ad to 70MHz, natomiast czÄ™stotliwość taktowania tego ukÅ‚adu to 180MHz. Generator czÄ™stotliwoÅ›ci wzorca użyty do tego ukÅ‚ady to 30MHz i ta czÄ™stotliwość jest mnożona wewnÄ…trz ukÅ‚adu AD9851 razy 6 co daje czÄ™stotliwość taktowania 180MHz.

Mnożnik czÄ™stotliwoÅ›ci razy 6 wÅ‚Ä…czany jest programowo za pomocÄ… bitu konfiguracyjnego w ramce sterujÄ…cej. Wszystko opiszÄ™ dokÅ‚adniej przy okazji omawiania oprogramowania dla tego moduÅ‚u. Zaznaczam że domyÅ›lnie w moduÅ‚ach AD9851, mnożnik zegara jest wyÅ‚Ä…czony, jeżeli o tym zapomnimy, nasz ukÅ‚ad bÄ™dzie generowaÅ‚ znacznie niższe czÄ™stotliwoÅ›ci od oczekiwanych.

​

Dla uproszczenia i oszczÄ™dnoÅ›ci pinów mikroprocesora sterujÄ…cego ukÅ‚adami AD985X, bÄ™dziemy je sterować za pomocÄ… magistrali SPI. 

​

Ja dla oszczÄ™dnoÅ›ci i uÅ‚atwienia pracy, zaopatrzyÅ‚em siÄ™ w gotowe moduÅ‚y z ukÅ‚adami AD9851 które sÄ… dostÄ™pne w sprzedaży internetowej już zmontowane i gotowe do użycia. W dodatku czÄ™sto jest tak że zmontowany moduÅ‚ z AD9851 na pokÅ‚adzie , jest taÅ„szy od samego ukÅ‚adu scalonego. UżywaÅ‚em kilku moduÅ‚ów z różnych źródeÅ‚ i nigdy nie miaÅ‚em z nimi problemu. Co prawda nie kupowaÅ‚em ich z najtaÅ„szych źródeÅ‚, tylko od sprawdzonych dostawców.

​

Moduły jakich ja użyłem wyglądają tak

Moduły przygotowane są do pracy z napięciem 5V i zaopatrzone są we wszystkie niezbędne wyprowadzenia.

podczas zabaw z tymi moduÅ‚ami, zauważyÅ‚em że pracujÄ… one wyżej niż graniczna czÄ™stotliwość podana w nocie katalogowej, lecz im bliżej czÄ™stotliwoÅ›ci granicznej, tym na sygnale pojawia siÄ™ wiÄ™cej pasożytów. Na pewno spowodowane jest to miÄ™dzy innymi raczej przeciÄ™tnej jakoÅ›ci filtrem dolnoprzepustowym  który jest umieszczony na module. W naszym przypadku jednak, moduÅ‚ który zastosujemy do VFO, nie bÄ™dzie pracowaÅ‚ wyżej niż 35MHz.

Przy czÄ™stotliwoÅ›ci pierwszej P.CZ 38MHz, dla pracy na zakresie czÄ™stotliwoÅ›ci 70 do 73MHz, do mieszacza musimy dostarczyć czÄ™stotliwość 32 do 35MHz (70-38 = 32,   73-38 = 35MHz ). Zatem z powodzeniem możemy zastosować moduÅ‚ DDS z ukÅ‚adem AD9850 którego graniczna czÄ™stotliwość pracy wynosi 50MHz, jednak wÅ‚aÅ›nie do VFO ja preferujÄ™ użyć AD9851 aby w razie potrzeby poszerzyć docelowy zakres pracy....  a także ze wzglÄ™du na mniejszÄ… ilość "Å›mieci" jakie generuje ukÅ‚ad AD9851 pracujÄ…cy znacznie poniżej swojej czÄ™stotliwoÅ›ci granicznej.

Tańsze moduły AD9850 możemy użyć sobie w generatorach fali nośnej albo w generatorze przemiany dla 2 P.CZ

​

Aby nasz moduÅ‚ wydaÅ‚ z siebie Å‚adnÄ… sinusoidÄ™ o żądanej przez nas czÄ™stotliwoÅ›ci, musimy wysÅ‚ać do niego poprzez interfejs SPI sÅ‚owo w którym zawarte bÄ™dÄ… informacje o czÄ™stotliwoÅ›ci jakÄ… chcemy uzyskać, oraz dane konfiguracyjne. DokÅ‚adne informacje można znaleźć w notach katalogowych naszych ukÅ‚adów. Ja ograniczÄ™ siÄ™ do przedstawienia skondensowanych informacji dotyczÄ…cych metody obliczania czÄ™stotliwoÅ›ci oraz konfiguracji SPI.

​

SÅ‚owo które bÄ™dziemy wysyÅ‚ać do AD985X ma dÅ‚ugość 40 bitów czyli 5 bajtów. Pierwsze 4 bajty zawierajÄ… informacjÄ™ o czÄ™stotliwoÅ›ci i ostatni bajt to bajt konfiguracyjny naszego DDSa. Dla poprawnej transmisji sÅ‚owa po SPI, musimy ustawić interfejs w konfiguracji "LSB first".

A oto wzór jaki należy zastosować do wyliczenia wartoÅ›ci jakÄ… bÄ™dziemy wysyÅ‚ać do DDSa by poinformować go o żądanej czÄ™stotliwoÅ›ci:

QRG = F * 4294967296 / zegar

gdzie QRG to żądana czÄ™stotliwość w Hz (10MHz = 10000000, 21MHz = 21000000 itd), a zegar przyjmuje wartość czÄ™stotliwoÅ›ci zegara taktujÄ…cego nasz DDS wyrażonej też w Hz czyli 125MHz = 125000000 dla ukÅ‚adu AD9850 albo 180MHZ = 180000000 dla ukÅ‚adu AD9851. 

​

zatem aby uzyskać czÄ™stotliwość w zakresie pasma dwudziestu metrów 14,250.230 MHz nasz wzór bÄ™dzie wyglÄ…daÅ‚ tak: QRG = 14250230 * 4294967296 / 180000000 

jak widać mamy możliwość ustawiania każdej czÄ™stotliwoÅ›ci z dokÅ‚adnoÅ›ciÄ… do jednego HZ. 

Poniżej przedstawię kod dla mikroprocesora Atmega 32 z wykorzystaniem sprzętowego SPI

​

Przedstawiam zatem treść biblioteki skÅ‚adajÄ…cej siÄ™ z dwóch plików.

Plik nagÅ‚ówkowy SP_AD9851.h

Plik gÅ‚ówny SP_AD8951.c

​

/////////////////////////////////////////////////////////////////////SP_AD9851.h/////////////////////////////////////////////////////////////////////////

​

​

#ifndef SP_AD9851_SP_AD9851_H_
#define SP_AD9851_SP_AD9851_H_

​

/* konfiguracja hardware SPI do AD9851*/


#define MOSI (1<<PB3)        //   <---- A (SER IN) = D7
#define SCK (1<<PB5)        //   <---- SHIFT CLOCK (SC) = WCLK
#define LT (1<<PB2)            //     <---- LATCH CLOCK (LT) = FQ_UP

#define RESET (1<<PD1)        //     <---- Reset AD9851 (RESET)
#define RESETDIR DDRD
#define RESETPORT PORTD


// definicje makr LT, SCK, RST //
#define LT_ON PORTB |= LT
#define LT_OFF PORTB &= ~LT

#define SCK_ON PORTB |=SCK
#define SCK_OFF PORTB &= ~SCK

#define RESET_ON PORTD |= RESET
#define RESET_OFF PORTD &= ~RESET


uint32_t qrg;

 

//Funkcje obsługi AD9851
void InitSpi(void);
void SendSpi(uint32_t qrg);
void AD985Xinit (void);


#endif /* SP_AD9851_SP_AD9851_H_ */

​

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Drugi plik biblioteczny SP_AD9851.c

////////////////////////////////////////////////////////////////Teraz plik SP_AD8951.c////////////////////////////////////////////////////////////////////////

​

​

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include "SP_AD9851.h"

 

 


//----------------------------DEFINICJE FUNKCJI-------------------------------------------------//


// funkcja inicjalizacji sprzÄ™towego SPI  dla AD985/9851 =LSB First //
void InitSpi(void) {

    DDRB |= MOSI|SCK|LT;                                    // piny SPI jako wyjÅ›cia
    SPCR |= (1<<SPE)|(1<<MSTR)|(1<<DORD);   // wÅ‚Ä…cz SPI i ustaw Master oraz DORD na LSB first
    SPSR |= (1<<SPI2X);                                           // fosc/2
}


//.....................................................................//

// funkcja Wysyłania słowa 40 bit do AD9851 bajt po bajcie//
void SendSpi( uint32_t qrg) {

    LT_ON;
    LT_OFF;
    SPDR = qrg;
    while( !(SPSR & (1<<SPIF)) );
    SPDR = qrg>>8;
    while( !(SPSR & (1<<SPIF)) );
    SPDR = qrg>>16;
    while( !(SPSR & (1<<SPIF)) );
    SPDR = qrg>>24;
    while( !(SPSR & (1<<SPIF)) );
    SPDR = 0x01;
//bajt konfiguracyjny - 0x01 dla AD9851 ustawia mnożnik zegara x6 w przypadku AD9850 należy wysÅ‚ac 0x00 //   

while ( ! (SPSR & (1<<SPIF)) );
    LT_ON;
    LT_OFF;
}

//.........................................................................................

//Funkcja inicjująca uklad DDS AD9850_9851 Bezpośrednio po wywolaniu inicjalizacji należy
// kolejno wywolac funkcje sendspi nawet z ustawieniem zero.

 

void AD985Xinit (void) {

    RESET_ON;                      // Reset AD9851 stanem wysokim
        _delay_ms (5);
        RESET_OFF;
        SCK_ON;
        _delay_ms (5);
        SCK_OFF;
        LT_ON;
        _delay_ms (5);
        LT_OFF;

        SendSpi ( qrg );            // wyslanie zerowej qrg z bajtem konfiguracyjnym (inicjacja AD985X)
                    

}

​

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

W dwóch powyższych plikach mamy ustawionÄ… konfiguracjÄ™ dla ukÅ‚adu Atmega32. WykorzystujÄ™ tam sprzÄ™towy interfejs SPI. 

​

Jak widać z opisów w pliku nagÅ‚ówkowym, moduÅ‚ DDS podÅ‚Ä…czamy do mikroprocesora w nastÄ™pujÄ…cy sposób:

#define MOSI (1<<PB3)        //   <---- A (SER IN) = D7
#define SCK (1<<PB5)        //   <---- SHIFT CLOCK (SC) = WCLK
#define LT (1<<PB2)            //     <---- LATCH CLOCK (LT) = FQ_UP

#define RESET (1<<PD1)        //     <---- Reset AD9851 (RESET)

​

PB3 = D7

PB5 = WCLK

PB2 = FP_UP

PD1 = RESET

​

​

Korzystając z powyższej biblioteki, możemy teraz umieścić w programie taką funkcję:

 

qrg = data * 4294967296 / zegar;
        SendSpi ( qrg );

​

​

Teraz wpisujÄ…c w miejsce "data" rzÄ…dnÄ… czÄ™stotliwość w Hz, wysyÅ‚am wynik do moduÅ‚y i uzyskujÄ™ na jego wyjÅ›ciu zadanÄ… czÄ™stotliwość. 

​

Dalej już możemy sobie wykorzystać ten kod w dowolny sposób do sterowania naszymi DDSami w Transceiverze.

Kolejny moduÅ‚ który użyjemy to wyÅ›wietlacz graficzny. ModuÅ‚ dostÄ™pny w internecie w wielu różnych odmianach.

 

HX8357B 3,2'' 420x380 16bit bus

​

Ponieważ wyÅ›wietlacze z tym interfejsem HX8357 dostÄ™pne sÄ… w wielu różnych wykonaniach, przedstawiÄ™ zdjÄ™cia tych egzemplarzy które trafiÅ‚y w moje rÄ™ce zakupione u jednego ze sprzedawców internetowych. 

Ten rodzaj wyÅ›wietlacza gotowy jest do pracy z napiÄ™ciem 5V, jego rozdzielczość to 420x380 a przekÄ…tna ekranu to 3,2'' , ale uwaga!! wykorzystuje on równolegÅ‚y interfejs 16 bitowy czyli bÄ™dziemy musieli użyć dwóch oÅ›miobitowych portów do sterowania tym wyÅ›wietlacze ( sÄ… dostÄ™pne te wyÅ›wietlacze także z interfejsem SPI, jednak ja mam wÅ‚aÅ›nie takie z interfejsem równolegÅ‚ym i takiego użyjÄ™). Na jego pokÅ‚adzie znajdziemy też interfejs karty SD który obsÅ‚uguje siÄ™ przez SPI, jednak ja  nie bÄ™dÄ™ siÄ™ nim zajmowaÅ‚ (przynajmniej nie na tym etapie konstruowania transceivera).

Ten wyÅ›wietlacz posÅ‚uży mi do obrazowania aktywnych ustawieÅ„ urzÄ…dzenia oraz czÄ™stotliwoÅ›ci na której Transceiver pracuje. Moja wiedza nie pozwala mi jeszcze na zbudowanie popularnej obecnie ramki monitora pasma, jednak nie wykluczam takiej możliwoÅ›ci w przyszÅ‚oÅ›ci. 

Opanowanie programowe takiego wyÅ›wietlacza jest bardzo cennÄ… naukÄ…, ponieważ wiÄ™kszość innych wyÅ›wietlaczy graficznych dziaÅ‚a bardzo podobnie i nie ma już wiÄ™kszego kÅ‚opotu żeby opanować ich obsÅ‚ugÄ™. 

 

Zaczynamy

​

Do wysterowania tego wÅ‚aÅ›nie wyÅ›wietlacza potrzebujemy aż dwudziestu pinów z naszego mikroprocesora. 

16 dla magistrali danych, oraz 4 dla sterowania kontrolera wyświetlacza.

Na zdjęciu poniżej widać mapę wyprowadzeń:

Nas interesujÄ… piny DB0 do DB15 to wÅ‚aÅ›nie 16 bitów magistrali danych, oraz LCD_RS, LCD_WR, LCD_CS, LCD_RST.

OczywiÅ›cie piny 5V oraz GND aby zasilić nasz wyÅ›wietlacz. PozostaÅ‚e piny SPI które sÄ… tam widoczne,  to wÅ‚aÅ›nie interface do obsÅ‚ugi slotu kart SD. 

PrzykÅ‚ad który teraz opisujÄ™, dotyczy sterowania tego wyÅ›wietlacza za pomocÄ… mikroprocesora Atmega 32.

W internecie znalazÅ‚em caÅ‚Ä… masÄ™ przykÅ‚adów bibliotek dla sterownika HX8357, jednak albo byÅ‚y przygotowane w jÄ™zyku C++ dla Arduino którego nie znam, albo dla interfejsu SPI którego nie ma w moim wyÅ›wietlaczu.

 

Najważniejsze jest przygotowanie podstawowych funkcji za pomocÄ… których bÄ™dziemy sterować tym wyÅ›wietlaczem, czyli takich funkcji sprzÄ™towych. ResztÄ™ funkcji już tych z wyższego poziomu, do sterowania samym interfejsem graficznym, bÄ™dÄ™ mógÅ‚ po modyfikacji wykorzystać z istniejÄ…cych w internecie bibliotek. OczywiÅ›cie niezbÄ™dne bÄ™dzie ich przerobienie z C++ czy Arduino do czystego jÄ™zyka C którym siÄ™ posÅ‚ugujÄ™. 

Å»eby jeszcze bardziej uproÅ›cić sobie obsÅ‚ugÄ™ interfejsu równolegÅ‚ego, postanowiÅ‚em użyć dwóch peÅ‚nych portów mikrokontrolera, a dokÅ‚adnie wybór padÅ‚ na porty PA oraz PC. Dla sygnaÅ‚ów sterujÄ…cych użyÅ‚em pinów z portów PD oraz PB. Oto lista poÅ‚Ä…czeÅ„ jakie użyÅ‚em w moim projekcie:

 

      TFT    AVR
    -------------------
    D15    PA7
    D14    PA6
    D13    PA5
    D12    PA4
    D11    PA3
    D10    PA2
    D9      PA1
    D8      PA0
    -------------------
    D7    PC7
    D6    PC6
    D5    PC5
    D4    PC4
    D3    PC3
    D2    PC2
    D1    PC1
    D0    PC0

  

    RS      PD7
    WR    PB2
    CS     PB1
    RST   PB0

​

Ze względu na objętość kodu potrzebnego do obsługi HX8357B, przedstawię tutaj tylko podstawowe informacje i niezbędne funkcje aby posłużyć się naszym wyświetlaczem.

​

Na poczÄ…tek potrzebujemy skonfigurować poÅ‚Ä…czenia TFT z Atmega32 oraz stworzyć niezbÄ™dne makra do obsÅ‚ugi sygnaÅ‚ów sterujÄ…cych i to wszystko w pliku nagÅ‚ówkowym SP_HX8357B.h:

​

///////////////////////////////////////////////////////////////////////SP_HX8357.h///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------
//
//        Ustawienia sprzÄ™towe poÅ‚Ä…czeÅ„ sterownika z mikrokontrolerem
//
//----------------------------------------------------------------------------------------


// tu definiuje piny procesora do których podÅ‚Ä…czam sygnaÅ‚y RS,WR,CS, RST
//! konfiguracja pinów sterujÄ…cych LCD TFT HX8357B


#define RST (1<<PB0)        //ustawiam pin RST
#define RST_PORT      PORTB
#define RST_DDR        DDRB

#define CS     (1<<PB1)        //ustawiam pin CS
#define CS_PORT      PORTB
#define CS_DDR        DDRB

#define WR     (1<<PB2)        //ustawiam pin WR
#define WR_PORT      PORTB
#define WR_DDR        DDRB

#define RS     (1<<PD7)        //ustawiam pin RS
#define RS_PORT      PORTD
#define RS_DDR        DDRD

​

// tu konfiguruje porty dla linii D0..D15 LCD muszÄ… byc dwa pelne porty od 0 do 7
#define DATA_PORT1         PORTC        // ustawiam port pierwszy D0-D7
#define DATA_PORT1_DDR    DDRC

#define DATA_PORT2         PORTA        // ustawiam port drugi    D8-D15
#define DATA_PORT2_DDR    DDRA

 

//------------------------------------------------  koniec ustawieÅ„ sprzÄ™towych ---------------


//definicje makr pinów sterujÄ…cych wyÅ›wietlacz//
#define DEB_H     PORTD |= DEB
#define DEB_L     PORTD &= ~DEB
#define DEB_B    PORTD ^= DEB

#define RST_H     PORTB |= RST
#define RST_L     PORTB &= ~RST

#define CS_H    PORTB |= CS
#define CS_L     PORTB &= ~CS

#define WR_H     PORTB |= WR
#define WR_L     PORTB &= ~WR
#define WR_STB     PORTB &= ~WR; PORTB |= WR;

#define RS_H     PORTD |= RS
#define RS_L     PORTD &= ~RS

​

/////////////////////////////////////////////////////cdn. //////////////////////////////////////////////////////////////////

​

Do naszego wyświetlacza będziemy wysyłać dwa rodzaje informacji, komendy - Command i dane - Data.

Komendy żeby byÅ‚o Å‚atwiej i jaÅ›niej, zdefiniujemy sobie również w pliku nagÅ‚ówkowy. Także dane o kolorach oraz inne dane potrzebne do konfiguracji wyÅ›wietlacza . Zaznaczam że poniższe dotyczy dokÅ‚adnie tego wyÅ›wietlacza jakim siÄ™ teraz zajmujemy. Dla innego modelu z tym sterownikiem HX8357 poniżesz komendy mogÄ… siÄ™ nieco różnić. To też dotyczy danych konfiguracyjnych. Jednak to co tutaj przedstawiam jest sprawdzone i dziaÅ‚a poprawnie z wyÅ›wietlaczem który tutaj omawiam.

​

///////////////////////////////////////////////////////////dalszy ciÄ…g SP_HX8357B.h////////////////////////////////

​

// komendy dla sterownika HX8357D
#define HX8357B 0xB

#define HX8357_TFTWIDTH  480 //320 
#define HX8357_TFTHEIGHT 320 //480

#define HX8357_NOP     0x00
#define HX8357_SWRESET 0x01
#define HX8357_RDDID   0x04
#define HX8357_RDDST   0x09

#define HX8357_RDPOWMODE  0x0A
#define HX8357_RDMADCTL  0x0B
#define HX8357_RDCOLMOD  0x0C
#define HX8357_RDDIM  0x0D
#define HX8357_RDDSDR  0x0F

#define HX8357_SLPIN   0x10
#define HX8357_SLPOUT  0x11
#define HX8357B_PTLON   0x12
#define HX8357B_NORON   0x13

#define HX8357_INVOFF  0x20
#define HX8357_INVON   0x21
#define HX8357_DISPOFF 0x28
#define HX8357_DISPON  0x29

#define HX8357_CASET   0x2A
#define HX8357_PASET   0x2B
#define HX8357_RAMWR   0x2C
#define HX8357_RAMRD   0x2E

#define HX8357B_PTLAR   0x30
#define HX8357_TEON  0x35
#define HX8357_TEARLINE  0x44
#define HX8357_MADCTL  0x36
#define HX8357_COLMOD  0x3A

#define HX8357_SETOSC 0xB0
#define HX8357_SETPWR1 0xB1
#define HX8357B_SETDISPLAY 0xB2
#define HX8357_SETRGB 0xB3
#define HX8357D_SETCOM  0xB6

#define HX8357B_SETDISPMODE  0xB4
#define HX8357D_SETCYC  0xB4
#define HX8357B_SETOTP 0xB7
#define HX8357D_SETC 0xB9

#define HX8357B_SET_PANEL_DRIVING 0xC0
#define HX8357D_SETSTBA 0xC0
#define HX8357B_SETDGC  0xC1
#define HX8357B_SETID  0xC3
#define HX8357B_SETDDB  0xC4
#define HX8357B_SETDISPLAYFRAME 0xC5
#define HX8357B_GAMMASET 0xC8
#define HX8357B_SETCABC  0xC9
#define HX8357_SETPANEL  0xCC

#define HX8357B_SETPOWER 0xD0
#define HX8357B_SETVCOM 0xD1
#define HX8357B_SETPWRNORMAL 0xD2

#define HX8357B_RDID1   0xDA
#define HX8357B_RDID2   0xDB
#define HX8357B_RDID3   0xDC
#define HX8357B_RDID4   0xDD

#define HX8357D_SETGAMMA 0xE0

#define HX8357B_SETGAMMA 0xC8
#define HX8357B_SETPANELRELATED  0xE9

//definicje kolorów
#define black           0x0000
#define navy            0x000F
#define dark_green      0x03E0
#define dark_cyan       0x03EF
#define maroon          0x7800
#define purple          0x780F
#define olive           0x7BE0
#define light_grey      0xC618
#define dark_grey       0x7BEF
#define blue            0x001F
#define green           0x07E0
#define cyan            0x07FF
#define red             0xF800
#define magenta         0xF81F
#define yellow          0xFFE0
#define white           0xFFFF
#define orange          0xFD20
#define green_yellow    0xAFE5
#define brown           0x79E0

//definicje kierunków
#define MADCTL_MY  0x80
#define MADCTL_MX  0x40
#define MADCTL_MV  0x20
#define MADCTL_ML  0x10
#define MADCTL_RGB 0x00
#define MADCTL_BGR 0x08
#define MADCTL_MH  0x04
#define MADCTL_SS  0x02 // SP2LUB dodane dla HX8357X 16 bit interface równolegÅ‚y
#define MADCTL_GS  0x01 // SP2LUB dodane dla HX8357X 16 bit interface równolegÅ‚y


//definicje pomocnicze
#define swap(a, b) { int16_t t = a; a = b; b = t; }

​

//deklaracje zmiennych
uint16_t _width, _height;
extern const uint8_t font[];
extern int crsor_x, cursor_y;

​

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

​

Teraz czas na zadeklarowanie funkcji z których później bÄ™dziemy korzystać. CiaÅ‚a tych funkcji przedstawiÄ™ przy okazji is definiowania w pliku bibliotecznym .c Funkcje tutaj przedstawione to fukcje najbardziej podstawowe czyli te zwiÄ…zane z hardwarem. Te wÅ‚aÅ›nie funkcje bezpoÅ›rednio wspóÅ‚pracujÄ… ze sterownikiem wyÅ›wietlacza. One bÄ™dÄ… podstawowymi skÅ‚adnikami funkcji wyższego poziomu z których tylko kilka tutaj przedstawiÄ™.

​

///////////////////////////////////////////////////////////dalszy ciÄ…g SP_HX8357B.h////////////////////////////////

​

// ### deklaracje funkcji ###

//funkcje sprzętowe
void writecommand( uint8_t dat );
void writedata( uint8_t dat );
void hx8357d_init ( void );//
void hx8357d_setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
void hx8357d_setRotation(uint8_t rotation);
uint16_t hx8357d_color565(uint8_t r, uint8_t g, uint8_t b); //convert three 8 bit RGB levels to a 16 bit colour value
void hx8357d_pushColor(uint16_t color);

​

////////////////////////////////////////////////////// END ///////////////////////////////////////////////

​

Dwie najbardziej podstawowe funkcje które bÄ™dÄ™ odpowiedzialne za transfer informacji do wyÅ›wietlacza 

Pierwsza to void writecommand( uint8_t dat ); Ta funkcja bÄ™dzie sÅ‚użyć do wysyÅ‚ania Komend które zdefiniowaliÅ›my sobie wczeÅ›niej w pliku nagÅ‚ówkowym.

Druga to writedata( uint8_t dat ); Ta funkcja bÄ™dzie sÅ‚użyć do wysyÅ‚ania danych.

​

Kolejna bardzo ważna funkcja to funkcja inicjujÄ…ca wyÅ›wietlacz hx8357d_init ( void );

​

w pliku bibliotecznym SP_HX8357B.c zawarte sÄ… ciaÅ‚a tych funkcji które teraz przedstawiÄ™

​

/////////////////////////////////////////////////SP_HX8357.c/////////////////////////////////////

​

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

#include "SP_HX8357B.h"

 

//deklaracje zmiennych
int cursor_x, cursor_y;
uint16_t _width, _height;

​

// wysłanie komendy
void writecommand( uint8_t cmd ) {
    CS_L;
    RS_L;
PORTA = 0;
PORTC = cmd;
    WR_STB;
    RS_H;
    CS_H;

}
 

//wysładnie danych
void writedata( uint8_t dat ) {

    CS_L;
PORTA =dat>>8;
PORTC =dat;
    WR_STB;
    CS_H;

}

​

// Inicjacja wyswietlacza HX8357-B 16bit
void hx8357d_init ( void ) {


        DDRA     = 0xff;
        DDRC     = 0xff;

​

        RST_DDR    |= RST;
        CS_DDR    |= CS;
        WR_DDR    |= WR;
        RS_DDR    |= RS;

        RST_H;
        _delay_ms (50);
        RST_L;
        _delay_ms (10);
        RST_H;
        _delay_ms (10);

        writecommand(0x11);
        _delay_ms(120);
        writecommand(0xD0); // HX8357B_SETPOWER
       writedata(0x07);
       writedata(0x42);
       writedata(0x18);
       writedata(0x00);

        writecommand(0xD1); //HX8357B_SETVCOM
       writedata(0x00);
       writedata(0x07);
       writedata(0x10);

       writecommand(0xD2); //HX8357B_SETPWRNORMAL
       writedata(0x01);
       writedata(0x02);

        writecommand(0xC0);
        writedata(0x10);
        writedata(0x3B);
        writedata(0x00);
        writedata(0x02);
        writedata(0x11);

        writecommand(0xC5);
        writedata(0x08);

        writecommand(0xC8);
        writedata(0x00);
        writedata(0x32);
        writedata(0x36);
        writedata(0x45);
        writedata(0x06);
        writedata(0x16);
        writedata(0x37);
        writedata(0x75);
        writedata(0x77);
        writedata(0x54);
        writedata(0x0C);
        writedata(0x00);

        writecommand(0x36); // HX8357_MADCTL
        writedata(0x0a);

        writecommand(0x3A); // Interface pixel format
        writedata(0x55);    // 16 bits per pixel

        writecommand(0x2A); // HX8357_CASET
        writedata(0x00);
        writedata(0x00);
        writedata(0x01);
        writedata(0x3F);

        writecommand(0x2B); // HX8357_PASET
        writedata(0x00);
        writedata(0x00);
        writedata(0x01);
        writedata(0xDF);

        _delay_ms(120);
        writecommand(0x29);
        _delay_ms(25);

 

        CS_L;
}
 

///////////////////////////////////////////////////////////////////////////////////cdn./////////////////////////////////////////////////////////////

​

Właściwie to co przedstawiłem powyżej już wystarczy żeby podłączyć i zainicjować wyświetlacz z Atmega32.

​

Potrzebne sÄ… jeszcze funkcje wyższego poziomu, czyli te które pozwolÄ… nam na czyszczenie ekranu, ryzowanie figur geometrycznych, wysyÅ‚anie znaków i stringów... Te funkcje można w dość prosty sposób przerobić z bibliotek napisanych dla tego wyÅ›wietlacza na platformÄ™ Ardunio. Pisane sÄ… one w jÄ™zyku C++ ale po odrobinie wysiÅ‚ku można je przerobić opierajÄ…c siÄ™ na bazowych funkcjach które powyżej przestawiÅ‚em. Jeżeli ktoÅ› jest zainteresowany uzyskaniem wiÄ™cej informacji o przedstawionej bibliotece, proszÄ™ o email na sp2lub@gmail.com

bottom of page