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