/* **************************************************** */ /* 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); }