SP2LUB - LA1BUA
SP2LUB - Poland QTH Gdynia ITU Zone 28 -CQ Zone 15 - Grid Square JO94gl
LA1BUA - Norway QTH Lye ITU Zone 18 - CQ Zone 14 - Grid Square JO28TR
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