// LCD Terminal pro menic pro solarni vozitko
// (c)miho 2005
// Pouziva PIC16F84 (mozno i jakykoli jiny, nepouzivaji se zadne specialni funkce).
// Na vstupnim vyvodu RS_IN ocekava seriovou komunikaci rychlosti RS_BOUD. Pri detekci
// start bitu pomoci preruseni dojde k programovemu prijmu znaku a jeho zarazeni do
// fronty FIFO. Po navratu z preruseni dochazi k vypisu na pripojeny dvouradkovy
// LCD displej. Program zpracovava ridici kody dle knihovny LCD.C. Pri delsich vypisech
// musi vysilajici strana ponechat (obcas) nejaky cas na zpracovani (napriklad 20ms).
#include <16F84.h> // define standardnich konstant procesoru
#use delay(clock=4000000) // standardni krystal
#fuses HS, NOWDT, NOPUT, NOPROTECT
// Parmetry komuniace
//
#define INV // definuje polaritu
#define RS_BOUD 9600 // komunikacni rychlost
#define RS_IN PIN_B0 // musi to byt vstup extrniho preruseni
// Pripojeni LCD displeje
//
#define LCD_RS PIN_A0 // rizeni registru LCD displeje
#define LCD_E PIN_A1 // enable LCD displeje
#define LCD_DATA_LSB PIN_B4 // pripojeni LSB bitu datoveho portu LCD displeje (celkem 4 bity vzestupne za sebou)
#include "LCD.C"
// Vstup seriovky
//
#ifdef INV
#use RS232 (BAUD=RS_BOUD, RCV=RS_IN, PARITY=N, INVERT)
#else
#use RS232 (BAUD=RS_BOUD, RCV=RS_IN, PARITY=N)
#endif
// Buffer FIFO
//
#define MAX 40 // delka bufferu
char c[MAX]; // bufer FIFO
unsigned int ci; // ukazatel na bunku kam se bude ukladat novy znak
unsigned int co; // ukazatel na bunku odkud se bude cist znak
// Preruseni - ukladani dat ze seriovky do bufferu
//
#int_ext // preruseni od zacatku znaku (start bit)
void Interupt()
{
c[ci]=getc(); // nacti znak (asynchronni cteni programem)
if (ci<(MAX-1)) ci++; else ci=0; // posun ukazovatko do FIFO
#ifdef INV
while(input(PIN_B0)); // pockej na konec posledniho bitu
#else
while(~input(PIN_B0)); // pockej na konec posledniho bitu
#endif
}
// Hlavni smycka
//
void main()
{
char ch; // pomocna promenna pro 1 znak
// Inicializace portu
output_a(0); // vsechny porty vystupni
output_b(0); // a nulove krome
output_float(RS_IN); // portu pro RS232 (a preruseni)
// Inicializace LCD
lcd_init(); // inicializace LCD
printf(lcd_putc,"LCD Terminal 1.0"); // standardni vypis
#ifdef INV
printf(lcd_putc,"\nInverted"); // oznameni o inverzni variante
#else
printf(lcd_putc,"\nStandard"); // oznameni o inverzni variante
#endif
delay_ms(300); // cas na precteni
printf(lcd_putc,"\f"); // smazani displeje
// Inicializace FIFO ukazatelu
ci=0;
co=0;
// Inicializace preruseni
#ifdef INV // dle polarity kominkace polarita preruseni
ext_int_edge(L_TO_H);
#else
ext_int_edge(H_TO_L);
#endif
enable_interrupts(int_ext); // povoleni preruseni od INT0
enable_interrupts(global); // povoleni globalniho preruseni
// Hlavni smycka
while (1)
{
// Test na neprazdny buffer
while (ci==co);
// Zobrazeni znaku
lcd_putc(c[co]);
// Posunuti ukazovatka
if (co<(MAX-1)) co++; else co=0;
}
}