Simple library for UC1701 based GLCD's
Dependents: Opensmart_LCD_UC1701
With lots of fonts! Will include more in the future. A couple bitmaps have also been added.
UC1701.cpp@3:baaa16e24adc, 2016-12-19 (annotated)
- Committer:
- Anaesthetix
- Date:
- Mon Dec 19 12:58:10 2016 +0000
- Revision:
- 3:baaa16e24adc
- Parent:
- 1:f396898c2963
- Child:
- 4:8da4c691643a
Added setContrast() function
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Anaesthetix | 0:a8cfaf48d064 | 1 | /** |
Anaesthetix | 0:a8cfaf48d064 | 2 | * This is a simple library for UC1701 controlled graphic LCD's. |
Anaesthetix | 0:a8cfaf48d064 | 3 | * Written for a cheap OPEN-SMART 1.8" 128x64 display |
Anaesthetix | 0:a8cfaf48d064 | 4 | * See http://www.dx.com/p/open-smart-1-8-128-64-lcd-display-breakout-module-w-blue-backlit-444694 |
Anaesthetix | 1:f396898c2963 | 5 | * |
Anaesthetix | 0:a8cfaf48d064 | 6 | * Written by: Erik van de Coevering |
Anaesthetix | 0:a8cfaf48d064 | 7 | * With special thanks to Tim Barr from whom I've reused some code |
Anaesthetix | 0:a8cfaf48d064 | 8 | * Use this code in whatever way you like, as long as it stays free of charge! |
Anaesthetix | 0:a8cfaf48d064 | 9 | */ |
Anaesthetix | 0:a8cfaf48d064 | 10 | |
Anaesthetix | 0:a8cfaf48d064 | 11 | #include "UC1701.h" |
Anaesthetix | 0:a8cfaf48d064 | 12 | |
Anaesthetix | 0:a8cfaf48d064 | 13 | UC1701::UC1701(SPI &lcd, DigitalOut &lcd_cs, DigitalOut &lcd_cd) |
Anaesthetix | 0:a8cfaf48d064 | 14 | { |
Anaesthetix | 0:a8cfaf48d064 | 15 | _lcd = &lcd; |
Anaesthetix | 0:a8cfaf48d064 | 16 | _lcd_cs = &lcd_cs; |
Anaesthetix | 0:a8cfaf48d064 | 17 | _lcd_cd = &lcd_cd; |
Anaesthetix | 0:a8cfaf48d064 | 18 | } |
Anaesthetix | 0:a8cfaf48d064 | 19 | |
Anaesthetix | 0:a8cfaf48d064 | 20 | void UC1701::init() |
Anaesthetix | 0:a8cfaf48d064 | 21 | { |
Anaesthetix | 0:a8cfaf48d064 | 22 | _lcd_cs->write(1); |
Anaesthetix | 0:a8cfaf48d064 | 23 | _lcd->frequency(24000000); // Abusing SPI to save some time.. |
Anaesthetix | 0:a8cfaf48d064 | 24 | _lcd->format(8,3); |
Anaesthetix | 0:a8cfaf48d064 | 25 | _lcd_cs->write(0); // enable SPI |
Anaesthetix | 0:a8cfaf48d064 | 26 | _lcd_cd->write(0); // COMMAND mode |
Anaesthetix | 0:a8cfaf48d064 | 27 | |
Anaesthetix | 0:a8cfaf48d064 | 28 | wait_ms(50); |
Anaesthetix | 0:a8cfaf48d064 | 29 | |
Anaesthetix | 0:a8cfaf48d064 | 30 | _lcd->write(0xE2); // Reset |
Anaesthetix | 0:a8cfaf48d064 | 31 | _lcd->write(0x40); // Set display start line to 0 |
Anaesthetix | 0:a8cfaf48d064 | 32 | _lcd->write(0xA1); // Set SEG direction |
Anaesthetix | 0:a8cfaf48d064 | 33 | _lcd->write(0xC0); // Set COM direction |
Anaesthetix | 0:a8cfaf48d064 | 34 | _lcd->write(0xA2); // Set bias = 1/9 |
Anaesthetix | 0:a8cfaf48d064 | 35 | _lcd->write(0x2C); // Boost ON |
Anaesthetix | 0:a8cfaf48d064 | 36 | _lcd->write(0x2E); // Voltage regulator on |
Anaesthetix | 0:a8cfaf48d064 | 37 | _lcd->write(0x2F); // Voltage follower on |
Anaesthetix | 0:a8cfaf48d064 | 38 | _lcd->write(0xF8); // Set booster ratio |
Anaesthetix | 3:baaa16e24adc | 39 | _lcd->write(0x00); |
Anaesthetix | 0:a8cfaf48d064 | 40 | _lcd->write(0x23); // Set resistor ratio |
Anaesthetix | 3:baaa16e24adc | 41 | _lcd->write(0x81); // Set contrast to |
Anaesthetix | 3:baaa16e24adc | 42 | _lcd->write(0x28); // 40 |
Anaesthetix | 3:baaa16e24adc | 43 | _lcd->write(0xEE); // Set cursor update -> after write, column cursor will be updated (rows will not!) |
Anaesthetix | 0:a8cfaf48d064 | 44 | _lcd->write(0xAC); // Disable static indicator |
Anaesthetix | 0:a8cfaf48d064 | 45 | _lcd->write(0x00); |
Anaesthetix | 0:a8cfaf48d064 | 46 | _lcd->write(0xA6); // Disable inverse |
Anaesthetix | 0:a8cfaf48d064 | 47 | _lcd->write(0xAF); // Display enable |
Anaesthetix | 3:baaa16e24adc | 48 | //_lcd->write(0xA5); // display all points |
Anaesthetix | 0:a8cfaf48d064 | 49 | _lcd->write(0xA4); // clear |
Anaesthetix | 3:baaa16e24adc | 50 | _lcd_cs->write(1); // disable SPI |
Anaesthetix | 3:baaa16e24adc | 51 | _lcd_cd->write(1); // DATA mode |
Anaesthetix | 0:a8cfaf48d064 | 52 | |
Anaesthetix | 0:a8cfaf48d064 | 53 | } |
Anaesthetix | 0:a8cfaf48d064 | 54 | |
Anaesthetix | 3:baaa16e24adc | 55 | void UC1701::setContrast(char contrast) |
Anaesthetix | 3:baaa16e24adc | 56 | { |
Anaesthetix | 3:baaa16e24adc | 57 | _lcd_cs->write(0); // enable SPI |
Anaesthetix | 3:baaa16e24adc | 58 | _lcd_cd->write(0); // command mode |
Anaesthetix | 3:baaa16e24adc | 59 | _lcd->write(0x81); // command to set contrast |
Anaesthetix | 3:baaa16e24adc | 60 | _lcd->write(contrast); // set contrast |
Anaesthetix | 3:baaa16e24adc | 61 | _lcd_cs->write(1); |
Anaesthetix | 3:baaa16e24adc | 62 | _lcd_cd->write(1); |
Anaesthetix | 3:baaa16e24adc | 63 | } |
Anaesthetix | 3:baaa16e24adc | 64 | |
Anaesthetix | 0:a8cfaf48d064 | 65 | void UC1701::setCursor(char column, char line) |
Anaesthetix | 0:a8cfaf48d064 | 66 | { |
Anaesthetix | 0:a8cfaf48d064 | 67 | int i, j; |
Anaesthetix | 0:a8cfaf48d064 | 68 | column = column+4; |
Anaesthetix | 0:a8cfaf48d064 | 69 | |
Anaesthetix | 0:a8cfaf48d064 | 70 | i=(column&0xF0)>>4; |
Anaesthetix | 0:a8cfaf48d064 | 71 | j=column&0x0F; |
Anaesthetix | 0:a8cfaf48d064 | 72 | _lcd_cd->write(0); |
Anaesthetix | 0:a8cfaf48d064 | 73 | _lcd->write(0xb0+line); |
Anaesthetix | 0:a8cfaf48d064 | 74 | _lcd->write(0x10+i); |
Anaesthetix | 0:a8cfaf48d064 | 75 | _lcd->write(j); |
Anaesthetix | 0:a8cfaf48d064 | 76 | _lcd_cd->write(1); |
Anaesthetix | 0:a8cfaf48d064 | 77 | } |
Anaesthetix | 0:a8cfaf48d064 | 78 | |
Anaesthetix | 0:a8cfaf48d064 | 79 | void UC1701::clear() |
Anaesthetix | 0:a8cfaf48d064 | 80 | { |
Anaesthetix | 0:a8cfaf48d064 | 81 | _lcd_cs->write(0); |
Anaesthetix | 0:a8cfaf48d064 | 82 | _lcd_cd->write(1); |
Anaesthetix | 0:a8cfaf48d064 | 83 | |
Anaesthetix | 0:a8cfaf48d064 | 84 | for(unsigned short j = 0; j < 8; j++) { |
Anaesthetix | 0:a8cfaf48d064 | 85 | UC1701::setCursor(0, j); |
Anaesthetix | 0:a8cfaf48d064 | 86 | for(unsigned short i = 0; i < 128 ; i++) { |
Anaesthetix | 0:a8cfaf48d064 | 87 | _lcd->write(0x00); |
Anaesthetix | 0:a8cfaf48d064 | 88 | } |
Anaesthetix | 0:a8cfaf48d064 | 89 | } |
Anaesthetix | 0:a8cfaf48d064 | 90 | |
Anaesthetix | 0:a8cfaf48d064 | 91 | UC1701::setCursor(0, 0); |
Anaesthetix | 0:a8cfaf48d064 | 92 | |
Anaesthetix | 0:a8cfaf48d064 | 93 | _lcd_cs->write(1); |
Anaesthetix | 0:a8cfaf48d064 | 94 | } |
Anaesthetix | 0:a8cfaf48d064 | 95 | |
Anaesthetix | 0:a8cfaf48d064 | 96 | // fill() only used to optimize the library. Using command 0xA5 is faster, if needed. |
Anaesthetix | 0:a8cfaf48d064 | 97 | void UC1701::fill() |
Anaesthetix | 0:a8cfaf48d064 | 98 | { |
Anaesthetix | 0:a8cfaf48d064 | 99 | _lcd_cs->write(0); |
Anaesthetix | 0:a8cfaf48d064 | 100 | _lcd_cd->write(1); |
Anaesthetix | 0:a8cfaf48d064 | 101 | |
Anaesthetix | 0:a8cfaf48d064 | 102 | for(unsigned short j = 0; j < 8; j++) { |
Anaesthetix | 0:a8cfaf48d064 | 103 | UC1701::setCursor(0, j); |
Anaesthetix | 0:a8cfaf48d064 | 104 | for(unsigned short i = 0; i < 128 ; i++) { |
Anaesthetix | 0:a8cfaf48d064 | 105 | _lcd->write(0xFF); |
Anaesthetix | 0:a8cfaf48d064 | 106 | } |
Anaesthetix | 0:a8cfaf48d064 | 107 | } |
Anaesthetix | 0:a8cfaf48d064 | 108 | |
Anaesthetix | 0:a8cfaf48d064 | 109 | UC1701::setCursor(0, 0); |
Anaesthetix | 0:a8cfaf48d064 | 110 | |
Anaesthetix | 0:a8cfaf48d064 | 111 | _lcd_cs->write(1); |
Anaesthetix | 0:a8cfaf48d064 | 112 | } |
Anaesthetix | 0:a8cfaf48d064 | 113 | |
Anaesthetix | 0:a8cfaf48d064 | 114 | void UC1701::writeText2d(char column, char page, const char font_address[96][8], const char *text, int size) |
Anaesthetix | 0:a8cfaf48d064 | 115 | { |
Anaesthetix | 0:a8cfaf48d064 | 116 | _lcd_cs->write(0); |
Anaesthetix | 0:a8cfaf48d064 | 117 | UC1701::setCursor(column, page); |
Anaesthetix | 0:a8cfaf48d064 | 118 | for(int i=0; i<=size; i++) { |
Anaesthetix | 0:a8cfaf48d064 | 119 | for(int a=0; a<8; a++) { |
Anaesthetix | 0:a8cfaf48d064 | 120 | _lcd->write((font_address[(text[i]-32)][a])); |
Anaesthetix | 0:a8cfaf48d064 | 121 | } |
Anaesthetix | 0:a8cfaf48d064 | 122 | } |
Anaesthetix | 0:a8cfaf48d064 | 123 | _lcd_cs->write(1); |
Anaesthetix | 0:a8cfaf48d064 | 124 | } |
Anaesthetix | 0:a8cfaf48d064 | 125 | |
Anaesthetix | 0:a8cfaf48d064 | 126 | void UC1701::writeText(char column, char page, const char *font_address, const char *text, const uint8_t size) |
Anaesthetix | 0:a8cfaf48d064 | 127 | { |
Anaesthetix | 0:a8cfaf48d064 | 128 | // Position of character data in memory array |
Anaesthetix | 0:a8cfaf48d064 | 129 | uint16_t pos_array; |
Anaesthetix | 0:a8cfaf48d064 | 130 | // temporary column, page address, and column_cnt are used |
Anaesthetix | 0:a8cfaf48d064 | 131 | // to stay inside display area |
Anaesthetix | 0:a8cfaf48d064 | 132 | uint8_t i,y, column_cnt = 0; |
Anaesthetix | 0:a8cfaf48d064 | 133 | uint8_t count = 0; |
Anaesthetix | 0:a8cfaf48d064 | 134 | |
Anaesthetix | 0:a8cfaf48d064 | 135 | // font information, needed for calculation |
Anaesthetix | 0:a8cfaf48d064 | 136 | uint8_t start_code, last_code, width, page_height, bytes_p_char; |
Anaesthetix | 0:a8cfaf48d064 | 137 | |
Anaesthetix | 0:a8cfaf48d064 | 138 | uint8_t *txtbuffer; |
Anaesthetix | 0:a8cfaf48d064 | 139 | |
Anaesthetix | 0:a8cfaf48d064 | 140 | start_code = font_address[2]; // get first defined character |
Anaesthetix | 0:a8cfaf48d064 | 141 | last_code = font_address[3]; // get last defined character |
Anaesthetix | 0:a8cfaf48d064 | 142 | width = font_address[4]; // width in pixel of one char |
Anaesthetix | 0:a8cfaf48d064 | 143 | page_height = font_address[6]; // page count per char |
Anaesthetix | 0:a8cfaf48d064 | 144 | bytes_p_char = font_address[7]; // bytes per char |
Anaesthetix | 0:a8cfaf48d064 | 145 | |
Anaesthetix | 0:a8cfaf48d064 | 146 | _lcd_cs->write(0); // Enable SPI |
Anaesthetix | 0:a8cfaf48d064 | 147 | _lcd_cd->write(1); // Data mode |
Anaesthetix | 0:a8cfaf48d064 | 148 | |
Anaesthetix | 0:a8cfaf48d064 | 149 | if(page_height + page > LCDPAGES) //stay inside display area |
Anaesthetix | 0:a8cfaf48d064 | 150 | page_height = LCDPAGES - page; |
Anaesthetix | 0:a8cfaf48d064 | 151 | |
Anaesthetix | 0:a8cfaf48d064 | 152 | // The string is displayed character after character. If the font has more then one page, |
Anaesthetix | 0:a8cfaf48d064 | 153 | // the top page is printed first, then the next page and so on |
Anaesthetix | 0:a8cfaf48d064 | 154 | for(y = 0; y < page_height; y++) { |
Anaesthetix | 0:a8cfaf48d064 | 155 | txtbuffer = &_lcdbuffer[page*LCDWIDTH + column]; |
Anaesthetix | 0:a8cfaf48d064 | 156 | column_cnt = 0; // clear column_cnt start point |
Anaesthetix | 0:a8cfaf48d064 | 157 | i = 0; |
Anaesthetix | 0:a8cfaf48d064 | 158 | while(( i < size) && ((column_cnt + column) < LCDWIDTH)) { |
Anaesthetix | 0:a8cfaf48d064 | 159 | if(text[i] < start_code || (uint8_t)text[i] > last_code) //make sure data is valid |
Anaesthetix | 0:a8cfaf48d064 | 160 | i++; |
Anaesthetix | 0:a8cfaf48d064 | 161 | else { |
Anaesthetix | 0:a8cfaf48d064 | 162 | // calculate position of ASCII character in font array |
Anaesthetix | 0:a8cfaf48d064 | 163 | // bytes for header + (ASCII - startcode) * bytes per char) |
Anaesthetix | 0:a8cfaf48d064 | 164 | pos_array = 8 + (uint8_t)(text[i++] - start_code) * bytes_p_char; |
Anaesthetix | 0:a8cfaf48d064 | 165 | |
Anaesthetix | 0:a8cfaf48d064 | 166 | // get the dot pattern for the part of the char to print |
Anaesthetix | 0:a8cfaf48d064 | 167 | pos_array += y*width; |
Anaesthetix | 0:a8cfaf48d064 | 168 | |
Anaesthetix | 0:a8cfaf48d064 | 169 | // stay inside display area |
Anaesthetix | 0:a8cfaf48d064 | 170 | if((column_cnt + width + column) > LCDWIDTH) |
Anaesthetix | 0:a8cfaf48d064 | 171 | column_cnt = LCDWIDTH-width; |
Anaesthetix | 0:a8cfaf48d064 | 172 | |
Anaesthetix | 0:a8cfaf48d064 | 173 | // copy character data to buffer |
Anaesthetix | 0:a8cfaf48d064 | 174 | memcpy (txtbuffer+column_cnt,font_address+pos_array,width); |
Anaesthetix | 0:a8cfaf48d064 | 175 | } |
Anaesthetix | 0:a8cfaf48d064 | 176 | |
Anaesthetix | 0:a8cfaf48d064 | 177 | column_cnt += width; |
Anaesthetix | 0:a8cfaf48d064 | 178 | } |
Anaesthetix | 0:a8cfaf48d064 | 179 | UC1701::setCursor(column,page); // set start position x and y |
Anaesthetix | 0:a8cfaf48d064 | 180 | |
Anaesthetix | 0:a8cfaf48d064 | 181 | do { |
Anaesthetix | 0:a8cfaf48d064 | 182 | _lcd->write(txtbuffer[count]); |
Anaesthetix | 0:a8cfaf48d064 | 183 | count++; |
Anaesthetix | 0:a8cfaf48d064 | 184 | } while ((count <= column_cnt)); |
Anaesthetix | 0:a8cfaf48d064 | 185 | } |
Anaesthetix | 0:a8cfaf48d064 | 186 | |
Anaesthetix | 0:a8cfaf48d064 | 187 | _lcd_cs->write(1); // Disable SPI |
Anaesthetix | 0:a8cfaf48d064 | 188 | |
Anaesthetix | 0:a8cfaf48d064 | 189 | } |
Anaesthetix | 0:a8cfaf48d064 | 190 | |
Anaesthetix | 0:a8cfaf48d064 | 191 | void UC1701::drawBitmap(const char *data) |
Anaesthetix | 0:a8cfaf48d064 | 192 | { |
Anaesthetix | 0:a8cfaf48d064 | 193 | int cnt = 0; |
Anaesthetix | 0:a8cfaf48d064 | 194 | _lcd_cs->write(0); |
Anaesthetix | 0:a8cfaf48d064 | 195 | _lcd_cd->write(1); |
Anaesthetix | 0:a8cfaf48d064 | 196 | UC1701::setCursor(0,0); |
Anaesthetix | 0:a8cfaf48d064 | 197 | for(int row=0; row<8; row++) { |
Anaesthetix | 0:a8cfaf48d064 | 198 | UC1701::setCursor(0, row); |
Anaesthetix | 0:a8cfaf48d064 | 199 | for(int column=0; column<128; column++) { |
Anaesthetix | 0:a8cfaf48d064 | 200 | _lcd->write(data[cnt]); |
Anaesthetix | 0:a8cfaf48d064 | 201 | cnt++; |
Anaesthetix | 0:a8cfaf48d064 | 202 | } |
Anaesthetix | 0:a8cfaf48d064 | 203 | } |
Anaesthetix | 0:a8cfaf48d064 | 204 | } |