00001 /* 00002 graphic LCD backpack code 00003 00004 set up for the big LCD, 160x128 00005 00006 10/16/08, everything works. Pixel, line, circle, set x, set y, print_char, clear_screen. All good. 00007 00008 11/14/08, block erase, box, converted to ATMega168 00009 00010 11/19/08 added reverse mode 00011 */ 00012 00013 00014 #include <avr/io.h> 00015 #include "rprintf.h" 00016 #include <math.h> 00017 #include <avr/interrupt.h> 00018 00019 #define FOSC 16000000// Clock Speed 00020 #define BAUD 57600 00021 #define MYUBRR FOSC/16/BAUD-1 00022 00023 #define WR 0 //PC0 00024 #define RD 1 //PC1 00025 #define CE 2 //PC2 00026 #define CD 3 //PC3 00027 #define HALT 4 //PC4 00028 #define RST 5 //PC5 00029 00030 #define BL_EN 2 //PB2 00031 00032 #define X_ENDPOINT 159 00033 #define Y_ENDPOINT 127 00034 00035 00036 //Define functions 00037 //====================== 00038 void ioinit(void); //Initializes IO 00039 void delay_ms(uint16_t x); //General purpose delay 00040 void delay_us(uint8_t x); 00041 void USART_Init( unsigned int ubrr); 00042 void put_char(char byte); 00043 int rnd(float number); 00044 00045 void set_data(char data);//sets the data port 00046 char read(char D_S);//reads data (D_S = 1) or status (D_S = anything else) 00047 void write(char D_C, char byte);//writes data or command 00048 void display_init(void);//initializes the display 00049 00050 00051 void clear_screen(void); 00052 00053 void print_char(char S_R, char txt); 00054 void del_char(char endpoint); 00055 void pixel(char S_R, char x, char y); 00056 void line(char S_R, char x1, char y1, char x2, char y2); 00057 void circle(char S_R, int x, int y, int r); 00058 void demo(void); 00059 00060 void erase_block(char x1, char y1, char x2, char y2); 00061 void box(char x1, char y1, char x2, char y2); 00062 00063 //====================== 00064 char x_offset = 0; 00065 char y_offset = 127; 00066 char reverse = 0; 00067 00068 unsigned char RX_array[256]; 00069 volatile unsigned short RX_in = 0; 00070 unsigned short RX_read = 0; 00071 unsigned char BL_dutycycle = 20; 00072 00073 static char logo[30] = {0x01,0xC0,0x03,0x80,0x03,0x80,0x01,0xD0, 00074 0x01,0xF8,0x0C,0xF8,0x18,0xF8,0x1F,0xF8, 00075 0x1F,0xF8,0x1F,0xF0,0x1F,0xE0,0x1F,0xC0, 00076 0x1C,0x00,0x18,0x00,0x10,0x00}; 00077 00078 //Jacked from Sinister 7 code 00079 static char text_array[475] = {0x00,0x00,0x00,0x00,0x00,/*space*/ 00080 0x00,0xF6,0xF6,0x00,0x00,/*!*/ 00081 0x00,0xE0,0x00,0xE0,0x00,/*"*/ 00082 0x28,0xFE,0x28,0xFE,0x28,/*#*/ 00083 0x00,0x64,0xD6,0x54,0x08,/*$*/ 00084 0xC2,0xCC,0x10,0x26,0xC6,/*%*/ 00085 0x4C,0xB2,0x92,0x6C,0x0A,/*&*/ 00086 0x00,0x00,0xE0,0x00,0x00,/*'*/ 00087 0x00,0x38,0x44,0x82,0x00,/*(*/ 00088 0x00,0x82,0x44,0x38,0x00,/*)*/ 00089 0x88,0x50,0xF8,0x50,0x88,/***/ 00090 0x08,0x08,0x3E,0x08,0x08,/*+*/ 00091 0x00,0x00,0x05,0x06,0x00,/*,*/ 00092 0x08,0x08,0x08,0x08,0x08,/*-*/ 00093 0x00,0x00,0x06,0x06,0x00,/*.*/ 00094 0x02,0x0C,0x10,0x60,0x80,/*/*/ 00095 0x7C,0x8A,0x92,0xA2,0x7C,/*0*/ 00096 0x00,0x42,0xFE,0x02,0x00,/*1*/ 00097 0x42,0x86,0x8A,0x92,0x62,/*2*/ 00098 0x44,0x82,0x92,0x92,0x6C,/*3*/ 00099 0x10,0x30,0x50,0xFE,0x10,/*4*/ 00100 0xE4,0xA2,0xA2,0xA2,0x9C,/*5*/ 00101 0x3C,0x52,0x92,0x92,0x0C,/*6*/ 00102 0x80,0x86,0x98,0xE0,0x80,/*7*/ 00103 0x6C,0x92,0x92,0x92,0x6C,/*8*/ 00104 0x60,0x92,0x92,0x94,0x78,/*9*/ 00105 0x00,0x00,0x36,0x36,0x00,/*:*/ 00106 0x00,0x00,0x35,0x36,0x00,/*;*/ 00107 0x10,0x28,0x44,0x82,0x00,/*<*/ 00108 0x28,0x28,0x28,0x28,0x28,/*=*/ 00109 0x00,0x82,0x44,0x28,0x10,/*>*/ 00110 0x40,0x80,0x8A,0x90,0x60,/*?*/ 00111 0x7C,0x82,0xBA,0xBA,0x62,/*@*/ 00112 0x3E,0x48,0x88,0x48,0x3E,/*A*/ 00113 0xFE,0x92,0x92,0x92,0x6C,/*B*/ 00114 0x7C,0x82,0x82,0x82,0x44,/*C*/ 00115 0xFE,0x82,0x82,0x82,0x7C,/*D*/ 00116 0xFE,0x92,0x92,0x92,0x82,/*E*/ 00117 0xFE,0x90,0x90,0x90,0x80,/*F*/ 00118 0x7C,0x82,0x82,0x8A,0x4E,/*G*/ 00119 0xFE,0x10,0x10,0x10,0xFE,/*H*/ 00120 0x82,0x82,0xFE,0x82,0x82,/*I*/ 00121 0x84,0x82,0xFC,0x80,0x80,/*J*/ 00122 0xFE,0x10,0x28,0x44,0x82,/*K*/ 00123 0xFE,0x02,0x02,0x02,0x02,/*L*/ 00124 0xFE,0x40,0x20,0x40,0xFE,/*M*/ 00125 0xFE,0x60,0x10,0x0C,0xFE,/*N*/ 00126 0x7C,0x82,0x82,0x82,0x7C,/*O*/ 00127 0xFE,0x90,0x90,0x90,0x60,/*P*/ 00128 0x7C,0x82,0x82,0x86,0x7E,/*Q*/ 00129 0xFE,0x90,0x98,0x94,0x62,/*R*/ 00130 0x64,0x92,0x92,0x92,0x4C,/*S*/ 00131 0x80,0x80,0xFE,0x80,0x80,/*T*/ 00132 0xFC,0x02,0x02,0x02,0xFC,/*U*/ 00133 0xF8,0x04,0x02,0x04,0xF8,/*V*/ 00134 0xFC,0x02,0x0C,0x02,0xFC,/*W*/ 00135 0xC6,0x28,0x10,0x28,0xC6,/*X*/ 00136 0xC0,0x20,0x1E,0x20,0xC0,/*Y*/ 00137 0x86,0x8A,0x92,0xA2,0xC2,/*Z*/ 00138 0x00,0x00,0xFE,0x82,0x00,/*[*/ 00139 0x80,0x60,0x10,0x0C,0x02,/*this should be / */ 00140 0x80,0x60,0x10,0x0C,0x02,/*]*/ 00141 0x20,0x40,0x80,0x40,0x20,/*^*/ 00142 0x01,0x01,0x01,0x01,0x01,/*_*/ 00143 0x80,0x40,0x20,0x00,0x00,/*`*/ 00144 0x04,0x2A,0x2A,0x2A,0x1E,/*a*/ 00145 0xFE,0x12,0x22,0x22,0x1C,/*b*/ 00146 0x1C,0x22,0x22,0x22,0x14,/*c*/ 00147 0x1C,0x22,0x22,0x12,0xFE,/*d*/ 00148 0x1C,0x2A,0x2A,0x2A,0x18,/*e*/ 00149 0x10,0x7E,0x90,0x80,0x40,/*f*/ 00150 0x18,0x25,0x25,0x25,0x1E,/*g*/ 00151 0xFE,0x10,0x10,0x10,0x0E,/*h*/ 00152 0x00,0x12,0x5E,0x02,0x00,/*i*/ 00153 0x02,0x01,0x01,0x11,0x5E,/*j*/ 00154 0xFE,0x08,0x08,0x14,0x22,/*k*/ 00155 0x00,0x82,0xFE,0x02,0x00,/*l*/ 00156 0x3E,0x20,0x1C,0x20,0x1E,/*m*/ 00157 0x3E,0x20,0x20,0x20,0x1E,/*n*/ 00158 0x1C,0x22,0x22,0x22,0x1C,/*o*/ 00159 0x3F,0x24,0x24,0x24,0x18,/*p*/ 00160 0x18,0x24,0x24,0x3F,0x01,/*q*/ 00161 0x3E,0x10,0x20,0x20,0x10,/*r*/ 00162 0x12,0x2A,0x2A,0x2A,0x04,/*s*/ 00163 0x00,0x10,0x3C,0x12,0x04,/*t*/ 00164 0x3C,0x02,0x02,0x02,0x3E,/*u*/ 00165 0x30,0x0C,0x02,0x0C,0x30,/*v*/ 00166 0x38,0x06,0x18,0x06,0x38,/*w*/ 00167 0x22,0x14,0x08,0x14,0x22,/*x*/ 00168 0x38,0x05,0x05,0x05,0x3E,/*y*/ 00169 0x22,0x26,0x2A,0x32,0x22,/*z*/ 00170 0x00,0x10,0x6C,0x82,0x82,/*{*/ 00171 //0x00,0x00,0xFF,0x00,0x00,/*|*/ 00172 0x04,0x02,0xFF,0x02,0x04,/*|, arrow*/ 00173 0x82,0x82,0x6C,0x10,0x00,/*}*/ 00174 0x08,0x10,0x18,0x08,0x10};/*~*/ 00175 00176 00177 00178 ISR (SIG_USART_RECV)//USART Receive Interrupt 00179 { 00180 cli();//Disable Interrupts 00181 RX_array[RX_in] = UDR0; 00182 00183 RX_in++; 00184 00185 if (RX_in >= 256) RX_in = 0; 00186 00187 sei();//Enable Interrupts 00188 00189 } 00190 00191 ISR (TIMER0_COMPA_vect) 00192 { 00193 //unsigned char y; 00194 00195 cli();//Disable Interrupts 00196 00197 TIFR0 = (1<<OCF0A);//clear the interrupt 00198 00199 PORTB &= (~(1<<BL_EN));//on 00200 00201 //y = PINB; 00202 //if (y & (1<<BL_EN)) PORTB &= (~(1<<BL_EN)); 00203 //else PORTB |= (1<<BL_EN); 00204 //PORTB |= (1<<BL_EN); 00205 00206 TIMSK0 = (1<<OCIE0B);//disable A, enable B 00207 sei();//Enable Interrupts 00208 } 00209 00210 00211 ISR (TIMER0_COMPB_vect) 00212 { 00213 //unsigned char y; 00214 00215 cli();//Disable Interrupts 00216 00217 TIFR0 = (1<<OCF0B);//clear the interrupt 00218 00219 //y = PINB; 00220 //if (y & (1<<BL_EN)) PORTB &= (~(1<<BL_EN)); 00221 //else PORTB |= (1<<BL_EN); 00222 //PORTB |= (1<<BL_EN); 00223 00224 PORTB |= (1<<BL_EN);//off 00225 00226 TIMSK0 = (1<<OCIE0A);//disable B, enable A 00227 sei();//Enable Interrupts 00228 } 00229 00230 00231 00232 00233 00234 int main (void) 00235 { 00236 char x, y; 00237 00238 ioinit(); //Setup IO pins and defaults 00239 USART_Init( MYUBRR); 00240 rprintf_devopen(put_char); // init rrprintf 00241 00242 //reset the display 00243 delay_ms(1); 00244 PORTC |= (1<<RST); 00245 00246 //initialize the display 00247 display_init(); 00248 00249 clear_screen(); 00250 00251 //Backlight on 00252 PORTB &= (~(1<<BL_EN)); 00253 00254 while(1) 00255 { 00256 if(RX_in != RX_read) 00257 { 00258 x = RX_array[RX_read]; 00259 RX_read++; 00260 if(RX_read >= 256) RX_read = 0; 00261 00262 //Backspace=================================================== 00263 if(x == 8) del_char(0); 00264 00265 //Special commands 00266 else if (x == 124) 00267 { 00268 //make sure the next byte is there 00269 while(RX_in == RX_read); 00270 00271 //0, clear screen====================================================== 00272 if(RX_array[RX_read] == 0) 00273 { 00274 clear_screen(); 00275 RX_read++; 00276 if(RX_read >= 256) RX_read = 0; 00277 } 00278 00279 00280 //Backlight on/off 00281 else if(RX_array[RX_read] == 2) 00282 { 00283 y = PINB; 00284 if (y & (1<<BL_EN)) PORTB &= (~(1<<BL_EN)); 00285 else PORTB |= (1<<BL_EN); 00286 RX_read++; 00287 if(RX_read >= 256) RX_read = 0; 00288 } 00289 00290 //demo mode 00291 else if(RX_array[RX_read] == 4) 00292 { 00293 RX_in = 0, RX_read = 0; 00294 demo(); 00295 clear_screen(); 00296 RX_in = 0; 00297 } 00298 00299 //reverse mode 00300 else if(RX_array[RX_read] == 18) 00301 { 00302 reverse ^= 1; 00303 clear_screen(); 00304 RX_read++; 00305 if(RX_read >= 256) RX_read = 0; 00306 00307 } 00308 00309 else 00310 { 00311 //set x or y========================================================= 00312 if((RX_array[RX_read] == 24) | (RX_array[RX_read] == 25)) 00313 { 00314 RX_read++; 00315 if(RX_read >= 256) RX_read = 0; 00316 while(RX_in == RX_read);//wait for byte 00317 if (RX_array[RX_read-1] == 24) x_offset = RX_array[RX_read]; 00318 else if (RX_array[RX_read-1] == 25) y_offset = RX_array[RX_read]; 00319 00320 RX_read++; 00321 if(RX_read >= 256) RX_read = 0; 00322 00323 if (x_offset > 159) x_offset = 159; 00324 if (y_offset > 127) y_offset = 127; 00325 00326 } 00327 00328 //set pixel========================================================= 00329 if (RX_array[RX_read] == 16) 00330 { 00331 //need 3 bytes 00332 for (y = 0; y < 3; y++) 00333 { 00334 RX_read++; 00335 if(RX_read >= 256) RX_read = 0; 00336 while(RX_in == RX_read);//wait for byte 00337 } 00338 00339 pixel(RX_array[RX_read], RX_array[RX_read-2], RX_array[RX_read-1]); 00340 00341 RX_read++; 00342 if(RX_read >= 256) RX_read = 0; 00343 00344 } 00345 00346 //<ctrl>c, circle====================================================== 00347 if(RX_array[RX_read] == 3) 00348 { 00349 //need 4 bytes 00350 for (y = 0; y < 4; y++) 00351 { 00352 RX_read++; 00353 if(RX_read >= 256) RX_read = 0; 00354 while(RX_in == RX_read);//wait for byte 00355 } 00356 00357 circle(RX_array[RX_read], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1]); 00358 00359 RX_read++; 00360 if(RX_read >= 256) RX_read = 0; 00361 } 00362 00363 00364 //<ctrl>e, erase block====================================================== 00365 if(RX_array[RX_read] == 5) 00366 { 00367 //need 4 bytes 00368 for (y = 0; y < 4; y++) 00369 { 00370 RX_read++; 00371 if(RX_read >= 256) RX_read = 0; 00372 while(RX_in == RX_read);//wait for byte 00373 } 00374 00375 erase_block(RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1], RX_array[RX_read]); 00376 00377 RX_read++; 00378 if(RX_read >= 256) RX_read = 0; 00379 } 00380 00381 00382 //<ctrl>o, box, running out of meaningful letters====================================================== 00383 if(RX_array[RX_read] == 15) 00384 { 00385 //need 4 bytes 00386 for (y = 0; y < 4; y++) 00387 { 00388 RX_read++; 00389 if(RX_read >= 256) RX_read = 0; 00390 while(RX_in == RX_read);//wait for byte 00391 } 00392 00393 box(RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1], RX_array[RX_read]); 00394 00395 RX_read++; 00396 if(RX_read >= 256) RX_read = 0; 00397 } 00398 00399 00400 //<ctrl>L, line======================================================== 00401 else if (RX_array[RX_read] == 12) 00402 { 00403 //need 5 bytes 00404 for (y = 0; y < 5; y++) 00405 { 00406 RX_read++; 00407 if(RX_read >= 256) RX_read = 0; 00408 while(RX_in == RX_read);//wait for byte 00409 } 00410 00411 line(RX_array[RX_read], RX_array[RX_read-4], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read+-1]); 00412 RX_read++; 00413 if(RX_read >= 256) RX_read = 0; 00414 } 00415 00416 00417 } 00418 00419 } 00420 00421 //print character to the screen=============================================== 00422 else 00423 { 00424 del_char(1); 00425 print_char(1, x); 00426 } 00427 } 00428 00429 } 00430 00431 00432 00433 } 00434 00435 void ioinit (void) 00436 { 00437 00438 //1 = output, 0 = input 00439 00440 /* 00441 WR //PC0 00442 RD //PC1 00443 CE //PC2 00444 C_D //PC3 00445 HALT //PC4 00446 RST //PC5 00447 */ 00448 00449 PORTB |= (1<<BL_EN);//Backlight off 00450 DDRB |= (1<<BL_EN);//set PB2 as output 00451 00452 PORTC = ((1<<WR) | (1<<RD) | (1<<CE) | (1<<CD) | (1<<HALT)); 00453 PORTC &= (~(1<<RST));//set the reset line low at power up 00454 DDRC = ((1<<WR) | (1<<RD) | (1<<CE) | (1<<CD) | (1<<HALT) | (1<<RST)); 00455 00456 //Init timer 2 00457 TCCR2B = (1<<CS21); //Set Prescaler to 8. CS21=1 00458 00459 //Set up Timer 0 00460 TCCR0A = (1<<WGM01);//CTC mode 00461 TCCR0B = (1<<CS01); 00462 TIMSK0 = (1<<OCIE0A); 00463 OCR0B = BL_dutycycle; 00464 00465 OCR0A = 100 - BL_dutycycle; 00466 00467 SREG |= 0x80; 00468 } 00469 00470 //General short delays 00471 void delay_ms(uint16_t x) 00472 { 00473 for (; x > 0 ; x--) 00474 { 00475 delay_us(250); 00476 delay_us(250); 00477 delay_us(250); 00478 delay_us(250); 00479 } 00480 00481 } 00482 00483 //General short delays 00484 void delay_us(uint8_t x) 00485 { 00486 char temp; 00487 00488 if (x == 0) temp = 1; 00489 else temp = x; 00490 00491 TIFR2 |= 0x01;//Clear any interrupt flags on Timer2 00492 00493 TCNT2 = 256 - temp; //256 - 125 = 131 : Preload timer 2 for x clicks. Should be 1us per click 00494 00495 while(!(TIFR2 & 0x01)); 00496 00497 if (x == 0) return;//this is for display timing 00498 00499 //The prescaler doesn't allow for a setting of 16, just 8 or 32. So, we do this twice. 00500 TIFR2 |= 0x01; 00501 00502 TCNT2 = 256 - temp; //256 - 125 = 131 : Preload timer 2 for x clicks. Should be 1us per click 00503 00504 while(!(TIFR2 & 0x01)); 00505 00506 } 00507 00508 void USART_Init( unsigned int ubrr) 00509 { 00510 // Set baud rate 00511 UBRR0H = (unsigned char)(ubrr>>8); 00512 UBRR0L = (unsigned char)ubrr; 00513 00514 // Enable receiver and transmitter 00515 UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0); //Enable Interrupts on receive character 00516 00517 UCSR0C = (1<<UCSZ00)|(1<<UCSZ01); 00518 sei(); 00519 } 00520 00521 void put_char(char byte) 00522 { 00523 /* Wait for empty transmit buffer */ 00524 while ( !( UCSR0A & (1<<UDRE0)) ); 00525 /* Put data into buffer, sends the data */ 00526 UDR0 = byte; 00527 } 00528 00529 00530 //set data port 00531 void set_data(char data) 00532 { 00533 //PORTB 00534 //DB0 = PB0 00535 //DB1 = PB1 00536 00537 PORTB &= 0xFC; 00538 00539 //PORTD 00540 //DB2 = PD2 00541 //DB3 = PD3 00542 //DB4 = PD4 00543 //DB5 = PD5 00544 //DB6 = PD6 00545 //DB7 = PD7 00546 00547 PORTD &= 0x03; 00548 00549 PORTB |= (data & 0x03); 00550 PORTD |= (data & 0xFC); 00551 00552 } 00553 00554 00555 //Reads data or status 00556 //for data D_S = 1, for status D_S = 0 00557 //returns the value of the data bus 00558 char read(char D_S) 00559 { 00560 char data1 = 0, data2 = 0; 00561 00562 DDRB &= 0xFC;//PB0 and PB1 inputs 00563 DDRD &= 0x02;//everything but PD1 as input 00564 00565 PORTC &= ~((1 << RD) | (1 << CE));//CD high for status 00566 if (D_S == 1) PORTC &= ~(1 << CD);//CD down for data 00567 00568 delay_us(0); 00569 00570 data1 = PINB; 00571 data1 &= 0x03; 00572 00573 data2 = PIND; 00574 data2 &= 0xFC; 00575 00576 data1 |= data2; 00577 00578 PORTC |= ((1 << CD) | (1 << RD) | (1 << CE));//all up 00579 00580 delay_us(0); 00581 00582 return data1; 00583 00584 } 00585 00586 00587 //Writes data (D_C = 1) or command (D_C = anything else) 00588 void write(char D_C, char byte) 00589 { 00590 DDRB |= 0x03; //PB0 and PB1 are outs 00591 DDRD |= 0xFC; //PD2-PD7 are also outs. Ports B and D are the data bus 00592 00593 set_data(byte); 00594 00595 if (D_C == 1) PORTC &= ~((1 << WR) | (1 << CE) | (1 << CD));//down 00596 else PORTC &= ~((1 << WR) | (1 << CE));//down 00597 00598 delay_us(0); 00599 PORTC |= ((1 << CD) | (1 << WR) | (1 << CE));//all up 00600 delay_us(0); 00601 DDRB &= 0xFC;//PB0 and PB1 inputs 00602 DDRD &= 0x02;//everything but PD1 as input 00603 00604 delay_us(0); 00605 00606 } 00607 00608 00609 00610 void display_init(void) 00611 { 00612 //set graphics home address to 0 00613 while(!(read(0) & 3));//read status 00614 write(1, 0); 00615 while(!(read(0) & 3));//read status 00616 write(1, 0); 00617 while(!(read(0) & 3));//read status 00618 write(0, 0x42); 00619 00620 //set graphics area 00621 while(!(read(0) & 3));//read status 00622 write(1, 20);//20 bytes, 160/8 00623 while(!(read(0) & 3));//read status 00624 write(1, 0); 00625 while(!(read(0) & 3));//read status 00626 write(0, 0x43); 00627 00628 //set mode 00629 while(!(read(0) & 3));//read status 00630 write(0, 0x80);//Or, with internal character generator 00631 00632 //set display mode 00633 while(!(read(0) & 3));//read status 00634 write(0, 0x98);//Graphics on 00635 00636 } 00637 00638 00639 00640 00641 00642 void clear_screen(void) 00643 { 00644 int x; 00645 00646 //set address pointer to 0, start of graphics 00647 while(!(read(0) & 3));//read status 00648 write(1, 0); 00649 while(!(read(0) & 3));//read status 00650 write(1, 0); 00651 while(!(read(0) & 3));//read status 00652 write(0, 0x24); 00653 00654 for(x = 0; x < 0xA00; x++) 00655 { 00656 while(!(read(0) & 3));//read status 00657 if (reverse == 1) write(1,0xFF); 00658 else if (reverse == 0) write(1, 0); 00659 while(!(read(0) & 3));//read status 00660 write(0, 0xC0); 00661 } 00662 00663 x_offset = 0; 00664 y_offset = 127; 00665 } 00666 00667 00668 //sets (S_R = 1) or resets (S_R = 0) at x, y 00669 void pixel(char S_R, char x, char y) 00670 { 00671 short address = 0; 00672 char byte = 0; 00673 00674 if (reverse == 1) S_R ^= 1; 00675 00676 //don't try to print something outside of our range 00677 if (x > 159) return; 00678 if (y > 127) return; 00679 00680 address = ((127-y) * 20) + (x / 8); 00681 00682 //set address pointer 00683 while(!(read(0) & 3));//read status 00684 byte = (char)(address & 0xFF); 00685 00686 write(1, byte);//20 bytes, 160/8 00687 00688 while(!(read(0) & 3));//read status 00689 byte = (char)((address & 0xFF00) >> 8); 00690 00691 write(1, byte); 00692 00693 while(!(read(0) & 3));//read status 00694 write(0, 0x24); 00695 00696 byte = ~(x % 8); 00697 00698 byte |= 0xF8; 00699 if (S_R == 0) byte &= 0xF7; 00700 00701 //if (reverse == 1) byte = ~(byte); 00702 00703 //set-reset bit 00704 while(!(read(0) & 3));//read status 00705 write(0, byte); 00706 00707 } 00708 00709 00710 //draws (S_R = 1) or erases (S_R = 0) a line from x1, y1 to x2, y2 00711 void line(char S_R, char x1, char y1, char x2, char y2) 00712 { 00713 float m, q; 00714 int x_dif, y_dif; 00715 int a, b, c; 00716 00717 if ((x1 > X_ENDPOINT) | (x2 > X_ENDPOINT)) return; 00718 if ((y1 > Y_ENDPOINT) | (y2 > Y_ENDPOINT)) return; 00719 00720 x_dif = x2 - x1; 00721 y_dif = y2 - y1; 00722 if (y_dif < 0) y_dif *= (-1); 00723 00724 00725 m = (float)(y2 - y1) / (float)(x2 - x1); 00726 00727 b = y1-(m*x1); 00728 00729 if(x_dif >= y_dif) 00730 { 00731 for (a = x1; a <= x2; a++) 00732 { 00733 pixel(S_R, (char)a, (char)((m*a)+b)); 00734 00735 } 00736 } 00737 00738 else 00739 { 00740 if (y2 > y1) 00741 { 00742 for (a = y1; a <= y2; a++) 00743 { 00744 if (x_dif == 0) c = x1; 00745 else 00746 { 00747 q = (((float)(a-b))/m); 00748 c = rnd(q); 00749 } 00750 00751 pixel(S_R, (char)c, (char)a); 00752 00753 } 00754 } 00755 00756 else if (y1 > y2) 00757 { 00758 for (a = y1; a >= y2; a--) 00759 { 00760 if (x_dif == 0) c = x1; 00761 else 00762 { 00763 q = (((float)(a-b))/m); 00764 c = rnd(q); 00765 } 00766 00767 pixel(S_R, (char)c, (char)a); 00768 00769 } 00770 } 00771 } 00772 00773 } 00774 00775 00776 //draws (S_R = 1) or erases (S_R = 0) a circle ar x, y with radius r 00777 void circle(char S_R, int x, int y, int r) 00778 { 00779 int x1 = 0, x2 = 0; 00780 int x_line = 0, y_line = 0; 00781 int temp_y; 00782 int temp_x; 00783 00784 x1 = x - r; 00785 x2 = x + r; 00786 00787 for (temp_x = x1; temp_x <= x2; temp_x++) 00788 { 00789 temp_y = ((sqrt((r*r) - ((temp_x - x)*(temp_x - x)))) - y); 00790 00791 temp_y *= (-1); 00792 00793 if (temp_x > x1) 00794 { 00795 line(S_R, (char)x_line, (char)y_line, (char)temp_x, (char)temp_y); 00796 line(S_R, (char)x_line, (char)(2*y - y_line), (char)temp_x, (char)(2*y - temp_y)); 00797 } 00798 00799 else 00800 { 00801 pixel(S_R, (char)temp_x, (char)temp_y); 00802 pixel(S_R, (char)temp_x, (char)(y + y - temp_y)); 00803 } 00804 00805 x_line = temp_x; 00806 y_line = temp_y; 00807 00808 } 00809 00810 00811 } 00812 00813 //rounds a floar to the nearest int 00814 int rnd(float number) 00815 { 00816 int a; 00817 float b; 00818 00819 a = number / 1; 00820 b = number - a; 00821 00822 if (b >= 0.5) a++; 00823 00824 return a; 00825 00826 } 00827 00828 //prints (S_R = 1) or erases (S_R = 0) a character to the screen 00829 //at x_offset, y_offset. Automatically augments offsets for next write 00830 void print_char(char S_R, char txt) 00831 { 00832 short text_array_offset = (txt - 32)*5, j; 00833 char x, k; 00834 00835 00836 for (j = text_array_offset; j < text_array_offset+5; j++) 00837 { 00838 k = text_array[j]; 00839 00840 for (x = 0; x < 8; x++) 00841 { 00842 if(k & 0x80) pixel(S_R, x_offset, y_offset - x); 00843 k <<= 1; 00844 } 00845 00846 x_offset++; 00847 00848 } 00849 00850 x_offset++; 00851 00852 if ((x_offset + 6) > 159) 00853 { 00854 x_offset = 0; 00855 if (y_offset <= 7) y_offset = 127; 00856 else y_offset -= 8; 00857 00858 } 00859 00860 } 00861 00862 00863 //demonstration code 00864 void demo(void) 00865 { 00866 char x, y, temp; 00867 int q = 0; 00868 00869 while(1) 00870 { 00871 x_offset = 0; 00872 y_offset = 127; 00873 00874 for (y = 0; y < 5; y++) 00875 { 00876 for (x = 32; x < 123; x++) 00877 { 00878 del_char(1); 00879 print_char(1, x); 00880 if (RX_in > 0) return; 00881 } 00882 } 00883 00884 clear_screen(); 00885 00886 for (y = 0; y < 5; y++) 00887 { 00888 for (x = 32; x < 123; x++) 00889 { 00890 //x_offset += 4; 00891 y_offset -= 6; 00892 if (y_offset <= 8) y_offset = 127; 00893 del_char(1); 00894 print_char(1, x); 00895 if (RX_in > 0) return; 00896 } 00897 } 00898 00899 clear_screen(); 00900 00901 //draw circles================================ 00902 for (x = 5; x < 120; x += 5) 00903 { 00904 circle(1,80,64,x); 00905 if (RX_in > 0) return; 00906 } 00907 00908 00909 //draw lines=================================== 00910 y = Y_ENDPOINT; 00911 00912 for (x = 0; x < X_ENDPOINT; x += 20) 00913 { 00914 line(1,0,y,x,0); 00915 y -= 16; 00916 } 00917 00918 y = 0; 00919 00920 for (x = 0; x < X_ENDPOINT; x += 20) 00921 { 00922 line(1,x,0,X_ENDPOINT,y); 00923 y += 16; 00924 } 00925 00926 y = Y_ENDPOINT; 00927 00928 for (x = 0; x < X_ENDPOINT; x += 20) 00929 { 00930 line(1,x,Y_ENDPOINT,X_ENDPOINT,y); 00931 y -= 16; 00932 } 00933 00934 y = 0; 00935 00936 for (x = 0; x < X_ENDPOINT; x += 20) 00937 { 00938 line(1,0,y,x,Y_ENDPOINT); 00939 y += 16; 00940 } 00941 00942 00943 //erase circles================================ 00944 for (x = 5; x < 120; x += 5) 00945 { 00946 circle(0,80,64,x); 00947 if (RX_in > 0) return; 00948 } 00949 00950 //erase lines=================================== 00951 y = Y_ENDPOINT; 00952 00953 for (x = 0; x < X_ENDPOINT; x += 20) 00954 { 00955 line(0,0,y,x,0); 00956 y -= 16; 00957 } 00958 00959 y = 0; 00960 00961 for (x = 0; x < X_ENDPOINT; x += 20) 00962 { 00963 line(0,x,0,X_ENDPOINT,y); 00964 y += 16; 00965 } 00966 00967 y = Y_ENDPOINT; 00968 00969 for (x = 0; x < X_ENDPOINT; x += 20) 00970 { 00971 line(0,x,Y_ENDPOINT,X_ENDPOINT,y); 00972 y -= 16; 00973 } 00974 00975 y = 0; 00976 00977 for (x = 0; x < X_ENDPOINT; x += 20) 00978 { 00979 line(0,0,y,x,Y_ENDPOINT); 00980 y += 16; 00981 } 00982 00983 if (RX_in > 0) return; 00984 00985 //Boxes================================================================= 00986 y = 111; 00987 for (x = 0; x <= 140; x += 10) 00988 { 00989 erase_block(x, y, x+16, y+16); 00990 box(x, y, x+16, y+16); 00991 y -= 7; 00992 } 00993 00994 00995 //x = 110; 00996 y = 28; 00997 //Logo================================================================= 00998 q = 0; 00999 while(q < 30) 01000 { 01001 temp = logo[q]; 01002 for (x = 140; x < 148; x++) 01003 { 01004 if (temp & 0x80) pixel(1,x,y); 01005 01006 temp <<= 1; 01007 } 01008 q++; 01009 temp = logo[q]; 01010 for (x = 148; x < 156; x++) 01011 { 01012 if (temp & 0x80) pixel(1,x,y); 01013 01014 temp <<= 1; 01015 } 01016 y--; 01017 q++; 01018 } 01019 01020 delay_ms(3000); 01021 clear_screen(); 01022 01023 } 01024 01025 01026 } 01027 01028 //Deletes a full character space. Endpoint == 0 for a backwards delete, 01029 //Endpoint != 0 to erase spot for a new character write 01030 void del_char(char endpoint) 01031 { 01032 char a, y; 01033 01034 if (endpoint == 0)//Backwards delete 01035 { 01036 if (x_offset <= 5) 01037 { 01038 x_offset += 152; 01039 y_offset += 8; 01040 01041 if (y_offset > 127) y_offset -= 128; 01042 } 01043 01044 else x_offset -= 6; 01045 } 01046 01047 for (a = x_offset; a < x_offset + 6; a++) 01048 { 01049 for (y = y_offset - 7; y <= y_offset; y++) 01050 { 01051 pixel(0, a, y); 01052 01053 } 01054 } 01055 01056 } 01057 01058 01059 //erases a block of the screen. Block is decribed 01060 //by a diagonal line from x, y1 to x2, y2 01061 void erase_block(char x1, char y1, char x2, char y2) 01062 { 01063 static char temp_x = 0, temp_y = 0; 01064 01065 for (temp_y = y2; temp_y >= y1; temp_y--) 01066 { 01067 for (temp_x = x1; temp_x <= x2; temp_x++) 01068 { 01069 pixel(0, temp_x, temp_y); 01070 01071 } 01072 } 01073 01074 01075 01076 } 01077 01078 //draws a box. The box is decribed 01079 //by a diagonal line from x, y1 to x2, y2 01080 void box(char x1, char y1, char x2, char y2) 01081 { 01082 line(1, x1, y1, x1, y2); 01083 line(1, x1, y1, x2, y1); 01084 line(1, x2, y1, x2, y2); 01085 line(1, x1, y2, x2, y2); 01086 01087 } 01088 01089 01090 01091 01092