codice:
//_________________________________________________________________
//40x4 LCD Subroutines by Atilla Demiray
#include <dos.h>
#include <stdarg.h>
#include <stdio.h>
#include <windows.h>
/* ----Prototypes of Inp and Outp--- */
short _stdcall Inp32(short PortAddress);
void _stdcall Out32(short PortAddress, short data);
#define NULL 0
//8 bit unsigned data type
typedef unsigned char byte;
//1 bit data
typedef bool bit;
//struct containing lcd status info
struct l_c_d{
byte cursor;
byte x;
byte y;
bit cursor_on;
};
//class LCD
class lcd{
public:
lcd(void);//constructor
l_c_d getxy(void); //l_C_D is a struct containing x,y,cursor,cursor_on elements
void gotoxy(byte,byte);//to locate cursor at x,y: x=0-39,y=0-3
void set_cursor(byte);//locate cursor by direct coordinate d=40*y+x
void putsxy(byte,byte,char*);//put string starting x,y
void printfxy(byte,byte,char*,...);//print formated string starting x,y, works like printf
void clr_desired_area(byte,byte,byte,byte,char);//fill desired area with a char
void putcxy(byte,byte,char);//put a char in x,y
void cursor_on_off(bit);//cursor on/off: 1=on, 0:off
private:
l_c_d lcdisplay;//structure to store lcd status info
void E_1(bit);//pin E1 on/off
void E_2(bit);//pin E2 on/off
void R_S(bit);//pin RS on/off
void R_W(bit);//pin RW on/off
void D_T(byte);//put 8 bit data in databus
void E(bit);//set enable according to cursor
void calculate_xy(void);//calculate x,y from direc cursor location
void cmd(byte);//send a command to lcd
void dat(byte);//send a char to lcd
};
//constructor function that is called at the start
//initializes lcd
lcd::lcd(void)
{
byte i;
Out32(0x0103,0x80);//ppi mode 0
for(i=0;i<2;i++)
{
if(i==0)lcdisplay.cursor=0;else lcdisplay.cursor=80;
E(0);
R_W(0);
R_S(0);
cmd(0x38);
cmd(0x38);
cmd(0x06);
cursor_on_off(0);
cmd(0x01);
cmd(0x80);
}
lcdisplay.cursor=0;
lcdisplay.x=0;
lcdisplay.y=0;
}
//function to export l_c_d status info
l_c_d lcd::getxy(void)
{
return lcdisplay;
}
//function to locate cursor
//x:0-39
//y:0-3
void lcd::gotoxy(byte x, byte y)
{
byte b;
bit c=lcdisplay.cursor_on;
cursor_on_off(0);
lcdisplay.cursor=y*40+x;
if(y==0||y==2) b=0x80;else if(y==1||y==3) b=0xC0;
cmd(b+x);
calculate_xy();
cursor_on_off(c);
}
void lcd::set_cursor(byte x)
{
if(x>159) return;
lcdisplay.cursor=x;
calculate_xy();
gotoxy(lcdisplay.x,lcdisplay.y);
}
//function to write a string starting x,y
void lcd::putsxy(byte x,byte y,char *str)
{
bit c=lcdisplay.cursor_on;
byte ch,k=0;
cursor_on_off(0);
gotoxy(x,y);
while((ch=(byte)*(str+k++))!=NULL) dat(ch);
calculate_xy();
cursor_on_off(c);
}
//function to print formated string starting x,y
//works like printf
void lcd::printfxy( byte x, byte y, char* string, ... )
{
va_list parameter;// Parameter list for VA_... macros
char stngbuf[255];// Buffer for formatted string
va_start( parameter, string );// Convert parameters
vsprintf( stngbuf, string, parameter );// Format
putsxy( x, y, stngbuf);//display
}
//function to fill a desired area of the screen with the charachter 'ch'
//area starts at x1,y1 and ends at x2,y2
//before return, cursor is located at x1,y1
void lcd::clr_desired_area(byte x1, byte y1, byte x2, byte y2,char ch)
{
bit cu=lcdisplay.cursor_on;
byte k;
byte xs,ys;
byte p1=y1*40+x1;
byte p2=y2*40+x2;
byte c;
cursor_on_off(0);
if(p1>p2) {c=p1-p2;xs=x1;ys=y1;} else {c=p2-p1;xs=x2;ys=y2;}
gotoxy(xs,ys);
++c;
for(k=0;k<c;k++) dat(ch);
gotoxy(xs,ys);
calculate_xy();
cursor_on_off(cu);
}
//function to put a char at x,y
void lcd::putcxy(byte x,byte y,char c)
{
bit cu=lcdisplay.cursor_on;
cursor_on_off(0);
gotoxy(x,y);
dat(c);
calculate_xy();
cursor_on_off(cu);
}
//function to activate and inactivate blinking cursor
void lcd::cursor_on_off(bit x){
byte crs;
//if cursor off
if(!x)
{
cmd(0x0C);
lcdisplay.cursor_on=0;
}
else
{ //if on
//first disable the cursor of the other half
//otherwise you can see two cursors on the screen
crs=lcdisplay.cursor;
if(crs<80) lcdisplay.cursor=80;else lcdisplay.cursor=0;
calculate_xy();
cmd(0x0C);
//now set the cursor of corresponding part of the lcd
lcdisplay.cursor=crs;
calculate_xy();
cmd(0x0F);
lcdisplay.cursor_on=1;
}
}
//ALL THE FUNCTIONS BELOW ARE I/O FUNCTIONS
//CONTROLING CORRESPONDING I/O LINES
// E1=I17
void lcd::E_1(bit x){if(x) Out32(0x0101,0x80|(Inp32(0x101))); else Out32(0x0101,0x7F&Inp32(0x101));}
// E2=I23
void lcd::E_2(bit x){if(x) Out32(0x0102,0x08|(Inp32(0x102))); else Out32(0x0102,0xF7&Inp32(0x102));}
// RS=I25
void lcd::R_S(bit x){if(x) Out32(0x0102,0x20|(Inp32(0x102))); else Out32(0x0102,0xDF&Inp32(0x102));}
// RW=I24
void lcd::R_W(bit x){if(x) Out32(0x0102,0x10|(Inp32(0x102))); else Out32(0x0102,0xEF&Inp32(0x102));}
//Put the word x in the data bus
void lcd::D_T(byte x){Out32(0x0100,x);}
//set enable pin according to lcd_segment flag
void lcd::E(bit x){if(lcdisplay.cursor<80) E_1(x);else E_2(x);}
//this function is called by various functions
//to calculate x and y position from the cursor location info
void lcd::calculate_xy(void)
{
lcdisplay.y=lcdisplay.cursor/40;
lcdisplay.x=lcdisplay.cursor-lcdisplay.y*40;
}
//function to output a command word to lcd
void lcd::cmd(byte cmd)
{
E(0);
D_T(cmd);
R_S(0);
E(1);
E(0);
Sleep(1);
}
//function to output a data word to lcd
void lcd::dat(byte dat)
{
E(0);
D_T(dat);
R_S(1);
E(1);
E(0);
if(++lcdisplay.cursor==160){lcdisplay.cursor=0;cmd(0x80);}
if(lcdisplay.cursor==80)cmd(0x80);
Sleep(1);
}
//_________________________________________________________________
//here is the main() illusrating how to use some of the class functions
void main(void)
{
printf("Ok... let's go!!!");
//declare a l_c_d type that can keep all the status info
l_c_d lcd_info;
//declare a lcd class
lcd screen;
while(1){
//write a hello message starting (0,0)
screen.putsxy(0,0,"Hello world, this is a 40x4 LCD.");
//get current lcd status info: x,y,cursor position, cursor on/off
lcd_info=screen.getxy();
//locate cursor at x=23, y=3
screen.gotoxy(23,3);
//display cursor info: x,y and cursor_location=40*y+x
screen.printfxy(0,1,"cursor is located at x=%d y=%d cr=%d",screen.getxy().x,screen.getxy().y,screen.getxy().cursor);
//locate cursor at where it was before
screen.gotoxy(lcd_info.x,lcd_info.y);
//put a 'tilda' char in x=17,y=2
screen.putcxy(17,2,'~');
//display cursor on/off status
if(screen.getxy().cursor_on)
screen.putsxy(0,3,"Cursor is on ");
else
screen.putsxy(0,3,"Cursor is off");
//wait little
Sleep(9000);
Sleep(9000);
//switch cursor on/off flag
screen.cursor_on_off(~screen.getxy().cursor_on);
//display cursor on/off status again
if(screen.getxy().cursor_on)
screen.putsxy(0,3,"Cursor is on ");
else
screen.putsxy(0,3,"Cursor is off");
//wait little
Sleep(9000);
Sleep(9000);
//clear up everything, (0,0) is the start point, (39,3) is the last point
screen.clr_desired_area(0,0,39,3,' ');
}
}
Ho trovato un bell'esempio in C++ con interfaccina grafica della cristal fontz... andrò a studiarla...