/* LCD Instruction Library PIN Description 1 VSS - GND 2 VDD - 5V 3 V0 - POT btwn VDD & VEE 4 D/I - Data/Instruction bit, 1=Data, 0=Instruction 5 R/W - 1 = can be read, 0 enables writes on falling edge of E if CS1 & 2 are high 6 E - Enable. Read data when E=1, Data written at falling edge 7-14 Data0-7 15 CS1 16 CS2 - chip selects for left and right half of display, active high 17 RES - active low reset - display off, display starts from line 0 18 VEE - supposed to be -8V, let's see if we can get away w/ 0 or just bottom of Pot 19 BKL1 - VBKLT = 5V w/ current limiting resistors, max current = 780 mA 20 BKL2 - */ #include #include #define LCD_DATA PORTC #define D_I PORTA.5 #define R_W PORTA.4 #define E PORTA.3 #define CS1 PORTA.2 #define CS2 PORTA.1 #define RES PORTA.0 #define DISPLAY_ON 0b00111111 #define DISPLAY_OFF 0b00111110 #define SET_Y 0b01000000 //OR this w/ desired 6-bit Y address #define SET_X 0b10111000 //OR this w/ desired 3-bit X address #include "uppercase.h" #include "lowercase.h" #include "specials.h" #include "numbers.h" #include "shapes.h" //Bitmaps unsigned char* flash* digit_ptr[10] = {num0, num1, num2, num3, num4, num5, num6, num7, num8, num9}; unsigned char* flash* upper_ltr[26] = {upper65, upper66, upper67, upper68, upper69, upper70, upper71, upper72, upper73, upper74, upper75, upper76, upper77, upper78, upper79, upper80, upper81, upper82, upper83, upper84, upper85, upper86, upper87, upper88, upper89, upper90}; unsigned char* flash* lower_ltr[26] = {lower97, lower98, lower99, lower100, lower101, lower102, lower103, lower104, lower105, lower106, lower107, lower108, lower109, lower110, lower111, lower112, lower113, lower114, lower115, lower116, lower117, lower118, lower119, lower120, lower121, lower122}; unsigned char* flash* spec_ptr[13] = {space, comma, period, exclaim, question, colon, dash, pound, ampersand, star, oparanthesis, cparanthesis, percent}; //Latches byte to ks0108 by toggling E // control lines set elsewhere void ks0108_send(unsigned char data){ LCD_DATA=data; //data on the data port E=0; delay_us(1); E=1; //enable driven high delay_us(3); E=0; //latch data delay_us(3); } //Sets control lines to send a byte as data void ks0108_send_data(unsigned char data){ D_I=1; //D/I = 1 for data R_W=0; ks0108_send(data); } //Sets control lines to select left screen and sends a byte as an instruction void ks0108_send_inst_left(unsigned char inst){ CS1=1; //enable left side CS2=0; //disable right side D_I=0; //D/I = 0 for instruction R_W=0; ks0108_send(inst); } //Sets control lines to select right screen and sends a byte as an instruction void ks0108_send_inst_right(unsigned char inst){ CS1=0; //disable left side CS2=1; //enable right side D_I=0; //D/I = 0 for instruction R_W=0; ks0108_send(inst); } //Initializes the LCD by setting the I/O ports, resetting, and turning both halves on, void ks0108_init(void){ DDRC=0xFF; DDRA=0xFF; RES=0; delay_us(3); RES=1; ks0108_send_inst_left(DISPLAY_ON); ks0108_send_inst_right(DISPLAY_ON); } //Sets (Y,X) addresses void ks0108_set_xy(unsigned char x, unsigned char y){ if (y<64){ if (x<8) ks0108_send_inst_left(SET_X|x); if (y<128) ks0108_send_inst_left(SET_Y|y); } else{ if (x<8) ks0108_send_inst_right(SET_X|x); if (y<128) ks0108_send_inst_right(SET_Y|(y-64)); } } //Draws a 10x16 character - (y,x) specifies the top left corner of the character void draw_char(flash unsigned char* map, unsigned char x, unsigned char y){ char i,j; for (j=0;j<2;j++){ for (i=0;i<10;i++){ if (((x+j)<8)&&((y+i)<128)){ ks0108_set_xy((x+j),(y+i)); ks0108_send_data(map[i+(10*j)]); } } } } //Draws a string of 10x16 characters from flash //(y,x) specifies the top left corner of the first character void string2LCDf(flash char* myString, unsigned char x, unsigned char y){ char i; i=0; while (myString[i]!=0x00){ if ((y+(i*10))<128){ if ((myString[i]-'0')<10){ draw_char(digit_ptr[(myString[i]-'0')],x,y+(i*10)); } else if ((myString[i]-'A')<26){ draw_char(upper_ltr[(myString[i]-'A')],x,y+(i*10)); } else if ((myString[i]-'a')<26){ draw_char(lower_ltr[(myString[i]-'a')],x,y+(i*10)); } else{ switch (myString[i]){ case ' ':draw_char(spec_ptr[0],x,y+(i*10));break; case ',':draw_char(spec_ptr[1],x,y+(i*10));break; case '.':draw_char(spec_ptr[2],x,y+(i*10));break; case '!':draw_char(spec_ptr[3],x,y+(i*10));break; case '?':draw_char(spec_ptr[4],x,y+(i*10));break; case ':':draw_char(spec_ptr[5],x,y+(i*10));break; case '-':draw_char(spec_ptr[6],x,y+(i*10));break; case '#':draw_char(spec_ptr[7],x,y+(i*10));break; case '&':draw_char(spec_ptr[8],x,y+(i*10));break; case '*':draw_char(spec_ptr[9],x,y+(i*10));break; case '(':draw_char(spec_ptr[10],x,y+(i*10));break; case ')':draw_char(spec_ptr[11],x,y+(i*10));break; case '%':draw_char(spec_ptr[12],x,y+(i*10));break; default:break; } } } i++; } } //Draws a string of 10x16 characters //(y,x) specifies the top left corner of the first character void string2LCD(char* myString, unsigned char x, unsigned char y){ char i; i=0; while (myString[i]!=0x00){ if ((y+(i*10))<128){ if ((myString[i]-'0')<10){ draw_char(digit_ptr[(myString[i]-'0')],x,y+(i*10)); } else if ((myString[i]-'A')<26){ draw_char(upper_ltr[(myString[i]-'A')],x,y+(i*10)); } else if ((myString[i]-'a')<26){ draw_char(lower_ltr[(myString[i]-'a')],x,y+(i*10)); } else{ switch (myString[i]){ case ' ':draw_char(spec_ptr[0],x,y+(i*10));break; case ',':draw_char(spec_ptr[1],x,y+(i*10));break; case '.':draw_char(spec_ptr[2],x,y+(i*10));break; case '!':draw_char(spec_ptr[3],x,y+(i*10));break; case '?':draw_char(spec_ptr[4],x,y+(i*10));break; case ':':draw_char(spec_ptr[5],x,y+(i*10));break; case '-':draw_char(spec_ptr[6],x,y+(i*10));break; case '#':draw_char(spec_ptr[7],x,y+(i*10));break; case '&':draw_char(spec_ptr[8],x,y+(i*10));break; case '*':draw_char(spec_ptr[9],x,y+(i*10));break; case '(':draw_char(spec_ptr[10],x,y+(i*10));break; case ')':draw_char(spec_ptr[11],x,y+(i*10));break; case '%':draw_char(spec_ptr[12],x,y+(i*10));break; default:break; } } } i++; } } //Draws a 32x32 pixel graphic, (y,x) = top left corner of the graphic void drawShape(char num, unsigned char x, unsigned char y){ char i,j; flash unsigned char* map; switch (num){ case 0: map = shocktart;break; case 1: map = mm; break; case 2: map = chicklet;break; default : map = smint;break; } for (j=0;j<4;j++){ for (i=0;i<32;i++){ ks0108_set_xy((x+j),(y+i)); ks0108_send_data(map[i+(32*j)]); } } } //Clears the screen entirely void ks0108_clear(void){ char x,y; for (y=0;y<128;y++){ for (x=0;x<8;x++){ ks0108_set_xy(x,y); ks0108_send_data(0x00); } } }