/* LCD.c
x LCD basati su HD44870
*/
#include “GenericTypeDefs.h”
#include “Compiler.h”
#include “hardwareprofile.h” //
#include “contatoregeiger.h”
#include <stdlib.h>
#include <timer.h>
#include <ctype.h>
#include <libpic30.h>
#include “lcd.h”
#define LCD_MAX_COLS 16
#define LCD_MAX_ROWS 2
void subLCDInit(void);
void subLCDget(void);
void SetBeep(void);
#pragma udata
BYTE LCDCols;
BYTE LCDRows;
BYTE LCDX;
BYTE LCDY;
BYTE LuceLCD; // mirrored in EEPROM
BYTE ContrLCD;
BYTE StatoLCD; // usato per indicare se il cursore è attivo (b0);
BYTE BeepFreq;
BYTE TimerBuzz;
BYTE FLAGS_ESC; // per sequenze ESCAPE: 0=SetLuce, 1=SetContr, 2=SetFreq; 3=SetLed; 4&5=SetXY (1&2); 6=SetKClick; 7=invert_bitmap
BYTE FLAGS;
extern WORD I2CAddr;
BYTE I2CData;
BYTE I2CCnt;
BYTE I2CCntB;
BYTE lcd_temp0; // usato dentro LCDOutCmd da 6963, in GetCharDef da KS0108
BYTE lcd_temp1; // temporanea, usata da LCD
BYTE lcd_temp2;
BYTE lcd_temp3;
BYTE LCDtmpBuf[40]; // temp per scroll display (almeno 40 BYTE), BANCO 1
//BYTE *iconptr; // temp. per icone/bigchar LCD
WORD iconptr; // temp. per icone/bigchar LCD
#define LCD_DELAY { Nop(); Nop(); Nop(); ClrWdt(); Nop(); Nop(); Nop(); Nop(); Nop(); Nop(); Nop(); Nop(); Nop(); Nop(); Nop(); Nop(); }
//#define LCD_DELAY Delay_uS(1);
// ———————————————————————
//lang_1: // italiano (in caso si volessero + lingue…)
const char CopyrDate[32] = {“12/03/12 – S/N 0001n” };
// messg “Numero di serie: SERNUM”
static const char Copyright[32] = { ‘P’,'I’,'C’,'B’,'e’,'l’,'l’,’ ‘,’f',’w',’ ‘,’v',VERNUMH+’0′,’.',VERNUML/10+’0′,(VERNUML % 10)+’0′,0 };
// dt ”ADPM Synthesis – Terminale grafico USB “
// dt VERNUMH+’0′,’.',VERNUML/10+’0′,(VERNUML % 10)+’0′, ‘ ‘
// dt “08/04/05″,0
const char *CopyrString=Copyright;
static const char *Copyr1= { “(C) Cyberdyne 2009-2012; ADPM Synthesis 1999-2008 – G.Darn” };
const char String1_l1[32] = { “Cyberdyne” /*”ADPM Synthesis”*/ /* ” K-tronic sas” */ };
const char String2_l1[] = { ’ ‘,’P',’I',’C',’B',’e',’l',’l',’ ‘,’v',VERNUMH+’0′,’.',VERNUML/10+’0′,(VERNUML % 10)+’0′,’ ‘,0 };
//static const char String2_l1[] = { ’S',’k',’y',’N',’E',’T',’ ‘,’v',VERNUMH+’0′,’.',VERNUML/10+’0′,(VERNUML % 10)+’0′,’ ‘,0 };
const char String3_l1[2] =
{ ‘_’,0 }; // icona splash-screen ?
const BYTE LUTLuce[16]= { 0,1,2,3, 4,5,7,8, 10,12,14,18, 20,24,28,32 };
void aggLuceContrasto(void) {
WORD w;
// PR2=BeepFreq;
w = LUTLuce[LuceLCD & 0xf];
w *= 1000; // quasi-100%, tanto per
// …moltiplico per Luce (ossia il DutyCycle voluto)…
// divido per 32 (v. tab luce)…
// SetDCOC1PWM(w /* /32 */,BeepFreq); // FINIRE
// …il risultato nel timer
OC4R=w;
// SetDCOC2PWM(ContrLCD * 4,BeepFreq); // FINIRE
}
// ———————————————————————
void print_init(void) {
LCDCls();
LCDX= (LCD_MAX_COLS-14)/2; // “skynet/picbell vx.xx”: 16 char
LCDXY(0); // X,Y=[2,1]
#if LCD_MAX_ROWS>1
LCDWrite(String2_l1);
LCDX=(LCD_MAX_COLS-10)/2; // “cyberdyne”: 10 char
LCDXY(1); // X,Y=[3,2]
LCDWrite(String1_l1);
if(!sw1) {
LCDPrintLF();
#if LCD_MAX_ROWS>2
LCDPrintHex(LuceLCD);
LCDPrintHex(ContrLCD);
LCDPrintLF();
#else
LCDPrintHex(LuceLCD);
#endif
return;
}
// LCDWrite(String3_l1);
#else
LCDWrite(String2_l1);
#endif
}
// ———————————————————————
void LCDPutChar(BYTE ch) {
static BYTE parm1,parm2,nparms;
if(FLAGS & (1 << IN_ESCAPE_CHAR)) {
if(FLAGS_ESC & 1) {
FLAGS_ESC=0;
FLAGS &= ~(1 << IN_ESCAPE_CHAR);
EEscrivi_(&LuceLCD,ch-1); // 1..16
aggLuceContrasto();
return;
}
if(FLAGS_ESC & 2) {
FLAGS_ESC=0;
FLAGS &= ~(1 << IN_ESCAPE_CHAR);
EEscrivi_(&ContrLCD,ch-1); // 1..16
aggLuceContrasto();
return;
}
if(FLAGS_ESC & 4) {
FLAGS_ESC=0;
FLAGS &= ~(1 << IN_ESCAPE_CHAR);
// minimo 32 (v. PWM luce) (circa 10KHz per buzzer)
BeepFreq= ch < 32 ? 32 : ch;
aggLuceContrasto();
return;
}
if(FLAGS_ESC & {
FLAGS_ESC=0;
FLAGS &= ~(1 << IN_ESCAPE_CHAR);
// LATE = ch & 0xf; // OCCHIO!
return;
}
if(FLAGS_ESC & 0×10) {
// http://ascii-table.com/ansi-escape-sequences-vt-100.php
if(isdigit(ch)) { // set xy ESC [ x;y f/H
if(!nparms)
parm1=ch; //NO! usare atoi... su + char...
if(nparms==1)
parm2=ch; //NO! usare atoi... su + char...
nparms++;
}
else {
if(ch=='m') {
// if(nparms)
// bigFont=parm1 & 1;
}
if(ch=='f' || ch=='H') {
if(nparms>1) {
LCDY = parm1;
LCDX = parm2;
LCDXY_();
}
}
if(ch=='j') {
if(nparms && parm1=='2' /*sistemare!*/)
LCDCls();
}
FLAGS_ESC=0;
nparms=0;
FLAGS &= ~(1 << IN_ESCAPE_CHAR);
}
return;
}
if(FLAGS_ESC & 0x20) {
if(ch & 1)
FLAGS &= ~(1 << NOKCLICK);
else
FLAGS |= (1 << NOKCLICK);
return;
}
switch(ch) {
case 17: // v. sopra
FLAGS_ESC |= 1;
break;
case 18: // un po' a caso...
FLAGS_ESC |= 2;
break;
case 7: // come "BEL"
FLAGS_ESC |= 4;
break;
case 19: // v. sopra
FLAGS_ESC |= 8;
break;
case 91: // vagamente ANSI... (VT100 dice: "ESC [ ROW ; COLUMN f" , e simili...
FLAGS_ESC |= 0x10;
nparms=0;
break;
}
if(!FLAGS_ESC) // se non e' stato trovato nessun char. accettabile, tolgo QUI ESC!
FLAGS &= ~(1 << IN_ESCAPE_CHAR);
return;
}
if(ch >= ' ') {
if(ch & 0x80) // i caratteri >=0x80 sono usati per i char user-defined...
ch &= 0x7f; // ...banalmente, se solo testo, li riporto al valore in LCD
LCDOutData(ch);
LCDX++;
if(LCDX >= LCDCols)
goto LCDPrintLF;
/*
if(LCDRows == 1) {
if(LCDX ==
LCDXY_();
} per 1-riga, v. anche LCDXY e frequanzimetro
*/
}
else {
switch(ch) {
case 2:
StatoLCD |= 1;
LCDCursor(3); // STX=cursor On
break;
case 3:
StatoLCD &= 0xfe; // ETX=cursor Off
LCDCursor(0);
break;
case 7:
// call StdBeep ; resa ASINCRONA (per velocita' I2C e anche SER)!
SetBeep();
break;
case 9:
LCDtab:
LCDX++;
LCDOutBlankRaw(); // meglio non LCDPutBlank, per lo stack!
// così però non gestisce l'a-capo...
if(LCDX & 7)
goto LCDtab;
break;
case 11:
LCDScrollDown();
break;
case 12: // FF = scroll up
LCDScrollUp();
break;
case 10: // LF
LCDPrintLF:
LCDX=0;
LCDY++;
// METTERE un FLAG per disattivare scroll automatico (CHR$13) su ultima riga, per sfruttarla meglio??
LCDScroll(); // scroll SE necessario
break;
case 13: // CR
LCDX=0;
LCDXY_();
break;
case 14: // shift-in (cursor left)
LCDOutCmd(16);
break;
case 15: // shift-out (cursor right)
LCDOutCmd(20);
break;
case 8: //; BS
if(LCDX) { // solo se X>0...
LCDX--;
LCDOutCmd(16);
LCDOutBlankRaw();
LCDOutCmd(16);
}
break;
case 17: // DC1..2 usati per Luce LCD
LuceLCD=15;
LCDPC_NoPrint_17_:
// EEcopiaAEEPROM(&LuceLCD);
aggLuceContrasto(); // occhio allo stack...!
break;
case 18:
LuceLCD=0;
goto LCDPC_NoPrint_17_;
break;
case 19: // DC3..4 usati per Led on/off
mLED_1=1;
// LED1_IO=1;
break;
case 20:
mLED_1=0;
break;
case 24: // CAN (opp. FormFeed ?) = CLS
LCDCls();
break;
case 27: // ESC (comandi ausiliari)
FLAGS |= (1 << IN_ESCAPE_CHAR);
break;
default:
// LCDPut1: eliminato, eqv. a return
break;
}
}
}
// ---------------------------------------------------------------------
void LCDXY_(void) {
BYTE i,lcd_temp2;
lcd_temp2=0;
switch(LCDRows) {
case 1:
if(LCDRows == 1 && LCDX >= { // patch x 1 riga... (v. anche PutChar)
LCDOutCmd(0xc0 | (LCDX & 7));
return;
}
else {
LCDXY1:
i=LCDX & 0x7f;
i+=lcd_temp2;
LCDOutCmd(i | 0x80);
}
if(LCDX & 0x80) {
LCDX &= 0x7f;
LCDX-=LCDCols;
}
break;
case 2:
LCDXY2:
lcd_temp2=(LCDY & 1) * 0x40;
goto LCDXY1;
break;
case 4:
if(LCDCols < 40) { // se e' 4x40 (M4024) va bene cosi' (hanno 2 ENABLE)...
if(LCDY >= 2) { // ...altrimenti (4x20), se la riga e' 2 opp. 3...
LCDX+=LCDCols; // ...aggiungo a X la larghezza (16 opp. 20)
LCDX |= 0x80; //e me lo segno per poi ri-toglierla!
}
}
goto LCDXY2;
break;
default: // NON DEVE succedere!
break;
}
}
// ---------------------------------------------------------------------
void subLCDInit(void) {
LCDOutPort4Bit(0x3); // init 1st 4 bit!
Delay_mS(5); // >4.1mS
LCDOutPort4Bit(0x3); // init 2nd
Delay_mS(1); // >100uS
LCDOutPort4Bit(0x3); // init 3rd
Delay_mS(1); // >39uS
LCDOutPort4Bit(0x2); //
Delay_mS(1); //
LCDOutCmd(0b00101000); // function Set 0010NF** 4bit!
LCDOutCmd(0b00001100); // display ON/OFF = 00001DCB, Display ON,Cursor&Blink OFF
// entry Mode Set = 000001IS, increment & shift off
LCDOutCmd(0b00000110); // cursore, blink e ON/OFF
}
const BYTE LCDUserDefChar[7][8]={
// { 0b00000110,0b00001001,0b00011100,0b00001000,0b00011100,0b00001001,0b00000110,0b00000000 }, // EURO no qua
{ 0b00000000,0b00000000,0b00000001,0b00000011,0b00000111,0b00001111,0b00011111,0b00000000 }, //1=triang. dx (v. pag 77 rivista)
{ 0b00000100,0b00001110,0b00001110,0b00011111,0b00000000,0b00000000,0b00000000,0b00000000 }, //2=allarme
{ 0b00000000,0b00000000,0b00000011,0b00000111,0b00001111,0b00000111,0b00000011,0b00000000 }, //3=PC/232 conn.
{ 0b00000000,0b00000000,0b00011011,0b00010010,0b00011010,0b00001010,0b00011011,0b00000000 }, //4=SD card
{ 0b00000000,0b00000100,0b00001110,0b00001110,0b00001110,0b00001110,0b00001110,0b00000000 }, //5=batt. piena
{ 0b00000000,0b00000100,0b00001010,0b00001010,0b00001010,0b00001010,0b00001110,0b00000000 }, //6=batt. vuota
{ 0b00000000,0b00001010,0b00011011,0b00011111,0b00000100,0b00001110,0b00011111,0b00000000 }, //7=radioactive
//purtroppo ce ne sono solo 8!
};
void subLCDdefChar(void) {
BYTE x,y;
LCDOutCmd(0×48); // definisco char user-def partendo da 1 (non 0!)
for(y=0; y<7; y++) { // parametrizzare!!!
for(x=0; x<8; x++) {
LCDOutData(LCDUserDefChar[y][x]);
}
}
}
BYTE LCDInit(void) {
LCDY=0;
Delay_mS(15); // 15mS
subLCDInit();
subLCDdefChar();
#if !defined(__PIC24FJ128GA106__) && !defined(__PIC24FJ256GA106__)
// OpenOC1(OC_IDLE_CON & OC_TIMER4_SRC /* & CMP_FAULT2_IN_DISABLE */ /* & OC_FAULT1_IN_DISABLE */ & OC_PWM_FAULT_CLEAR & OC_TRIG_CLEAR_SYNC & OC_CONTINUE_PULSE,
// OC_FAULT_MODE_PWM_CYCLE & OC_PWM_FAULT_OUT_HIGH & OC_FAULT_PIN_UNCHANGE & OC_OUT_NOT_INVERT & OC_CASCADE_DISABLE /* & OC_SYNC_ENABLE */ & OC_UNTRIGGER_TIMER & OC_DIRN_TRIS & OC_SYNC_TRIG_IN_DISABLE,
// 0,0);
// OpenOC2(OC_IDLE_CON & OC_TIMER4_SRC /* & CMP_FAULT2_IN_DISABLE */ /* & OC_FAULT1_IN_DISABLE */ & OC_PWM_FAULT_CLEAR & OC_TRIG_CLEAR_SYNC & OC_CONTINUE_PULSE,
// OC_FAULT_MODE_PWM_CYCLE & OC_PWM_FAULT_OUT_HIGH & OC_FAULT_PIN_UNCHANGE & OC_OUT_NOT_INVERT & OC_CASCADE_DISABLE /* & OC_SYNC_ENABLE */ & OC_UNTRIGGER_TIMER & OC_DIRN_TRIS & OC_SYNC_TRIG_IN_DISABLE,
// 0,0);
#else
// OCCHIO CHE SU GA questa sopra non funziona!
// sembra mappare erroneamente sulle funzioni “_GB” che poi non vanno. usare accesso ai registri diretti
#endif
/* Reset PWM */
OC4CON1 = 0×0000;
OC4CON2 = 0×0000;
/* set PWM duty cycle to 50% */
OC4R = 16384 /* basato su SysClock => 500Hz (16MHz / 32768) */; //PWM_PERIOD >> 1; /* set the duty cycle tp 50% */
OC4RS = 32768 /* se uso Timer come Src SEMBRA NON FARE NULLA… qua boh! */; //PWM_PERIOD – 1; /* set the period */
/* configure PWM */
OC4CON2 = 0x001f; /* 0x001F = Sync with This OC module */
OC4CON1 = 0x1c00 /* 0×0400 => src=Timer3 */; /* 0x1C08 = Clock source Fcyc, trigger mode 1, Mode 0 (disable OC1) */
/* enable the PWM */
OC4CON1 |= 0×0006; /* Mode 6, Edge-aligned PWM Mode */
//v. anche PPS
LuceLCD=8;
ContrLCD=12;
LCDRows=LCD_MAX_ROWS; // PARAMETRIZZARE (da FLASH?)
// cp 3
// jp m,LCDInit2
// movlw 2
// movwf LCDY
// call subLCDInit
LCDCols=LCD_MAX_COLS; // PARAMETRIZZARE (da FLASH?)
LCDCls();
return 1;
}
// CONTINUA
// ———————————————————————
void LCDCls(void) {
// movfw LCDRows
// cp 3
// jp m,LCDCls1
// ld a,2
// ld (LCDY),a
// dec a
// call LCDOutPort
LCDX=0;
LCDY=0;
// bcf STATUS,C
LCDOutCmd(1);
// CONTINUA ; cls & home (comando 1)
}
// ———————————————————————
BYTE LCDOutPort(BYTE c, BYTE n) { // scrivo W nel display
// dato se C=1, comando se C=0
BYTE t;
m_LCDRWBit=1; // torno in lettura
m_LCDRSBit=0; // preparo per leggere Flag
lcd_temp1=0;
LCD_DELAY;
#ifndef __DEBUG
while(1) {
// clrwdt ; incorporato in LCD_DELAY
m_LCDEnBit=1; // scrivo!
LCD_DELAY;
t=PORTB & 0×8; // esco se b7=0
m_LCDEnBit=0;
LCD_DELAY;
m_LCDEnBit=1; // scrivo! cmq secondo nibble!
LCD_DELAY;
m_LCDEnBit=0;
LCD_DELAY;
if(!t) // esco se b7=0
break;
// decf lcd_temp1,f
// bz LCDDelay1_err
}
#endif
LCDDelay1_err:
LCDOut1:
m_LCDEnBit=0; // rimetto cmq a posto EN…
return LCDOutPortNoW(c,n);
}
BYTE LCDOutPortNoW(BYTE c,BYTE n) { // qui per non aspettare BUSY!
if(c)
m_LCDRSBit=1; // C=1, dato
else
m_LCDRSBit=0; // C=0, comando
m_LCDRWBit=0; // vado in scrittura
TRISB &= ~0b00001111;
LCD_DELAY;
m_LCDEnBit=1; // scrivo!
LCD_DELAY;
LATB &= ~0b00001111;
LATB |= ((n >> 4) & 0x0f); // nibble H, shift 4 a dx
LCD_DELAY;
m_LCDEnBit=0;
LCD_DELAY;
LCD_DELAY;
m_LCDEnBit=1; // scrivo!
LCD_DELAY;
LATB &= ~0b00001111;
LATB |= ((n & 0x0f) ); // nibble L, shift 0 a sx
LCD_DELAY;
m_LCDEnBit=0;
LCD_DELAY;
TRISB |= 0b00001111;
m_LCDRWBit=1; // torno in lettura
m_LCDRSBit=1;
return n;
}
BYTE LCDOutPort4Bit(BYTE n) {
m_LCDRSBit=0; // C=0, comando
m_LCDRWBit=0; // vado in scrittura
TRISB &= ~0b00001111;
LCD_DELAY;
m_LCDEnBit=1; // scrivo!
LCD_DELAY;
LATB &= ~0b00001111;
LATB |= ((n & 0x0f) ); // nibble L, shift 0 a sx
LCD_DELAY;
m_LCDEnBit=0;
LCD_DELAY;
TRISB |= 0b00001111;
m_LCDRWBit=1; // torno in lettura
return n;
}
void LCDOutBlankRaw(void) {
char c;
c=’ ‘;
LCDOutData(c);
}
// ———————————————————————
void LCDWrite(const char *p) {
while(*p)
LCDPutChar(*p++);
}
void LCDWriteN(const char *p, BYTE n) {
do {
LCDPutChar(*p++);
} while(–n);
}
// ———————————————————————
void subLCDget(void) {
BYTE *p;
BYTE i,lcd_temp1,t;
p=LCDtmpBuf;
for(i=0; i<LCDCols; i++) {
m_LCDRSBit=0; // preparo per leggere Flag
m_LCDRWBit=1; // vado in lettura
TRISB |= 0b00001111;
lcd_temp1=0;
while(1) {
m_LCDEnBit=1; // strobe!
LCD_DELAY
t=PORTB & 0×8; // esco se b7=0
m_LCDEnBit=0;
LCD_DELAY
m_LCDEnBit=1; // strobe! cmq 2 nibble
LCD_DELAY
m_LCDEnBit=0;
LCD_DELAY
if(!t) // esco se b7=0
break;
// decf lcd_temp1,f
// bz subLCDg3_err
}
subLCDg3_err:
m_LCDRSBit=1; // dato
LCD_DELAY
m_LCDEnBit=1; // leggo!
LCD_DELAY
Nop();
Nop();
t=PORTB << 4; // nibble hi
t &= 0xf0;
*p=t;
Nop();
Nop();
Nop();
m_LCDEnBit=0;
LCD_DELAY
LCD_DELAY
m_LCDEnBit=1; // leggo!
LCD_DELAY
Nop();
Nop();
t=PORTB >> 0;
t &= 0xf;
*p++ |= t;
Nop();
Nop();
Nop();
m_LCDEnBit=0;
LCD_DELAY
}
}
void LCDScroll(void) {
BYTE i,*p;
BYTE lcd_temp4;
if(LCDRows > 1) { // se 1 riga, niente scroll!
goto skippa; // QUA NO! e mettere ev. il flag di no scroll, v. sopra
if(LCDY == LCDRows) {
LCDScrollUp:
for(lcd_temp4=0; lcd_temp4<(LCDRows-1); lcd_temp4++) { // riga corrente
lcd_temp4++;
i= lcd_temp4 & 1 ? 0×40 : 0; // calcolo posizione della riga source
i+= lcd_temp4 & 2 ? LCDCols : 0;
LCDOutCmd(i | 0×80);
subLCDget();
lcd_temp4–;
i= lcd_temp4 & 1 ? 0×40 : 0; // calcolo posizione della riga dest
i+= lcd_temp4 & 2 ? LCDCols : 0;
LCDOutCmd(i | 0×80);
p=LCDtmpBuf;
for(i=0; i<LCDCols; i++)
LCDOutData(*p++);
// se c’e’ clock attivo su prima riga, limitare lo scroll?
}
LCDY–;
LCDClearCurrentLine();
}
skippa:
LCDXY_();
}
}
void LCDScrollDown(void) {
BYTE i,*p;
BYTE lcd_temp4;
lcd_temp4=LCDRows-1; // riga corrente
do {
lcd_temp4–;
i= lcd_temp4 & 1 ? 0×40 : 0; // calcolo posizione della riga source
i+= lcd_temp4 & 2 ? LCDCols : 0;
LCDOutCmd(i | 0×80);
subLCDget();
lcd_temp4++;
i= lcd_temp4 & 1 ? 0×40 : 0; // calcolo posizione della riga dest
i+= lcd_temp4 & 2 ? LCDCols : 0;
LCDOutCmd(i | 0×80);
p=LCDtmpBuf;
for(i=0; i<LCDCols; i++)
LCDOutData(*p++);
// se c’e’ clock attivo su prima riga, limitare lo scroll?
} while(–lcd_temp4);
LCDY=0;
LCDClearCurrentLine();
LCDXY_();
}
void LCDPrintHex(BYTE w) { // stampa in HEX il BYTE in W
BYTE n;
n=(w >> 4) & 0xf;
if(n>=10)
n+=7;
LCDPutChar(n+’0′);
n=w & 0xf;
if(n>=10)
n+=7;
LCDPutChar(n+’0′);
LCDPutBlank();
}
void LCDPrintDec2(BYTE n) { // stampa BYTE in W come decimale a 2 cifre (’0′ trailing)
char myBuf[4];
itoa(myBuf,n,10); // C30 ce l’ha a cazzo!
LCDOutData(myBuf[0]);
LCDOutData(myBuf[1]);
}
void LCDClearLine(BYTE n) { // entra n=linea da pulire
BYTE temp;
LCDX=0;
LCDXY(n);
temp=LCDCols;
while(temp–) {
LCDOutBlankRaw();
}
LCDXY_(); // in caso servisse, sono a inizio riga!
}
// —————————————————————————-
// ————————————————————————-
#if PIXEL_PER_CELLA==6
BYTE drawLineaVertTable[8]= { 0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xfd,0xfc };
// movlw 11111101b ; SetBit (su 6…)
#else
BYTE drawLineaVertTable[8]= { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8 };
// movlw 11111101b ; SetBit (su 8…)
#endif
void drawLinea(BYTE x1,BYTE y1,BYTE x2,BYTE y2) { // entrano coord. (lcd_temp2:lcd_temp3) (lcd_temp4:lcd_temp5)
// le X VENGONO ALTERATE!
// alla fine si fa LCDXY per rimettere l’addr ptr a posto per il testo…
// BYTE temp;
// WORD bPos;
// BYTE lcd_temp5;
}
void drawRect(BYTE x1,BYTE y1,BYTE x2,BYTE y2,BYTE w) {
// entrano coord. (lcd_temp6:lcd_temp7) (lcd_temp8:lcd_temp9); W=0 se vuoto, 1 se pieno, 2=grigio
}
void SetBeep(void) { // asincrono, viene poi resettato da interrupt
// PR2=BeepFreq;
// CCPR1L=BeepFreq >> 1; // /2 (duty cycle 50%)
// SetDCOC3PWM(BeepFreq,BeepFreq>>1);
// TRISBbits.TRISB9=0;
// movlw 00000111b
// movwf T2CON
TimerBuzz=2;
}
/*
char *itoa(int i,char *buffer) {
unsigned int n;
unsigned char negate = 0;
int c = 6;
if(i < 0) {
negate=1;
n = -i;
}
else if(i == 0) {
buffer[0] = ’0′;
buffer[1] = 0;
return buffer;
}
else {
n = i;
}
buffer[c--] = 0;
do {
buffer[c--] = (n % 10) + ’0′;
n = n / 10;
} while (n);
if(negate) {
buffer[c--] = ‘-’;
}
return &buffer[c+1];
}
*/