Ralf Neerfeld / Mbed 2 deprecated ht1632_matrix

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "ht1632.h"
00003 #include "font3.h"  
00004 
00005 #define HIGH 1
00006 #define LOW 0
00007 
00008 DigitalOut ht1632_wrclk(p23); // For Test : Led1 is Clock
00009 DigitalOut ht1632_data(p22); //            Led2 is Data ....
00010 DigitalOut ht1632_cs(p21); //            Led3 is CS
00011 
00012 typedef unsigned char byte;
00013 
00014 void byteOut(byte c);
00015 void ht1632_chipselect(byte chipno);
00016 static void ht1632_sendcmd (byte command);
00017 static void ht1632_senddata (byte address, byte data);
00018 void ht1632_chipfree(byte chipno);
00019 void ht1632_writebits (byte bits, byte firstbit);
00020 void ht1632_plot (int x, int y, char val);
00021 void setup();
00022 void loop();
00023 
00024 int main() {
00025     setup();
00026     while(1) {
00027         loop();
00028     }
00029 }
00030 
00031 /*********************************************************************** 
00032  * HT1624.pde - Arduino demo program for Holtek HT1632 LED driver chip, 
00033  *            As implemented on the Sure Electronics DE-DP016 display board 
00034  *            (16*24 dot matrix LED module.) 
00035  * Nov, 2008 by Bill Westfield ("WestfW") 
00036  *   Copyrighted and distributed under the terms of the Berkely license 
00037  *   (copy freely, but include this notice of original author.) 
00038  * 
00039  * Adapted for 8x32 display by FlorinC. 
00040  ***********************************************************************/  
00041   
00042 // comment out this line for the 8x32 display;  
00043 //#define _16x24_  
00044   
00045   
00046 #ifdef _16x24_  
00047   #define X_MAX 23  
00048   #define Y_MAX 15  
00049 #else  
00050   #define X_MAX 31  
00051   #define Y_MAX 7  
00052 #endif  
00053   
00054 #define plot(x,y,v)  ht1632_plot(x,y,v)  
00055 #define cls          ht1632_clear  
00056   
00057 #define DISPDELAY 0  
00058   
00059 char* msg = "   Guten Morgen liebe Kollegen ! - Alles im Lack ?  Noch 20 Tage bis Entwicklungsschluss .......  ";  
00060 int crtPos = 0;  
00061   
00062 /*********************************************************************** 
00063  * ht1632_chipselect / ht1632_chipfree 
00064  * Select or de-select a particular ht1632 chip. 
00065  * De-selecting a chip ends the commands being sent to a chip. 
00066  * CD pins are active-low; writing 0 to the pin selects the chip. 
00067  ***********************************************************************/  
00068   
00069 void ht1632_chipselect(byte chipno)
00070 {
00071   ht1632_cs = 0;
00072 }
00073 
00074 void ht1632_chipfree(byte chipno)
00075 {
00076   ht1632_cs = 1;
00077 }
00078   
00079 /* 
00080  * we keep a copy of the display controller contents so that we can 
00081  * know which bits are on without having to (slowly) read the device. 
00082  * Note that we only use the low four bits of the shadow ram, since 
00083  * we're shadowing 4-bit memory.  This makes things faster, and we 
00084  * use the other half for a "snapshot" when we want to plot new data 
00085  * based on older data... 
00086  */  
00087 // (fc) covers the case for 32x8 as well (64 bytes, 4 bits)  
00088 byte ht1632_shadowram[96];  // our copy of the display's RAM  
00089   
00090 /* 
00091  * ht1632_writebits 
00092  * Write bits (up to <img src="http://timewitharduino.com/wp-includes/images/smilies/icon_cool.gif" alt="8)" class="wp-smiley"> to h1632 on pins HT1632_DATA, HT1632_WRCLK 
00093  * Chip is assumed to already be chip-selected 
00094  * Bits are shifted out from MSB to LSB, with the first bit sent 
00095  * being (bits & firstbit), shifted till firsbit is zero. 
00096  */  
00097 void ht1632_writebits (byte bits, byte firstbit)
00098 {
00099   while (firstbit) {
00100     ht1632_wrclk = 0;
00101     if (bits & firstbit) {
00102       ht1632_data = 1;
00103     }
00104     else {
00105       ht1632_data = 0;
00106     }
00107     ht1632_wrclk = 1;
00108     firstbit >>= 1;
00109   }
00110 }
00111   
00112 /* 
00113  * ht1632_sendcmd 
00114  * Send a command to the ht1632 chip. 
00115  * A command consists of a 3-bit "CMD" ID, an 8bit command, and 
00116  * one "don't care bit". 
00117  *   Select 1 0 0 c7 c6 c5 c4 c3 c2 c1 c0 xx Free 
00118  */  
00119 static void ht1632_sendcmd (byte command)
00120 {
00121   ht1632_chipselect(ht1632_cs);  // Select chip
00122   ht1632_writebits(ID_CMD, 1<<2);  // send 3 bits of id: COMMMAND
00123   ht1632_writebits(command, 1<<7);  // send the actual command
00124   ht1632_writebits(0, 1);     /* one extra dont-care bit in commands. */
00125   ht1632_chipfree(ht1632_cs); //done
00126 }
00127  
00128   
00129 /* 
00130  * ht1632_clear 
00131  * clear the display, and the shadow memory, and the snapshot 
00132  * memory.  This uses the "write multiple words" capability of 
00133  * the chipset by writing all 96 words of memory without raising 
00134  * the chipselect signal. 
00135  */  
00136 void ht1632_clear()  
00137 {  
00138   char i;  
00139   
00140   ht1632_chipselect(HT1632_CS);  // Select chip  
00141   ht1632_writebits(ID_WR, 1<<2);  // send ID: WRITE to RAM  
00142   ht1632_writebits(0, 1<<6); // Send address  
00143   for (i = 0; i < 96/2; i++) // Clear entire display  
00144     ht1632_writebits(0, 1<<7); // send 8 bits of data  
00145   ht1632_chipfree(HT1632_CS); // done  
00146   for (i=0; i < 96; i++)  
00147     ht1632_shadowram[i] = 0;  
00148 }  
00149   
00150 /* 
00151  * ht1632_senddata 
00152  * send a nibble (4 bits) of data to a particular memory location of the 
00153  * ht1632.  The command has 3 bit ID, 7 bits of address, and 4 bits of data. 
00154  *    Select 1 0 1 A6 A5 A4 A3 A2 A1 A0 D0 D1 D2 D3 Free 
00155  * Note that the address is sent MSB first, while the data is sent LSB first! 
00156  * This means that somewhere a bit reversal will have to be done to get 
00157  * zero-based addressing of words and dots within words. 
00158  */  
00159 static void ht1632_senddata (byte address, byte data)  
00160 {  
00161   ht1632_chipselect(HT1632_CS);  // Select chip  
00162   ht1632_writebits(ID_WR, 1<<2);  // send ID: WRITE to RAM  
00163   ht1632_writebits(address, 1<<6); // Send address  
00164   ht1632_writebits(data, 1<<3); // send 4 bits of data  
00165   ht1632_chipfree(HT1632_CS); // done  
00166 }  
00167   
00168 void ht1632_setup()  
00169 {  
00170   ht1632_cs = HIGH;    // unselect (active low)  
00171   ht1632_sendcmd(CMD_SYSDIS);  // Disable system  
00172   
00173 #ifdef _16x24_  
00174   ht1632_sendcmd(CMD_COMS11);  // 16*32, PMOS drivers  
00175 #else  
00176 // (fc)  
00177   ht1632_sendcmd(CMD_COMS10);  // 32x8, PMOS drivers  
00178 #endif  
00179   
00180   ht1632_sendcmd(CMD_MSTMD);     // Master Mode  
00181   ht1632_sendcmd(CMD_SYSON);     // System on  
00182   ht1632_sendcmd(CMD_LEDON);     // LEDs on  
00183   
00184   for (byte i=0; i<64; i++)  
00185     ht1632_senddata(i, 0);  // clear the display!  
00186   
00187   wait(0.1);  // ?  
00188 }  
00189   
00190 /* 
00191  * Copy a character glyph from the myfont data structure to 
00192  * display memory, with its upper left at the given coordinate 
00193  * This is unoptimized and simply uses plot() to draw each dot. 
00194  */  
00195 void ht1632_putchar(int x, int y, char c)  
00196 {  
00197   // fonts defined for ascii 32 and beyond (index 0 in font array is ascii 32);  
00198   byte charIndex;  
00199   
00200   // replace undisplayable characters with blank;  
00201   if (c < 32 || c > 126)  
00202   {  
00203     charIndex = 0;  
00204   }  
00205   else  
00206   {  
00207     charIndex = c - 32;  
00208   }  
00209   
00210   // move character definition, pixel by pixel, onto the display;  
00211   // fonts are defined as one byte per row;  
00212   for (byte row=0; row<8; row++)  
00213   {  
00214     byte rowDots = myfont[charIndex][row];  
00215     for (byte col=0; col<6; col++)  
00216     {  
00217       if (rowDots & (1<<(5-col)))  
00218         plot(x+col, y+row, 1);  
00219       else  
00220         plot(x+col, y+row, 0);  
00221     }  
00222   }  
00223 }  
00224   
00225 /* 
00226  * plot a point on the display, with the upper left hand corner 
00227  * being (0,0), and the lower right hand corner being (23, 15). 
00228  * Note that Y increases going "downward" in contrast with most 
00229  * mathematical coordiate systems, but in common with many displays 
00230  * No error checking; bad things may happen if arguments are out of 
00231  * bounds!  (The ASSERTS compile to nothing by default 
00232  */  
00233 void ht1632_plot (int x, int y, char val)  
00234 {  
00235   if (x<0 || x>X_MAX || y<0 || y>Y_MAX)  
00236      return;  
00237   
00238   char addr, bitval;  
00239   
00240   /* 
00241    * The 4 bits in a single memory word go DOWN, with the LSB 
00242    * (first transmitted) bit being on top.  However, writebits() 
00243    * sends the MSB first, so we have to do a sort of bit-reversal 
00244    * somewhere.  Here, this is done by shifting the single bit in 
00245    * the opposite direction from what you might expect. 
00246    */  
00247   bitval = 8>>(y&3);  // compute which bit will need set  
00248   
00249 #ifdef _16x24_  
00250   addr = (x<<2) + (y>>2);  // compute which memory word this is in  
00251 #else  
00252 // (fc)  
00253   addr = (x<<1) + (y>>2);  // compute which memory word this is in  
00254 #endif  
00255   
00256   if (val) {  // Modify the shadow memory  
00257     ht1632_shadowram[addr] |= bitval;  
00258   }  
00259   else {  
00260     ht1632_shadowram[addr] &= ~bitval;  
00261   }  
00262   // Now copy the new memory value to the display  
00263   ht1632_senddata(addr, ht1632_shadowram[addr]);  
00264 }  
00265   
00266 /* 
00267  * get_shadowram 
00268  * return the value of a pixel from the shadow ram. 
00269  */  
00270 byte get_shadowram(byte x, byte y)  
00271 {  
00272   byte addr, bitval;  
00273   
00274   bitval = 8>>(y&3);  // compute which bit will need set  
00275   addr = (x<<2) + (y>>2);  // compute which memory word this is in  
00276   return (0 != (ht1632_shadowram[addr] & bitval));  
00277 }  
00278   
00279 /* 
00280  * snapshot_shadowram 
00281  * Copy the shadow ram into the snapshot ram (the upper bits) 
00282  * This gives us a separate copy so we can plot new data while 
00283  * still having a copy of the old data.  snapshotram is NOT 
00284  * updated by the plot functions (except "clear") 
00285  */  
00286 void snapshot_shadowram()  
00287 {  
00288   for (char i=0; i< sizeof ht1632_shadowram; i++) {  
00289     ht1632_shadowram[i] = (ht1632_shadowram[i] & 0x0F) | ht1632_shadowram[i] << 4;  // Use the upper bits  
00290   }  
00291 }  
00292   
00293 /* 
00294  * get_snapshotram 
00295  * get a pixel value from the snapshot ram (instead of 
00296  * the actual displayed (shadow) memory 
00297  */  
00298 byte get_snapshotram(byte x, byte y)  
00299 {  
00300   byte addr, bitval;  
00301   
00302   bitval = 128>>(y&3);  // user upper bits!  
00303   
00304 #ifdef _16x24_  
00305   addr = (x<<2) + (y>>2);  // compute which memory word this is in  
00306 #else  
00307 // (fc)  
00308   addr = (x<<1) + (y>>2);  // compute which memory word this is in  
00309 #endif  
00310   
00311   if (ht1632_shadowram[addr] & bitval)  
00312     return 1;  
00313   return 0;  
00314 }  
00315   
00316 /* 
00317 * This works equally well for both 16x24 and 8x32 matrices. 
00318 */  
00319 void displayScrollingLine()  
00320 {  
00321   // shift the whole screen 6 times, one column at a time;  
00322   for (int x=0; x < 6; x++)  
00323   {  
00324     ht1632_putchar(-x, 0, msg[crtPos]);  
00325     ht1632_putchar(-x+6,  0, ((crtPos+1 < strlen(msg)) ? msg[crtPos+1] : ' ')); 
00326     ht1632_putchar(-x+12, 0, ((crtPos+2 < strlen(msg)) ? msg[crtPos+2] : ' '));  
00327     ht1632_putchar(-x+18, 0, ((crtPos+3 < strlen(msg)) ? msg[crtPos+3] : ' ')); 
00328     ht1632_putchar(-x+24, 0, ((crtPos+4 < strlen(msg)) ? msg[crtPos+4] : ' '));  
00329     ht1632_putchar(-x+30, 0, ((crtPos+5 < strlen(msg)) ? msg[crtPos+5] : ' ')); 
00330     ht1632_putchar(-x+36, 0, ((crtPos+6 < strlen(msg)) ? msg[crtPos+6] : ' '));  
00331     wait(0.05);  
00332   }  
00333   
00334   crtPos++;  
00335   if (crtPos >= strlen(msg))  
00336   {  
00337     crtPos = 0;  
00338   }  
00339 }  
00340   
00341 /*********************************************************************** 
00342  * traditional Arduino sketch functions: setup and loop. 
00343  ***********************************************************************/  
00344   
00345 void setup ()  
00346 {  
00347   ht1632_setup();  
00348   cls();  
00349 }  
00350   
00351 void loop ()  
00352 {  
00353   // display line;  
00354   displayScrollingLine();  
00355 }