Paul Evans
/
Newhaven_LCD
Newhaven 320x240 LCD
newhaven.cpp@4:aa6dc362b462, 2011-02-28 (annotated)
- Committer:
- pbevans89
- Date:
- Mon Feb 28 17:48:12 2011 +0000
- Revision:
- 4:aa6dc362b462
- Parent:
- 3:1cf3ec6c70d7
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pbevans89 | 3:1cf3ec6c70d7 | 1 | /* mbed Newhaven LCD Library |
pbevans89 | 3:1cf3ec6c70d7 | 2 | * Copywrite (c) 2011, Paul Evans |
pbevans89 | 3:1cf3ec6c70d7 | 3 | */ |
pbevans89 | 3:1cf3ec6c70d7 | 4 | |
pbevans89 | 3:1cf3ec6c70d7 | 5 | #include "mbed.h" |
pbevans89 | 3:1cf3ec6c70d7 | 6 | #include "newhaven.h" |
pbevans89 | 3:1cf3ec6c70d7 | 7 | |
pbevans89 | 3:1cf3ec6c70d7 | 8 | NHLCD::NHLCD(PinName PIN_E,PinName PIN_RW,PinName PIN_A0,PinName PIN_CS,PinName PIN_RST, BusInOut *BUSLCD) |
pbevans89 | 3:1cf3ec6c70d7 | 9 | : E(PIN_E),RW(PIN_RW),A0(PIN_A0),CS(PIN_CS),RST(PIN_RST){ |
pbevans89 | 3:1cf3ec6c70d7 | 10 | LCD_PORT = BUSLCD; |
pbevans89 | 3:1cf3ec6c70d7 | 11 | } |
pbevans89 | 3:1cf3ec6c70d7 | 12 | |
pbevans89 | 3:1cf3ec6c70d7 | 13 | void delay(unsigned int n){ |
pbevans89 | 3:1cf3ec6c70d7 | 14 | unsigned int i,j; |
pbevans89 | 3:1cf3ec6c70d7 | 15 | for (i=0;i<n;i++) |
pbevans89 | 3:1cf3ec6c70d7 | 16 | for (j=0;j<350;j++) |
pbevans89 | 3:1cf3ec6c70d7 | 17 | {;} |
pbevans89 | 3:1cf3ec6c70d7 | 18 | } |
pbevans89 | 3:1cf3ec6c70d7 | 19 | |
pbevans89 | 3:1cf3ec6c70d7 | 20 | void delay1(unsigned int i){ |
pbevans89 | 3:1cf3ec6c70d7 | 21 | while(i--); |
pbevans89 | 3:1cf3ec6c70d7 | 22 | } |
pbevans89 | 3:1cf3ec6c70d7 | 23 | |
pbevans89 | 4:aa6dc362b462 | 24 | void swap(int* a, int* b){ |
pbevans89 | 4:aa6dc362b462 | 25 | int temp = *a; |
pbevans89 | 4:aa6dc362b462 | 26 | *a = *b; |
pbevans89 | 4:aa6dc362b462 | 27 | *b = temp; |
pbevans89 | 4:aa6dc362b462 | 28 | } |
pbevans89 | 4:aa6dc362b462 | 29 | |
pbevans89 | 3:1cf3ec6c70d7 | 30 | // send commands to the LCD |
pbevans89 | 3:1cf3ec6c70d7 | 31 | void NHLCD::comm_out(unsigned char j){ |
pbevans89 | 3:1cf3ec6c70d7 | 32 | LCD_PORT->output(); // sets the buffer to output data |
pbevans89 | 3:1cf3ec6c70d7 | 33 | A0 = 1; // set for a command output |
pbevans89 | 3:1cf3ec6c70d7 | 34 | LCD_PORT->write(j); // send the data in the buffer |
pbevans89 | 3:1cf3ec6c70d7 | 35 | CS = 0; // active LOW chip select |
pbevans89 | 3:1cf3ec6c70d7 | 36 | RW = 0; // set to 0 for write operation |
pbevans89 | 3:1cf3ec6c70d7 | 37 | E = 1; // operation enable |
pbevans89 | 4:aa6dc362b462 | 38 | //delay(1); // wait for operation to complete |
pbevans89 | 3:1cf3ec6c70d7 | 39 | E = 0; // reset values |
pbevans89 | 3:1cf3ec6c70d7 | 40 | RW = 1; |
pbevans89 | 3:1cf3ec6c70d7 | 41 | CS = 1; |
pbevans89 | 3:1cf3ec6c70d7 | 42 | } |
pbevans89 | 3:1cf3ec6c70d7 | 43 | |
pbevans89 | 3:1cf3ec6c70d7 | 44 | // send data to the LCD |
pbevans89 | 3:1cf3ec6c70d7 | 45 | void NHLCD::data_out(unsigned char j){ |
pbevans89 | 3:1cf3ec6c70d7 | 46 | LCD_PORT->output(); // sets the buffer to output data |
pbevans89 | 3:1cf3ec6c70d7 | 47 | A0 = 0; // set for a data output |
pbevans89 | 3:1cf3ec6c70d7 | 48 | LCD_PORT->write(j); // send the data in the buffer |
pbevans89 | 3:1cf3ec6c70d7 | 49 | CS = 0; // active LOW chip select |
pbevans89 | 3:1cf3ec6c70d7 | 50 | RW = 0; // set to 0 for write operation |
pbevans89 | 3:1cf3ec6c70d7 | 51 | E = 1; // operation enable |
pbevans89 | 4:aa6dc362b462 | 52 | //delay(1); // wait for operation to complete |
pbevans89 | 3:1cf3ec6c70d7 | 53 | E = 0; // reset values |
pbevans89 | 3:1cf3ec6c70d7 | 54 | RW = 1; |
pbevans89 | 3:1cf3ec6c70d7 | 55 | CS = 1; |
pbevans89 | 3:1cf3ec6c70d7 | 56 | } |
pbevans89 | 3:1cf3ec6c70d7 | 57 | |
pbevans89 | 3:1cf3ec6c70d7 | 58 | // clears the entire screen |
pbevans89 | 3:1cf3ec6c70d7 | 59 | void NHLCD::clearScreen(){ |
pbevans89 | 3:1cf3ec6c70d7 | 60 | int n; |
pbevans89 | 3:1cf3ec6c70d7 | 61 | comm_out(0x46); // command to set cursor location |
pbevans89 | 3:1cf3ec6c70d7 | 62 | data_out(0x00); // 0x00 is the start of text screen |
pbevans89 | 3:1cf3ec6c70d7 | 63 | data_out(0x00); |
pbevans89 | 3:1cf3ec6c70d7 | 64 | comm_out(0x42); // command to write data |
pbevans89 | 3:1cf3ec6c70d7 | 65 | for(n=0;n<1200;n++){ // 1200 locations on the screen |
pbevans89 | 3:1cf3ec6c70d7 | 66 | data_out(0x20); // fill each with a blank |
pbevans89 | 3:1cf3ec6c70d7 | 67 | } |
pbevans89 | 3:1cf3ec6c70d7 | 68 | comm_out(0x46); // command to set cursor location |
pbevans89 | 3:1cf3ec6c70d7 | 69 | data_out(0xB0); // 0x4B0 is the start of drawing screen |
pbevans89 | 3:1cf3ec6c70d7 | 70 | data_out(0x04); |
pbevans89 | 3:1cf3ec6c70d7 | 71 | comm_out(0x42); // command to write data |
pbevans89 | 3:1cf3ec6c70d7 | 72 | for(n=0;n<9600;n++){ // 9600 total byte locations |
pbevans89 | 3:1cf3ec6c70d7 | 73 | data_out(0x00); // set each to 0 |
pbevans89 | 3:1cf3ec6c70d7 | 74 | } |
pbevans89 | 3:1cf3ec6c70d7 | 75 | } |
pbevans89 | 3:1cf3ec6c70d7 | 76 | |
pbevans89 | 3:1cf3ec6c70d7 | 77 | // write text on the screen |
pbevans89 | 3:1cf3ec6c70d7 | 78 | void NHLCD::text(char *text, char row, char col){ |
pbevans89 | 3:1cf3ec6c70d7 | 79 | int c = row*40+col; // gets the correct address for the cursor |
pbevans89 | 3:1cf3ec6c70d7 | 80 | comm_out(0x46); // command to set cursor location |
pbevans89 | 3:1cf3ec6c70d7 | 81 | data_out((unsigned char)(c&0xFF)); // lower 8 bits of address |
pbevans89 | 3:1cf3ec6c70d7 | 82 | data_out((unsigned char)((c&0xFF00)>>8)); // upper 8 bits of address |
pbevans89 | 3:1cf3ec6c70d7 | 83 | comm_out(0x42); // command to write data to screen |
pbevans89 | 3:1cf3ec6c70d7 | 84 | while(*text != 0) { // write until you hit a null terminator |
pbevans89 | 3:1cf3ec6c70d7 | 85 | data_out(*text); // write the current character to the screen |
pbevans89 | 3:1cf3ec6c70d7 | 86 | text++; // move to the next character |
pbevans89 | 3:1cf3ec6c70d7 | 87 | } |
pbevans89 | 3:1cf3ec6c70d7 | 88 | } |
pbevans89 | 3:1cf3ec6c70d7 | 89 | |
pbevans89 | 3:1cf3ec6c70d7 | 90 | /* set an individual pixel on the screen. |
pbevans89 | 3:1cf3ec6c70d7 | 91 | * pixels are grouped in bytes, so you must isolate a particular pixel. |
pbevans89 | 3:1cf3ec6c70d7 | 92 | */ |
pbevans89 | 4:aa6dc362b462 | 93 | void NHLCD::setPixel(int row, int col, int color){ |
pbevans89 | 4:aa6dc362b462 | 94 | int c = row*40+(col/8); // get location in buffer |
pbevans89 | 4:aa6dc362b462 | 95 | char x = 1<<(7-(col%8)); // sets the bit to alter |
pbevans89 | 4:aa6dc362b462 | 96 | if (color) // to mark the bit |
pbevans89 | 4:aa6dc362b462 | 97 | screenBuffer[c] |= x; // marks the bit |
pbevans89 | 4:aa6dc362b462 | 98 | else // to clear the bit |
pbevans89 | 4:aa6dc362b462 | 99 | screenBuffer[c] &= ~x; // clears the bit |
pbevans89 | 4:aa6dc362b462 | 100 | LCD_PORT->output(); // sets the buffer to output data |
pbevans89 | 4:aa6dc362b462 | 101 | int loc = c+0x4B0; // get location on drawing screen |
pbevans89 | 4:aa6dc362b462 | 102 | comm_out(0x46); // command to set cursor location |
pbevans89 | 4:aa6dc362b462 | 103 | data_out((unsigned char)(loc&0xFF)); // lower 8 bits of address |
pbevans89 | 4:aa6dc362b462 | 104 | data_out((unsigned char)((loc&0xFF00)>>8)); // upper 8 bits of address |
pbevans89 | 4:aa6dc362b462 | 105 | comm_out(0x42); // command to write data |
pbevans89 | 4:aa6dc362b462 | 106 | data_out(screenBuffer[c]); // write byte to the screen |
pbevans89 | 4:aa6dc362b462 | 107 | } |
pbevans89 | 4:aa6dc362b462 | 108 | |
pbevans89 | 4:aa6dc362b462 | 109 | // draw a line -- Bresenham's line algorithm |
pbevans89 | 4:aa6dc362b462 | 110 | void NHLCD::drawLine(int r1, int c1, int r2, int c2, int color){ |
pbevans89 | 4:aa6dc362b462 | 111 | int w = r2 - r1; // calculate width of line |
pbevans89 | 4:aa6dc362b462 | 112 | int h = c2 - c1; // calculate height of line |
pbevans89 | 4:aa6dc362b462 | 113 | double ratio; |
pbevans89 | 4:aa6dc362b462 | 114 | int x, y; |
pbevans89 | 4:aa6dc362b462 | 115 | int upright = 0; // assumes the line is "wide" |
pbevans89 | 4:aa6dc362b462 | 116 | if (abs(h) > abs(w)) { // checks if height is greater than width |
pbevans89 | 4:aa6dc362b462 | 117 | upright = 1; // if it is, the line is "tall" |
pbevans89 | 4:aa6dc362b462 | 118 | swap(&c1, &r1); // mirrors coordinates over the line y=x to make it "wide" |
pbevans89 | 4:aa6dc362b462 | 119 | swap(&c2, &r2); |
pbevans89 | 4:aa6dc362b462 | 120 | swap(&w, &h); |
pbevans89 | 4:aa6dc362b462 | 121 | } |
pbevans89 | 4:aa6dc362b462 | 122 | if (r1 > r2) { // if the first row is on the right, swaps start and end coordinates |
pbevans89 | 4:aa6dc362b462 | 123 | swap(&c1, &c2); // now the line is always drawn from "bottom-left" to "top-right" |
pbevans89 | 4:aa6dc362b462 | 124 | swap(&r1, &r2); |
pbevans89 | 4:aa6dc362b462 | 125 | } |
pbevans89 | 4:aa6dc362b462 | 126 | ratio = ((double) h) / w; // calculates ratio of height to width |
pbevans89 | 4:aa6dc362b462 | 127 | for (x = r1; x < r2; x++) { // iterates through the rows |
pbevans89 | 4:aa6dc362b462 | 128 | y = c1 + (x - r1) * ratio; // calculates the height at this particular row |
pbevans89 | 4:aa6dc362b462 | 129 | if (upright) setPixel(y, x, color); // depending on if the line is "wide" or "tall", you have to |
pbevans89 | 4:aa6dc362b462 | 130 | else setPixel(x, y, color); // call setPixel differently |
pbevans89 | 4:aa6dc362b462 | 131 | } |
pbevans89 | 4:aa6dc362b462 | 132 | } |
pbevans89 | 4:aa6dc362b462 | 133 | |
pbevans89 | 4:aa6dc362b462 | 134 | // draw and fill a rectangle |
pbevans89 | 4:aa6dc362b462 | 135 | void NHLCD::fillRect(int row, int col, int height, int width, int color){ |
pbevans89 | 4:aa6dc362b462 | 136 | for (int r = 0; r < height; r++) // iterate through each row |
pbevans89 | 4:aa6dc362b462 | 137 | for (int c = 0; c < width; c++) // iterate through each column |
pbevans89 | 4:aa6dc362b462 | 138 | setPixel(row+r,col+c,color); // set each pixel in the rectangle |
pbevans89 | 3:1cf3ec6c70d7 | 139 | } |
pbevans89 | 3:1cf3ec6c70d7 | 140 | |
pbevans89 | 3:1cf3ec6c70d7 | 141 | // initialize the LCD |
pbevans89 | 3:1cf3ec6c70d7 | 142 | void NHLCD::Init(void){ |
pbevans89 | 4:aa6dc362b462 | 143 | RST = 0; // resets the device |
pbevans89 | 3:1cf3ec6c70d7 | 144 | delay(5); |
pbevans89 | 4:aa6dc362b462 | 145 | RST = 1; // restarts it |
pbevans89 | 3:1cf3ec6c70d7 | 146 | delay(10); |
pbevans89 | 3:1cf3ec6c70d7 | 147 | |
pbevans89 | 3:1cf3ec6c70d7 | 148 | comm_out(0x40); // system set command |
pbevans89 | 3:1cf3ec6c70d7 | 149 | delay(5); |
pbevans89 | 3:1cf3ec6c70d7 | 150 | data_out(0x30); // parameters |
pbevans89 | 3:1cf3ec6c70d7 | 151 | data_out(0x87); // horizontal character size (0x80 = 1) MUST BE MULTIPLE OF 320 |
pbevans89 | 3:1cf3ec6c70d7 | 152 | data_out(0x07); // vertical character size (0x00 = 1) MUST BE MULTIPLE OF 240 |
pbevans89 | 3:1cf3ec6c70d7 | 153 | data_out(40); // addresses per line |
pbevans89 | 4:aa6dc362b462 | 154 | data_out(80); // words per line |
pbevans89 | 3:1cf3ec6c70d7 | 155 | data_out(0xEF); // 240 displace lines |
pbevans89 | 3:1cf3ec6c70d7 | 156 | data_out(0x28); // virtual address 1 |
pbevans89 | 3:1cf3ec6c70d7 | 157 | data_out(0x00); // virtual address 2 |
pbevans89 | 3:1cf3ec6c70d7 | 158 | |
pbevans89 | 3:1cf3ec6c70d7 | 159 | comm_out(0x44); // scroll |
pbevans89 | 3:1cf3ec6c70d7 | 160 | data_out(0x00); // start address 1 |
pbevans89 | 3:1cf3ec6c70d7 | 161 | data_out(0x00); // start address 2 |
pbevans89 | 3:1cf3ec6c70d7 | 162 | data_out(0xEF); // 240 lines |
pbevans89 | 3:1cf3ec6c70d7 | 163 | data_out(0xB0); // 2nd screen start1 |
pbevans89 | 3:1cf3ec6c70d7 | 164 | data_out(0x04); // 2nd screen start2 |
pbevans89 | 3:1cf3ec6c70d7 | 165 | data_out(0xEF); // 2nd screen 240 lines |
pbevans89 | 3:1cf3ec6c70d7 | 166 | data_out(0x00); // 3rd screen address1 |
pbevans89 | 3:1cf3ec6c70d7 | 167 | data_out(0x00); // 3rd screen address2 |
pbevans89 | 3:1cf3ec6c70d7 | 168 | data_out(0x00); // 4th screen address1 |
pbevans89 | 3:1cf3ec6c70d7 | 169 | data_out(0x00); // 4th screen address2 |
pbevans89 | 3:1cf3ec6c70d7 | 170 | |
pbevans89 | 3:1cf3ec6c70d7 | 171 | comm_out(0x5A); // hdot scr |
pbevans89 | 3:1cf3ec6c70d7 | 172 | data_out(0x00); // horizontal pixel shift = 0 |
pbevans89 | 3:1cf3ec6c70d7 | 173 | |
pbevans89 | 3:1cf3ec6c70d7 | 174 | comm_out(0x5B); // overlay |
pbevans89 | 3:1cf3ec6c70d7 | 175 | data_out(0x00); // OR |
pbevans89 | 3:1cf3ec6c70d7 | 176 | |
pbevans89 | 3:1cf3ec6c70d7 | 177 | comm_out(0x58); // set display |
pbevans89 | 3:1cf3ec6c70d7 | 178 | data_out(0x56); |
pbevans89 | 3:1cf3ec6c70d7 | 179 | |
pbevans89 | 3:1cf3ec6c70d7 | 180 | comm_out(0x5D); // cursor form |
pbevans89 | 3:1cf3ec6c70d7 | 181 | data_out(0x04); // 5 pixels wide |
pbevans89 | 3:1cf3ec6c70d7 | 182 | data_out(0x86); // 7 pixels tall |
pbevans89 | 3:1cf3ec6c70d7 | 183 | |
pbevans89 | 3:1cf3ec6c70d7 | 184 | comm_out(0x4C); // cursor direction = right |
pbevans89 | 3:1cf3ec6c70d7 | 185 | |
pbevans89 | 3:1cf3ec6c70d7 | 186 | comm_out(0x59); // disp on/off |
pbevans89 | 3:1cf3ec6c70d7 | 187 | data_out(0x16); // on |
pbevans89 | 4:aa6dc362b462 | 188 | |
pbevans89 | 4:aa6dc362b462 | 189 | for(int i = 0; i < 40*240; i++) |
pbevans89 | 4:aa6dc362b462 | 190 | screenBuffer[i] = 0; |
pbevans89 | 3:1cf3ec6c70d7 | 191 | } |