Warning: file_get_contents(https://graph.facebook.com/?ids=http%3A%2F%2Fwww.stsystem.pl%2Findex.php%3Foption%3Dcom_content%26view%3Darticle%26id%3D22) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden in /domains/stsystem.pl/public_html/plugins/content/fbar/fbar.php on line 210

Warning: file_get_contents(https://graph.facebook.com/?ids=http%3A%2F%2Fwww.stsystem.pl%2Findex.php%3Foption%3Dcom_content%26view%3Darticle%26id%3D22) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden in /domains/stsystem.pl/public_html/plugins/content/fbar/fbar.php on line 210

Przed dalszą lekturą polecam zapoznanie się z:
- blogiem Mirosława Kardasia tutaj
- tematem na forum Elektroda.pl tutaj
- artykułem na mojej stronitutaj

Uzbrojony w taką lekturę możesz już bez obaw przejść dalej. Koncepcja zaprezentowana przez Kol. Mirka na Jego blogu bardzo przypadła mi do gustu. Mirek, jak sam mówi - nie jest autorem tego pomysłu. Tymbardziej ja muszę schylić czoła przed nim i przyznać, że bez jego przysłowiowego "kopniaka" dalej korzystałbym z obsługi wyświetlacza opisanej tutaj.

Ponieważ wskazane materiały doskonale prezentują ideę tego co za chwilę przedstawię, skupię się jedynie na pokazaniu praktycznego sposobu użycia moich funkcji, bez wnikania w sposób wewnętrznego działania bilbioteki (a właściwie zestawu funkcji bo bilbioteką plików *.h i *.c nazwać nie możemy).

Zawartość pliku LCDbuf.h

 
/*
 * LCDbuf.h
 *
 * Created on: 10-03-2012
 * Author: Thomaz
 */
 
#ifndef LCDBUF_H_
#define LCDBUF_H_
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include "lcd.h"
#include "..\TIMERY\tajmer2.h"
/***************************************************************************************/
//Definicja rozmiarow wyswietlacza
#define Lines 2
#define Columns 16
#define Refresh 15 //szybkosc odswiezania obrazu (x10ms)
//Definicja znakow specjalnych
#define Space 32
#define Null 0
/***************************************************************************************/
#if Lines<1
#error Zwieksz liczbe wierszy wyswietlacza!
#endif
#if Lines>4
#error Zmniejsz liczbe wierszy wyswietlacza!
#endif
#if Columns<8
#error Zwieksz liczbe kolumn wyswietlacza!
#endif
#if Columns>40
#error Zmniejsz liczbe kolumn wyswietlacza!
#endif
//Definicja buforów wyswietlania
char LCDbuf1[(Columns + 1)];
#if Lines>=2
char LCDbuf2[(Columns + 1)];
#endif
#if Lines>=3
char LCDbuf3[(Columns + 1)];
#endif
#if Lines>=4
char LCDbuf4[(Columns + 1)];
#endif
//bufor dla funkcji itoa mieszczący liczby 16bit
extern char result[6];
enum LCDmode {Freeze,Clear};
//ustawienie kursora
void bLCDxy(uint8_t x, uint8_t y);
//czyszczenie RAM
void bLCDcls(void);
//wyswietlanie tekstow z RAM na LCD
void LCDdisplay(uint8_t mode);
//zapis tekstow do pamieci RAM
void bLCDtext(char *txt);
void bLCDpgmtext(const uint8_t *FlashLoc);
#endif /* LCDBUF_H_ */

Zawartość pliku LCDbuf.c

 
#include "LCDbuf.h"
char result[6];
typedef uint8_t u8;
typedef uint16_t u16;
u8 Px,Py;
void bLCDxy(uint8_t x, uint8_t y)
{
Px=x;
Py=y;
return;
}
//Czyszczenie zawartosci bufora
void bLCDcls(void)
{
 for(uint8_t x=0;x<=(Columns);x++)
 {
 LCDbuf1[x]=Space;
#if Lines>=2
 LCDbuf2[x]=Space;
#endif
#if Lines>=3
 LCDbuf3[x]=Space;
#endif
#if Lines>=4
 LCDbuf4[x]=Space;
#endif
 }
 LCDbuf1[Columns]=Null;
 #if Lines>=2
 LCDbuf2[Columns]=Null;
 #endif
 #if Lines>=3
 LCDbuf3[Columns]=Null;
 #endif
 #if Lines>=4
 LCDbuf4[Columns]=Null;
 #endif
return;
}
//wyswietlanie tekstow z RAM na LCD
void LCDdisplay(uint8_t mode)
{
 if(!T_LCDrefresh)
 {
 T_LCDrefresh=Refresh;
 LCDxy(0,0);
 LCDtext(LCDbuf1);
#if Lines>=2
 LCDxy(0,1);
 LCDtext(LCDbuf2);
#endif
#if Lines>=3
 LCDxy(0,2);
 LCDtext(LCDbuf3);
#endif
#if Lines>=4
 LCDxy(0,3);
 LCDtext(LCDbuf4);
#endif
 }
 if(mode)
 bLCDcls();
 return;
}
//zapis tekstow do pamieci RAM
void bLCDtext(char *txt) {
 while (*txt&&(Px<Columns))
 {
 if(Py==1)
 LCDbuf1[Px++]=*txt++;
#if Lines>=2
 if(Py==2)
 LCDbuf2[Px++]=*txt++;
#endif
#if Lines>=3
 if(Py==3)
 LCDbuf3[Px++]=*txt++;
#endif
#if Lines>=4
 if(Py==4)
 LCDbuf4[Px++]=*txt++;
#endif
 }
 return;
}
 

void bLCDpgmtext(const uint8_t *FlashLoc) {
 register char znak;
 while ((znak=pgm_read_byte(FlashLoc++))&&(Px<Columns))
 {
 if(Py==1)
 LCDbuf1[Px++]=znak;
 #if Lines>=2
 if(Py==2)
 LCDbuf2[Px++]=znak;
 #endif
 #if Lines>=3
 if(Py==3)
 LCDbuf3[Px++]=znak;
 #endif
 #if Lines>=4
 if(Py==4)
 LCDbuf4[Px++]=znak;
 #endif
 }
return;
}

OBSŁUGA

Na samym wstępie uwagę Twoją zwrócić muszę na zapis:

..\TIMERY\tajmer2.h

znajdujący się na początku pliku nagłówkowego LCDbuf.h. Otóż timer2 naszego AVR skonfigurowany jest do pracy w trybie CTC z przepełnieniem rózno co 10ms. Każde przepełnienie timera powoduje ustawienie flagi zwanej "Tick". W pętli głównej programu umieszczona jest funkcja includowana z plików timera, w której następuje cykliczne dekrementowanie wartości zmiennej T_LCDrefresh (tzw. licznik programowy) w momencie wykrycia wartości true w zmiennej Tick. W głównej pętli umieszczona jest także funkcja

LCDdisplay(Clear);

wykorzystująca w swoim wnętrzu zmienną T_LCDrefresh. Gdy wartość tej zmiennej osiągnie 0 - wywoływana jest procedura przepisania wewnętrznego bufora wyświetlania do naszego wyświetlacza LCD i ponowne wpisanie do zmiennej T_LCDrefresh wartości czasu odswieżania. Więcej o sposobie użycia timerów programowych można przeczytać tutaj.

Funkcje do obsługi wyświetlania buforowego zostały nazwane identycznie jak te do właściwej obłsugi wyświetlacza, różnią się jedynie przedrostkiem w postaci literki "b" na początku nazwy. W moim kodzie użyty jest tylko jeden bufor do wyświetlania danych na LCD, w przeciwnieństwie do pomysłu Mirka, aby utworzyć sobie kilka takich buforów i móc przełączać się pomiędzy nimi. Prawdę powiedziawszy z początku myślałem nad realizacją tago w taki sam sposób. Jednak przynajmniej w zastosowaniu do którego ten kod już jest zdrożony nie miałem takiej potrzeby. Oczywiście nic nie stoi na przeszkodzie, aby powyższe kody zmodyfikować - rozbudować o większą ilość buforów. Zadanie to jest łatwe i nie powinno sprawić większego problemu. Używając powyższych funkcji, w połączeniu z timerami programowymi mogę w różnych miejscach wyświetlacza umieszczać różne animowane "gadżety" posiadające swoje własne czasy przełączania animacji. A teraz garść informacji nt. użycia funkcji w programie:

 
int main(void)
{
LCDinit(); //sprzętowa inicjalizacja LCD
LCDcls(); //czyszczenie LCD
bLCDcls(); //czyszczenie bufora LCD
bLCDxy(0,1); //ustawienie kursora na pozycji 0 w linii 1
bLCDpgmtext(Powitanie1); //wczytanie do bufora danych z pamięci programu
bLCDxy(4,2); //ustawienie kursora na pozycji 4 w linii 2
bLCDpgmtext(Powitanie2); //wczytanie do bufora danych z pamięci programu
LCDdisplay(Freeze); //wyświetlenie bufora na ekranie 
_delay_ms(2000); //przytrzymanie tekstu na ekranie przez 2 sekundy
while(1)
{
bLCDxy(0,1); //ustawienie kursora na pozycji 0 w linii 1
SysTick(); //wspomniana funkcja obsługi timerów programowych
bLCDpgmtext(mainWind); //wczytanie do bufora danych z pamięci programu
 bLCDtext(itoa(zmienna,result,10)); //wczytanie do bufora danych będących zwrotem z funkcji itoa
bLCDtext("test"); //wczytanie do bufora danych przekazanych "jawnie"
LCDdisplay(Clear);
}
}

Warto zauważyć, że ustawianie kursora na żądanej pozycji i następnie zapisywanie na tej pozycji jakiegoś znaku powoduje autoinkrementację pozycji kursora - tak jak ma to miejsce w standardowej aplikacji wyświetlaczy. Podawana jako parametr funkcji LCDdisplay(  ) zmienna typu wyliczeniowego ("Clear" lub "Freeze") wymusza następujące zachowanie się bufora:

- Clear - po każdym wyświetleniu bufor jest czyszczony

- Freeze - bufor zachowuje się tak samo jak pamięć wyświetlacza, jest nadpisywany

Mimo nieco innego podejścia do tematu niż autor mojego "kopniaka" - jestem w stanie otrzymać takie same efekty wizualne jak prezentowane w filmiku na jego stronie. Tutaj jednak należy się zastanowić co będzie łatwiejsze: użycie jednego bufora wyświetlania i odpowiednie manipulowanie danymi przekazywanymi do niego, czy użycie "warst" z wieloma buforami. Wszystko zależeć będzie od konkretnej realizacji i oczekiwanych efektów. Powyższe kody w zupełności wystarczą mi do realizacji zamierzonego efektu graficznego, jednak nie wykluczam, że w przyszłości zmuszony będę rozszerzyć je właśnie o dodatkowe bufory.

Zapraszam do eksperymentów :)

 

Do pobrania:

Użyj opcji uploadu plików, aby przekazać mi kod do sprawdzenia. Postaram się zajrzeć do niego tak szybko jak będzie to możliwe. Paczkę z poprawionym kodem umieszczę w tym samym miejscu.

 

 

Jeżeli wystąpi sytuacja, w której zostanie wyświetlona zawartość folderu z innego działu - należy wyczyścić cache przeglądarki! Następnie przeładować stronę.

Komentarze  

 
# JosephJoseph 2016-11-04 08:43
nasa, , harold hill
Odpowiedz | Odpowiedz z cytatem | Cytować
 

Licznik odwiedzin

Mapa odwiedzin



 

Copyright © ST WebSite 2017

Stronę hostuje FutureHost. []

Strona korzysta z plików cookie. Dane przechowywane na Twoim komputerze służą wyłą…cznie do poprawienia funkcjonalnoś›ci witryny. Jeżeli tego nie akceptujesz - powinieneś› ją… opuś›cić‡.

Akceptujesz ciasteczka z tej witryny?