/* **************************************************** */
/* Intel 80C552 - system IMM552 */
/* Definicny subor (adresy, spec.registre a biy */
/* **************************************************** */
#define TRUE 1
#define FALSE 0
#define CTRL 0x12
#define DATA 0x1A
#define WDINT 0 /* interval WD 1.57s */
#define DISP ((char *)0x28200L)[0] /* adresa displeja */
#define RWM ((char *)0x22000L) /* adresa RAM-ky */
#define RTC ((char *)0x24000L) /* adresa RT Clock */
/* definicie pre 8255 */
#define XBYTE ((char *)0x20000L)
#define CW55 0x90 /* PA-vstup, PB,PC-vystup */
#define PA55 0xF800
#define PB55 0xF801
#define PC55 0xF802
#define CR55 0xF803 /* Riadiaci register */
#if !defined reg552.h
/* adresy registrov specialnych funkcii */
sfr B = 0xF0;
sfr P1 = 0x90;
sfr P3 = 0xB0;
sfr P4 = 0xC0;
sfr P5 = 0xC4;
sfr T3 = 0xFF;
sfr PCON = 0x87;
sfr ADCH = 0xC6;
sfr ADCON= 0xC5;
#endif
/* **************************************************** */
/* Riadiace signaly displeja */
/* P1.7 je RS (Register Select) 0=registre, 1=RAMka */
/* R/W (Read/Write) je trvale 0 */
/* t.j. neda sa citat BUSY flag! */
/* E (Enable) je aktivovane adresou 8200H */
/* **************************************************** */
sbit D_RS = P1^7;
/* **************************************************** */
/* Reset WD timera, volat v riadiacom algoritme */
/* **************************************************** */
void wd(void)
{ PCON|=0x10; T3=WDINT; }
/* **************************************************** */
/* */
/* wait(n) */
/* */
/* Oneskorenie n*100us */
/* (plati pre krystal 4 alebo 11.0592MHz) */
/* **************************************************** */
void wait(n)
unsigned char n;
{ unsigned char i,ii;
for(ii=0;ii<n;ii++)
for(i=0;i<24;i++);
}
/* **************************************************** */
/* Funkcie pre obsluhu displeja a zobrazovanie */
/* **************************************************** */
/* **************************************************** */
/* */
/* Disp_send(Byte,Reg); */
/* */
/* posle na displej byte "a_" a nastavi signaly "b_" */
/* **************************************************** */
void Disp_send(char a_,char b_)
{
XBYTE[PB55]=a_; /* prepisane z Basic-u */
wait(1);
XBYTE[PC55]=b_;
wait(1);
XBYTE[PC55]=0;
wait(1);
}
/* **************************************************** */
/* */
/* Disp_ini8() */
/* */
/* Inicializacia displeja 8-bitovo */
/* P1.7 = Register Select */
/* **************************************************** */
void Disp_ini8(void)
{
XBYTE[CR55]=CW55; // inicializuj 8255
Disp_send(0x00,0x00); //Reset
wait(150); // po zapnuti cakaj 15ms
Disp_send(0x30,0x12); // 0 0 1 1 x x x x
wait(46); // cakaj 4.6ms
Disp_send(0x30,0x12); // a posli znova 0011 xxxx
wait(1); // cakaj 0.1ms
Disp_send(0x30,0x12); // a posli znova 0011 xxxx
wait(1);
Disp_send(0x38,0x12);
// 0 0 1 1 1 0 x x
// | | |_ F=0: font 7x5
// | |___ N=1: dva riadky
// |______ DL=1: 8 bitov
wait(1);
Disp_send(0x08,0x12);
// 0 0 0 0 1 0 0 0
// display OFF
wait(1);
Disp_send(0x01,0x12);
// 0 0 0 0 0 0 0 1
// clear & cursor home
wait(17);
Disp_send(0x06,0x12);
// 0 0 0 0 0 1 1 0
// |__ I/D: 1=Increment 0=Decrement
// set shift mode
}
/* **************************************************** */
/* */
/* Disp_clr(); */
/* */
/* zmaze displej, kurzor vrati na zaciatok 1. riadku */
/* **************************************************** */
#define Disp_clr(); { Disp_send(0x01,0x12); wait(17); }
/* **************************************************** */
/* */
/* Disp_on(); */
/* */
/* zapni displej a kurzor, vypni blikanie kurzora */
/* DISP = 0 0 0 0 1 D C B */
/* B: 1=ON 0=OFF (Blinkng cursor) */
/* C: 1=ON 0=OFF (Cursor On/Off ) */
/* D: 1=ON 0=OFF (Display On/Off) */
/* **************************************************** */
#define Disp_on(); Disp_send(0x0C,0x12);
/* **************************************************** */
/* */
/* Disp_text(text,row,pos) */
/* */
/* zobraz na displeji "text" v riadku "row" (1/2) */
/* pozicii "pos" (0-F) */
/* **************************************************** */
void Disp_text(text,row,pos)
char text[];
unsigned char row,pos;
{
unsigned char i;
Disp_send(0x40*(row-1)+pos+0x80,0x12); // pozicia na displeji
i=0;
while (text[i]!='\0')
Disp_send(text[i++],0x1A);
}
/* **************************************************** */
/* */
/* Disp_int(numb,row,pos) */
/* */
/* vypis cisla "numb" (0-99999) na displej */
/* do riadku "row" a od pozicie "pos" vlavo */
/* - nevyznamne nuly sa nepotlacaju */
/* **************************************************** */
void Disp_int(numb,row,pos)
unsigned int numb;
unsigned char row, pos;
{
unsigned int tmp,exp;
Disp_send(0x40*(row-1)+pos+0x80,CTRL); //pozicia na displeji
for(exp=10000;exp>=1;exp=exp/10)
{ tmp = numb/exp;
Disp_send(tmp+'0',DATA); // zapis vyssi rad
numb -= tmp*exp;
}
}
/* **************************************************** */
/* */
/* Disp_char(byte,row,pos) */
/* */
/* zobraz na displeji "byte" v riadku "row" (1/2) */
/* pozicii "pos" (0-F) */
/* **************************************************** */
void Disp_char(byte,row,pos)
unsigned char byte,row,pos;
{
unsigned char tmp;
Disp_send(0x40*(row-1)+pos+0x80,0x12); // pozicia na displeji
tmp = byte>>4;
tmp = (tmp<10 ? tmp+'0' : tmp+'7');
Disp_send(tmp,0x1A);
tmp = byte&0x0F;
tmp = (tmp<10 ? tmp+'0' : tmp+'7');
Disp_send(tmp,0x1A);
}
/* **************************************************** */
/* */
/* Kb_read() */
/* */
/* precita hodnotu z klavesnice 0: nic, 1-16: klavesa */
/* 255: error - prepisane z Basic-u */
/* ak je stlacena viac ako jedna, vrati len najnizsiu */
/* **************************************************** */
char Kb_read(void)
{
unsigned char a,b,c,i;
XBYTE[0xF802] = 0xF1; // odpoji displej
a=c=0;
do {
for(b=1,i=0;i<a;i++,b*=2);
XBYTE[0xF801] = b;
b = XBYTE[0xF800];
if ((c!=0)&&(b!=0)) c=255;
else switch (b) {
case 0: break;
case 1: c=13+a;
break;
case 2: c=9+a;
break;
case 4: c=5+a;
break;
case 8: c=1+a;
break;
default: c=255; };
a++;
} while (!((c==255) || (a>3)));
return (c);
}
/* ******************************************************* */
/* */
/* AD_measure(channel) */
/* */
/* Get A/D "channel" measured value */
/* ******************************************************* */
unsigned int AD_measure (unsigned char channel)
{
unsigned int tmp;
ADCON = 0x00; /* triggering SW, do not convert */
ADCON|= channel; /* select A/D channel */
ADCON |= 0x08; /* and start measurement */
wait(1);
while (ADCON&0x08); /* wait until measurement ready */
ADCON &= 0xef; /* clear interrupt flag */
return ( ADCH*4 + ((ADCON >>6)&0x03) );
}
/* Nasledovnu konstrukciu */
/* sbit AD_BUSY = ADCON^4; */
/* nemozme pouzit, pretoze ADCON */
/* nie je bitovo adresovatelny !!! */
void Disp_c(byte,row,pos)
unsigned char byte,row,pos;
{
Disp_send(0x40*(row-1)+pos+0x80,0x12); // pozicia na displeji
Disp_send(byte,0x1A);
}