Paul Evans
/
Newhaven_LCD
Newhaven 320x240 LCD
Revision 4:aa6dc362b462, committed 2011-02-28
- Comitter:
- pbevans89
- Date:
- Mon Feb 28 17:48:12 2011 +0000
- Parent:
- 3:1cf3ec6c70d7
- Commit message:
Changed in this revision
--- a/main.cpp Sun Feb 27 23:30:14 2011 +0000 +++ b/main.cpp Mon Feb 28 17:48:12 2011 +0000 @@ -1,3 +1,7 @@ +/* mbed Newhaven LCD simple Pong demonstration + * Copywrite (c) 2011, Paul Evans + */ + #include "mbed.h" #include "newhaven.h" @@ -5,19 +9,42 @@ NHLCD MyLCD(p5,p6,p7,p16,p17,&MyBus); int main() { - int i; + int r1 = 100, r2 = 100, rb = 115, cb = 155; + int dr = 5, dc = 5; + MyLCD.Init(); MyLCD.clearScreen(); wait(.5); + MyLCD.text("PONG!", 0, 15); + while(1) { - MyLCD.text("Hello World!", 10, 1); - wait(1); - for(i = 0; i < 20; i++){ - MyLCD.setPixel(i,i); + MyLCD.fillRect(r1, 0, 20, 4, 1); // draw the paddles and ball + MyLCD.fillRect(r2, 312, 20, 4, 1); + MyLCD.fillRect(rb, cb, 3, 3, 1); + + wait(.2); // wait between frames + + MyLCD.fillRect(r1, 0, 20, 4, 0); // clear the paddles and balls + MyLCD.fillRect(r2, 312, 20, 4, 0); + MyLCD.fillRect(rb, cb, 4, 4, 0); + + rb += dr; // move the ball + cb += dc; + if (cb > 100) { // move the right paddle if necessary + if (r2 > rb && r2 > 0) r2-=5; + else if (r2 < 214) r2+=5; } - wait(1); - MyLCD.clearScreen(); - wait(1); + if (cb < 220) { // move the left paddle if necessary + if (r1 > rb && r1 > 0) r1-=5; + else if (r1 < 214) r1+=5; + } + if (cb > 310 || cb < 4){ // check bounds for ball column + dc = -dc; + cb += dc; + }if (rb < 10 || rb > 234){ // check bounds for ball row + dr = -dr; + rb += dr; + } } }
--- a/newhaven.cpp Sun Feb 27 23:30:14 2011 +0000 +++ b/newhaven.cpp Mon Feb 28 17:48:12 2011 +0000 @@ -21,6 +21,12 @@ while(i--); } +void swap(int* a, int* b){ + int temp = *a; + *a = *b; + *b = temp; +} + // send commands to the LCD void NHLCD::comm_out(unsigned char j){ LCD_PORT->output(); // sets the buffer to output data @@ -29,7 +35,7 @@ CS = 0; // active LOW chip select RW = 0; // set to 0 for write operation E = 1; // operation enable - delay(1); // wait for operation to complete + //delay(1); // wait for operation to complete E = 0; // reset values RW = 1; CS = 1; @@ -43,7 +49,7 @@ CS = 0; // active LOW chip select RW = 0; // set to 0 for write operation E = 1; // operation enable - delay(1); // wait for operation to complete + //delay(1); // wait for operation to complete E = 0; // reset values RW = 1; CS = 1; @@ -84,31 +90,59 @@ /* set an individual pixel on the screen. * pixels are grouped in bytes, so you must isolate a particular pixel. */ -void NHLCD::setPixel(int row, int col){ - int loc = (0x04<<8)|(0xB0); //sets location to the top left corner of drawing screen - int c = loc+row*40+(col/8); // gets address of the correct byte - comm_out(0x46); // command to set cursor location - data_out((unsigned char)(c&0xFF)); // lower 8 bits of address - data_out((unsigned char)((c&0xFF00)>>8)); // upper 8 bits of address - comm_out(0x43); // command to read the byte - LCD_PORT->input(); // sets the buffer to input data - unsigned char buffer = LCD_PORT->read(); // stores byte in buffer - buffer = buffer|(1<<(7-((row*320+col)%8))); // sets the particular pixel on the byte - LCD_PORT->output(); // sets the buffer to output data - - comm_out(0x46); //command to set cursor location - data_out((unsigned char)(c&0xFF)); // lower 8 bits of address - data_out((unsigned char)((c&0xFF00)>>8)); // upper 8 bits of address - comm_out(0x42); // command to write to the screen - data_out(buffer); // write buffer to the screen +void NHLCD::setPixel(int row, int col, int color){ + int c = row*40+(col/8); // get location in buffer + char x = 1<<(7-(col%8)); // sets the bit to alter + if (color) // to mark the bit + screenBuffer[c] |= x; // marks the bit + else // to clear the bit + screenBuffer[c] &= ~x; // clears the bit + LCD_PORT->output(); // sets the buffer to output data + int loc = c+0x4B0; // get location on drawing screen + comm_out(0x46); // command to set cursor location + data_out((unsigned char)(loc&0xFF)); // lower 8 bits of address + data_out((unsigned char)((loc&0xFF00)>>8)); // upper 8 bits of address + comm_out(0x42); // command to write data + data_out(screenBuffer[c]); // write byte to the screen +} + +// draw a line -- Bresenham's line algorithm +void NHLCD::drawLine(int r1, int c1, int r2, int c2, int color){ + int w = r2 - r1; // calculate width of line + int h = c2 - c1; // calculate height of line + double ratio; + int x, y; + int upright = 0; // assumes the line is "wide" + if (abs(h) > abs(w)) { // checks if height is greater than width + upright = 1; // if it is, the line is "tall" + swap(&c1, &r1); // mirrors coordinates over the line y=x to make it "wide" + swap(&c2, &r2); + swap(&w, &h); + } + if (r1 > r2) { // if the first row is on the right, swaps start and end coordinates + swap(&c1, &c2); // now the line is always drawn from "bottom-left" to "top-right" + swap(&r1, &r2); + } + ratio = ((double) h) / w; // calculates ratio of height to width + for (x = r1; x < r2; x++) { // iterates through the rows + y = c1 + (x - r1) * ratio; // calculates the height at this particular row + if (upright) setPixel(y, x, color); // depending on if the line is "wide" or "tall", you have to + else setPixel(x, y, color); // call setPixel differently + } +} + +// draw and fill a rectangle +void NHLCD::fillRect(int row, int col, int height, int width, int color){ + for (int r = 0; r < height; r++) // iterate through each row + for (int c = 0; c < width; c++) // iterate through each column + setPixel(row+r,col+c,color); // set each pixel in the rectangle } // initialize the LCD void NHLCD::Init(void){ - /* reset the device */ - RST = 0; + RST = 0; // resets the device delay(5); - RST = 1; + RST = 1; // restarts it delay(10); comm_out(0x40); // system set command @@ -117,7 +151,7 @@ data_out(0x87); // horizontal character size (0x80 = 1) MUST BE MULTIPLE OF 320 data_out(0x07); // vertical character size (0x00 = 1) MUST BE MULTIPLE OF 240 data_out(40); // addresses per line - data_out(80); // bytes per line + data_out(80); // words per line data_out(0xEF); // 240 displace lines data_out(0x28); // virtual address 1 data_out(0x00); // virtual address 2 @@ -151,5 +185,7 @@ comm_out(0x59); // disp on/off data_out(0x16); // on - wait_ms(5); + + for(int i = 0; i < 40*240; i++) + screenBuffer[i] = 0; }
--- a/newhaven.h Sun Feb 27 23:30:14 2011 +0000 +++ b/newhaven.h Mon Feb 28 17:48:12 2011 +0000 @@ -67,14 +67,37 @@ * * @param row the row of the pixel * @param col the column of the pixel + * @param color 1 = on, 0 = off */ - void setPixel(int row, int col); + void setPixel(int row, int col, int color); + + /* draws a line on the LCD + * + * @param r1 the row of the first endpoint + * @param c1 the column of the first endpoint + * @param r2 the row of the second endpoint + * @param c2 the column of the second endpoint + * @param color 1 = on, 0 = off + */ + void drawLine(int r1, int c1, int r2, int c2, int color); + + /* draws and fills a rectangle on the LCD + * + * @param row the row of the top-left pixel + * @param col the column of the top-left pixel + * @param width the width of the rectangle + * @param height the height of the rectangle + * @param color 1 = on, 0 = off + */ + void fillRect(int row, int col, int width, int height, int color); private: DigitalOut E,RW,A0,CS,RST; - BusInOut *LCD_PORT; + BusInOut *LCD_PORT; + unsigned char screenBuffer[240*40]; }; void delay(unsigned int n); void delay1(unsigned int n); +void swap(int* a, int* b);