DCF77 Atomic clock using Nokia 6610 colour LCD display. This will continue to run with no signal and shows a graphic bit map display demonstrating the time build. Does not use the Mbed RTC so will run on the LPC11U24. The main signal timing is achieved by using a Ticker ISR that looks at the DCF signal input every 50mS this also produces the seconds on the local clock incase of signal errors or no signal. Many thanks to Lynton Towler for the idea of this part of the code and Wim who helped me convert it from an Arduino program. The Parity code was fromHans program that works.
MobileLCD.cpp
00001 /* mbed Library - Nokia LCD Labelled "X3" 00002 * This is using the Philips PCF8833 controller 00003 * Copyright (c) 2009 P.R.Green 00004 */ 00005 00006 #include "MobileLCD.h" 00007 00008 #include "mbed.h" 00009 00010 using namespace mbed; 00011 00012 MobileLCD::MobileLCD(PinName mosi, PinName miso, PinName clk, PinName cs, PinName rst) 00013 : _spi(mosi, miso, clk) 00014 , _rst(rst) 00015 , _cs(cs) { 00016 _row = 0; 00017 _column = 0; 00018 _rows = 16; 00019 _columns = 16; 00020 _width = 130; 00021 _height = 130; 00022 foreground(0xFFFF); 00023 background(0x0000); 00024 reset(); 00025 } 00026 00027 void MobileLCD::reset() { 00028 long i; 00029 _cs = 1; 00030 _rst = 0; 00031 _spi.format(9); 00032 _spi.frequency(5000000); 00033 wait(0.020); 00034 _rst = 1; 00035 wait(0.020); 00036 _select(); 00037 command(0x11);//SLEEPOUT 00038 command(0x3A);//COLMOD 00039 data(0x05);//0x03 = 16bits-per-pixel 5:6:5 mode 00040 command(0x36);//MADCTL 00041 data(0x60);// 0x60 = mirror x, vertical RAM write 00042 command(0x25);//SETCON 00043 data(0x42);// contrast 0x30 00044 wait(0.002); 00045 command(0x29);//DISPON 00046 command(0x03);//BSTRON 00047 00048 command(0x2B);//Row Address Set 00049 data(0); 00050 data(131); 00051 00052 command(0x2A);//Column Address Set 00053 data(0); 00054 data(131); 00055 00056 command(0x2C);//RAMWR 00057 //Clear RAM to black 00058 for (i=0; i < (132 * 132); i++) { 00059 data(0); 00060 data(0); 00061 } 00062 _deselect(); 00063 } 00064 00065 void MobileLCD::command(int value) { 00066 _spi.write(value & 0xFF); 00067 } 00068 00069 void MobileLCD::data(int value) { 00070 _spi.write(value | 0x100); 00071 } 00072 00073 void MobileLCD::_select() { 00074 _spi.format(9); 00075 _spi.frequency(5000000); 00076 _cs = 0; 00077 } 00078 00079 void MobileLCD::_deselect() { 00080 _cs = 1; 00081 } 00082 00083 void MobileLCD::_window(int x, int y, int width, int height) { 00084 int x1, x2, y1, y2; 00085 switch (0) { //_rotation) { 00086 default: 00087 case 0: 00088 x1 = x + 1; 00089 y1 = y + 1; 00090 x2 = x1 + width - 1; 00091 y2 = y1 + height -1 ; 00092 break; 00093 case 1: 00094 x1 = y + 1; 00095 y1 = x + 1; 00096 x2 = x1 + height - 1; 00097 y2 = y1 + width - 1; 00098 break; 00099 case 2: 00100 x1 = x + 1; 00101 y1 = y + 3; 00102 x2 = x1 + width - 1; 00103 y2 = y1 + height - 1; 00104 break; 00105 case 3: 00106 x1 = y + 3; 00107 y1 = x + 3; 00108 x2 = x1 + height - 1; 00109 y2 = y1 + width - 1; 00110 break; 00111 } 00112 command(0x2A); //CASET column 00113 data(x1); 00114 data(x2); 00115 command(0x2B); //PASET page 00116 data(y1); 00117 data(y2); 00118 command(0x2C); //RAMWR start write to ram 00119 } 00120 00121 void MobileLCD::_putp(int colour) { 00122 00123 data((colour >> 8) & 0xFF); 00124 data(colour & 0xFF); 00125 00126 } 00127 /* 00128 void MobileLCD::orientation() { 00129 int m; 00130 switch (0) { //_rotation) { 00131 case 0: 00132 default: 00133 m = 3; 00134 break; 00135 case 2: 00136 m = 0; 00137 break; 00138 case 1: 00139 m = 5; 00140 break; 00141 case 3: 00142 m = 6; 00143 break; 00144 } 00145 00146 command(0xBC); // data control 00147 data(m); // scan dirs 00148 data(1); // RGB 00149 data(4); // grayscale 00150 } 00151 */ 00152 00153 const unsigned char FONT8x8[97][8] = { 00154 0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, // columns, rows, num_bytes_per_char 00155 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space 0x20 00156 0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00, // ! 00157 0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00, // " 00158 0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00, // # 00159 0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00, // $ 00160 0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00, // % 00161 0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00, // & 00162 0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00, // ' 00163 0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00, // ( 00164 0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00, // ) 00165 0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00, // * 00166 0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00, // + 00167 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, // , 00168 0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // - 00169 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, // . 00170 0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, // / (forward slash) 00171 0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00, // 0 0x30 00172 0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00, // 1 00173 0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00, // 2 00174 0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00, // 3 00175 0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00, // 4 00176 0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00, // 5 00177 0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00, // 6 00178 0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00, // 7 00179 0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00, // 8 00180 0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00, // 9 00181 0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00, // : 00182 0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30, // ; 00183 0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00, // < 00184 0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, // = 00185 0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00, // > 00186 0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00, // ? 00187 0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00, // @ 0x40 00188 0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00, // A 00189 0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00, // B 00190 0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00, // C 00191 0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00, // D 00192 0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00, // E 00193 0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00, // F 00194 0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00, // G 00195 0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00, // H 00196 0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // I 00197 0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, // J 00198 0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00, // K 00199 0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00, // L 00200 0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00, // M 00201 0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00, // N 00202 0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00, // O 00203 0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00, // P 0x50 00204 0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00, // Q 00205 0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00, // R 00206 0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00, // S 00207 0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00, // T 00208 0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, // U 00209 0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00, // V 00210 0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, // W 00211 0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00, // X 00212 0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00, // Y 00213 0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00, // Z 00214 0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, // [ 00215 0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00, // \ (back slash) 00216 0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, // ] 00217 0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00, // ^ 00218 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, // _ 00219 0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00, // ` 0x60 00220 0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00, // a 00221 0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00, // b 00222 0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00, // c 00223 0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00, // d 00224 0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, // e 00225 0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00, // f 00226 0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C, // g 00227 0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00, // h 00228 0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00, // i 00229 0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C, // j 00230 0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00, // k 00231 0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // l 00232 0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, // m 00233 0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00, // n 00234 0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, // o 00235 0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78, // p 00236 0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F, // q 00237 0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00, // r 00238 0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, // s 00239 0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00, // t 00240 0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00, // u 00241 0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00, // v 00242 0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00, // w 00243 0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00, // x 00244 0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C, // y 00245 0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00, // z 00246 0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00, // { 00247 0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00, // | 00248 0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // } 00249 0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00, // ~ 00250 0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00 00251 }; // DEL 00252 00253 void MobileLCD::locate(int column, int row) { 00254 _row = row; 00255 _column = column; 00256 } 00257 00258 void MobileLCD::newline() { 00259 _column = 0; 00260 _row++; 00261 if (_row >= _rows) { 00262 _row = 0; 00263 } 00264 } 00265 00266 int MobileLCD::_putc(int value) { 00267 int x = _column * 8; // FIXME: Char sizes 00268 int y = _row * 8; 00269 bitblit(x , y , 8, 8, (char*)&(FONT8x8[value - 0x1F][0])); 00270 00271 _column++; 00272 00273 if (_column >= _columns) { 00274 _row++; 00275 _column = 0; 00276 } 00277 00278 if (_row >= _rows) { 00279 _row = 0; 00280 } 00281 00282 return value; 00283 } 00284 00285 void MobileLCD::cls() { 00286 fill(0, 0, _width, _height, _background); 00287 _row = 0; 00288 _column = 0; 00289 } 00290 00291 int MobileLCD::width() { 00292 return _width; 00293 } 00294 00295 int MobileLCD::height() { 00296 return _height; 00297 } 00298 00299 int MobileLCD::columns() { 00300 return _columns; 00301 } 00302 00303 int MobileLCD::rows() { 00304 return _rows; 00305 } 00306 00307 void MobileLCD::window(int x, int y, int width, int height) { 00308 _select(); 00309 _window(x, y, width, height); 00310 _deselect(); 00311 } 00312 00313 void MobileLCD::putp(int colour) { 00314 _select(); 00315 _putp(colour); 00316 _deselect(); 00317 } 00318 00319 void MobileLCD::pixel(int x, int y, int colour) { 00320 _select(); 00321 _window(x, y, 1, 1); 00322 _putp(colour); 00323 _deselect(); 00324 } 00325 00326 void MobileLCD::fill(int x, int y, int width, int height, int colour) { 00327 _select(); 00328 _window(x, y, width, height); 00329 for (int i=0; i<width*height; i++) { 00330 _putp(colour); 00331 } 00332 _window(0, 0, _width, _height); 00333 _deselect(); 00334 } 00335 00336 00337 void MobileLCD::blit(int x, int y, int width, int height, const int* colour) { 00338 _select(); 00339 _window(x, y, width, height); 00340 for (int i=0; i<width*height; i++) { 00341 _putp(colour[i]); 00342 } 00343 _window(0, 0, _width, _height); 00344 _deselect(); 00345 } 00346 00347 void MobileLCD::foreground(int v) { 00348 _foreground = v; 00349 } 00350 00351 void MobileLCD::background(int v) { 00352 _background = v; 00353 } 00354 00355 void MobileLCD::bitblit(int x, int y, int width, int height, const char* bitstream) { 00356 _select(); 00357 _window(x, y, width, height); 00358 00359 for (int i=0; i<height*width; i++) { 00360 unsigned char byte = i / 8; 00361 unsigned char bit = i % 8; 00362 int colour = (((bitstream[byte] << bit) & 0x80) ? _foreground : _background); 00363 _putp(colour); 00364 } 00365 _window(0, 0, _width, _height); 00366 _deselect(); 00367 } 00368 00369
Generated on Thu Jul 28 2022 11:07:56 by 1.7.2