Library for Sure Electronics HT1632 based LED matrix displays. Supports multiple displays connected together.
Dependents: HT1632MsgScroller SMS_LEDMatrixPrinter
Diff: HT1632_LedMatrix.cpp
- Revision:
- 3:48f430fe186e
- Parent:
- 2:3e477c909f7a
- Child:
- 4:7513dd37efed
--- a/HT1632_LedMatrix.cpp Fri Nov 09 08:54:37 2012 +0000 +++ b/HT1632_LedMatrix.cpp Fri Nov 09 16:33:53 2012 +0000 @@ -44,7 +44,7 @@ // helper macros #define chip_number(x,y) (x >> 5) + (y >> 3)*numYDevices -#define chip_nibble_address(x,y) ((x%32)<<1) + ((y%8)>>2); +#define chip_nibble_address(x,y) ((x%32)<<1) + ((y%8)>>2); #define chip_byte_address(x,y) ((x%32)<<1); #define max(a, b) (((a) > (b)) ? (a) : (b)) @@ -70,7 +70,7 @@ // Custom character buffers - 8 characters available // 6 cols * 8 rows - first byte of each char is the number of columns used // Bits are aranged in columns with LSB at top -uint8_t cgram [8][7] = { +uint8_t cgram [8][7] = { { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -78,42 +78,45 @@ { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; + { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; // Default constructor -HT1632_LedMatrix::HT1632_LedMatrix( void ) { +HT1632_LedMatrix::HT1632_LedMatrix( void ) +{ } -void HT1632_LedMatrix::init( uint8_t xDevices, uint8_t yDevices ) { - // Set up the display size based on number of devices both horizontal and vertical - numXDevices = xDevices; - xMax = 32 * numXDevices-1; - numYDevices = yDevices; - yMax = 8 * numYDevices-1; - numDevices = numXDevices * numYDevices; +void HT1632_LedMatrix::init( uint8_t xDevices, uint8_t yDevices ) +{ + // Set up the display size based on number of devices both horizontal and vertical + numXDevices = xDevices; + xMax = 32 * numXDevices-1; + numYDevices = yDevices; + yMax = 8 * numYDevices-1; + numDevices = numXDevices * numYDevices; - // Disable all display CS lines by taking high - for( uint8_t i = 0; i < 4; i++ ) - ht1632_cs[i] = HIGH; + // Disable all display CS lines by taking high + for( uint8_t i = 0; i < 4; i++ ) + ht1632_cs[i] = HIGH; - for (uint8_t chipno=0; chipno<numDevices; chipno++){ - chipfree(chipno); // unselect it - sendcmd(chipno, HT1632_CMD_SYSDIS); // Disable system - sendcmd(chipno, HT1632_CMD_COMS10); // 08*32, PMOS drivers - sendcmd(chipno, HT1632_CMD_MSTMD); // Master Mode - sendcmd(chipno, HT1632_CMD_SYSON); // System on - sendcmd(chipno, HT1632_CMD_LEDON); // LEDs on - sendcmd(chipno, HT1632_CMD_PWM | 0x0c); // PWM Duty - for (uint8_t i=0; i<96; i++) - senddata(chipno, i, 0); // clear the display - wait(0.1); - } - cursorX = 0; - cursorY = 0; + for (uint8_t chipno=0; chipno<numDevices; chipno++) { + chipfree(chipno); // unselect it + sendcmd(chipno, HT1632_CMD_SYSDIS); // Disable system + sendcmd(chipno, HT1632_CMD_COMS10); // 08*32, PMOS drivers + sendcmd(chipno, HT1632_CMD_MSTMD); // Master Mode + sendcmd(chipno, HT1632_CMD_SYSON); // System on + sendcmd(chipno, HT1632_CMD_LEDON); // LEDs on + sendcmd(chipno, HT1632_CMD_PWM | 0x0c); // PWM Duty + for (uint8_t i=0; i<96; i++) + senddata(chipno, i, 0); // clear the display + wait(0.1); + } + cursorX = 0; + cursorY = 0; } - + /*********************************************************************** * chipselect / chipfree * Select or de-select a particular ht1632 chip. @@ -139,16 +142,16 @@ */ void HT1632_LedMatrix::writebits (uint8_t bits, uint8_t firstbit) { - while (firstbit) { - ht1632_wrclk = LOW; - if (bits & firstbit) { - ht1632_data = HIGH; - } else { - ht1632_data = LOW; + while (firstbit) { + ht1632_wrclk = LOW; + if (bits & firstbit) { + ht1632_data = HIGH; + } else { + ht1632_data = LOW; + } + ht1632_wrclk = HIGH; + firstbit >>= 1; } - ht1632_wrclk = HIGH; - firstbit >>= 1; - } } /* @@ -159,17 +162,18 @@ */ void HT1632_LedMatrix::writedatabits (uint8_t bits, uint8_t count) { - while (count) { - ht1632_wrclk = LOW; - if (bits & 1) { - ht1632_data = HIGH; - } else { - ht1632_data = LOW; + while (count) { + ht1632_wrclk = LOW; + ht1632_data = bits & 1; +// if (bits & 1) { +// ht1632_data = HIGH; +// } else { +// ht1632_data = LOW; +// } + ht1632_wrclk = HIGH; + count--; + bits >>= 1; } - ht1632_wrclk = HIGH; - count--; - bits >>= 1; - } } /* @@ -181,11 +185,11 @@ */ void HT1632_LedMatrix::sendcmd (uint8_t chipno, uint8_t command) { - chipselect(chipno); // Select chip - writebits(HT1632_ID_CMD, 0x04); //1<<2); // send 3 bits of id: COMMMAND - writebits(command, 0x80); //1<<7); // send the actual command - writebits(0, 1); /* one extra dont-care bit in commands. */ - chipfree(chipno); //done + chipselect(chipno); // Select chip + writebits(HT1632_ID_CMD, 0x04); // send 3 bits of id: COMMMAND + writebits(command, 0x80); // send the actual command + writebits(0, 1); // one extra dont-care bit in commands. + chipfree(chipno); //done } /* @@ -197,28 +201,29 @@ */ void HT1632_LedMatrix::clear() { - char i; + char i; - for (uint8_t chipno=0; chipno<numDevices; chipno++){ - chipselect(chipno); // Select chip - writebits(HT1632_ID_WR, 0x04); //1<<2); // send ID: WRITE to RAM - writebits(0, 0x40); //1<<6); // Send address - for (i = 0; i < 32; i++) // Clear entire display - writedatabits(0, 8); //1<<7); // send 8 bits of data - chipfree(chipno); // done - for (i=0; i < 64; i++) - shadowram[i+64*chipno] = 0; - } - cursorX = 0; - cursorY = 0; + for (uint8_t chipno=0; chipno<numDevices; chipno++) { + chipselect(chipno); // Select chip + writebits(HT1632_ID_WR, 0x04); // send ID: WRITE to RAM + writebits(0, 0x40); // Send address + for (i = 0; i < 32; i++) // Clear entire display + writedatabits(0, 8); // send 8 bits of data + chipfree(chipno); // done + for (i=0; i < 64; i++) + shadowram[i+64*chipno] = 0; + } + cursorX = 0; + cursorY = 0; } // Brighness is from 0 to 15 -void HT1632_LedMatrix::setBrightness( unsigned char brightness ) { - for (uint8_t chipno=0; chipno<numDevices; chipno++) { - sendcmd(chipno, HT1632_CMD_PWM | (brightness & 0x0F )); - } +void HT1632_LedMatrix::setBrightness( unsigned char brightness ) +{ + for (uint8_t chipno=0; chipno<numDevices; chipno++) { + sendcmd(chipno, HT1632_CMD_PWM | (brightness & 0x0F )); + } } @@ -233,11 +238,11 @@ */ void HT1632_LedMatrix::senddata (uint8_t chipno, uint8_t address, uint8_t data) { - chipselect(chipno); // Select chip - writebits(HT1632_ID_WR, 0x04); //1<<2); // send ID: WRITE to RAM - writebits(address, 0x40); //1<<6); // Send address - writedatabits(data, 4); //1<<3); // send 4 bits of data - chipfree(chipno); // done + chipselect(chipno); // Select chip + writebits(HT1632_ID_WR, 0x04); // send ID: WRITE to RAM + writebits(address, 0x40); // Send address + writedatabits(data, 4); // send 4 bits of data + chipfree(chipno); // done } /* @@ -251,15 +256,16 @@ */ void HT1632_LedMatrix::sendcol (uint8_t chipno, uint8_t address, uint8_t data) { - chipselect(chipno); // Select chip - writebits(HT1632_ID_WR, 0x04); //1<<2); // send ID: WRITE to RAM - writebits(address, 0x40); //1<<6); // Send address - writedatabits(data, 8); // send 8 bits of data - chipfree(chipno); // done + chipselect(chipno); // Select chip + writebits(HT1632_ID_WR, 0x04); // send ID: WRITE to RAM + writebits(address, 0x40); // Send address + writedatabits(data, 8); // send 8 bits of data + chipfree(chipno); // done } // Write a string at the position specified -void HT1632_LedMatrix::putString(int x, int y, char *str) { +void HT1632_LedMatrix::putString(int x, int y, char *str) +{ cursorX = x; cursorY = y; while( *str ) { @@ -273,8 +279,9 @@ * display memory, with its upper left at the given coordinate * This is unoptimized and simply uses plot() to draw each dot. */ -void HT1632_LedMatrix::write( uint8_t c) { - putChar( cursorX, cursorY, (char)c ); +void HT1632_LedMatrix::write( uint8_t c) +{ + putChar( cursorX, cursorY, (char)c ); } /* @@ -283,69 +290,71 @@ * This is unoptimized and simply uses plot() to draw each dot. * returns number of columns that didn't fit */ -uint8_t HT1632_LedMatrix::putChar(int x, int y, char c) { - // fonts defined for ascii 32 and beyond (index 0 in font array is ascii 32); - // CGRAM characters are in range 0 to 15 with 8-15 being repeat of 0-7 - // note we force y to be modulo 8 - we do not support writing character to partial y values. +uint8_t HT1632_LedMatrix::putChar(int x, int y, char c) +{ + // fonts defined for ascii 32 and beyond (index 0 in font array is ascii 32); + // CGRAM characters are in range 0 to 15 with 8-15 being repeat of 0-7 + // note we force y to be modulo 8 - we do not support writing character to partial y values. + + uint8_t charIndex; + uint8_t colData; + uint8_t numCols; + uint8_t chipno; + uint8_t addr; + uint8_t colsLeft = 0; // cols that didn't fit + + if( c > 15 ) { + // Regular characters + // replace undisplayable characters with blank; + if (c < 32 || c > 126) { + charIndex = 0; + } else { + charIndex = c - 32; + } - uint8_t charIndex; - uint8_t colData; - uint8_t numCols; - uint8_t chipno; - uint8_t addr; - uint8_t colsLeft = 0; // cols that didn't fit - - if( c > 15 ) { - // Regular characters - // replace undisplayable characters with blank; - if (c < 32 || c > 126) { - charIndex = 0; + // move character definition, pixel by pixel, onto the display; + // fonts are defined as one byte per col; + numCols=smallFont[charIndex][6]; // get the number of columns this character uses + for (uint8_t col=0; col<numCols; col++) { + colData = smallFont[charIndex][col]; + chipno = chip_number(x,y); + addr = chip_byte_address(x,y); // compute which memory byte this is in + if (x <= xMax && y <= yMax) { + shadowram[(addr>>1)+32*chipno] = colData; + sendcol(chipno,addr,colData); + x++; + } else { + colsLeft++; + } + } } else { - charIndex = c - 32; + // CGRAM Characters + charIndex = c & 0x07; // Only low 3 bits count + numCols=cgram[charIndex][0]; // get the number of columns this character uses + // fonts are defined as one byte per col; + for (uint8_t col=1; col<=numCols; col++) { + colData = cgram[charIndex][col]; + chipno = chip_number(x,y); + addr = chip_byte_address(x,y); // compute which memory byte this is in + if (x <= xMax && y <= yMax) { + shadowram[(addr>>1)+32*chipno] = colData; + sendcol(chipno,addr,colData); + x++; + } else { + colsLeft++; + } + } } - // move character definition, pixel by pixel, onto the display; - // fonts are defined as one byte per col; - numCols=smallFont[charIndex][6]; // get the number of columns this character uses - for (uint8_t col=0; col<numCols; col++) { - colData = smallFont[charIndex][col]; - chipno = chip_number(x,y); - addr = chip_byte_address(x,y); // compute which memory byte this is in - if (x <= xMax && y <= yMax) { - shadowram[(addr>>1)+32*chipno] = colData; - sendcol(chipno,addr,colData); - x++; - } else { - colsLeft++; - } - } - } else { - // CGRAM Characters - charIndex = c & 0x07; // Only low 3 bits count - numCols=cgram[charIndex][0]; // get the number of columns this character uses - // fonts are defined as one byte per col; - for (uint8_t col=1; col<=numCols; col++) { - colData = cgram[charIndex][col]; - chipno = chip_number(x,y); - addr = chip_byte_address(x,y); // compute which memory byte this is in - if (x <= xMax && y <= yMax) { - shadowram[(addr>>1)+32*chipno] = colData; - sendcol(chipno,addr,colData); - x++; - } else { - colsLeft++; - } - } - } + cursorX = x; + cursorY = y; - cursorX = x; - cursorY = y; - - return colsLeft; + return colsLeft; } // Set position of cursor for writing -void HT1632_LedMatrix::gotoXY(int x, int y) { +void HT1632_LedMatrix::gotoXY(int x, int y) +{ cursorX = x; cursorY = y; } @@ -363,7 +372,8 @@ } // Shift cursor X position a number of positions either left or right. -void HT1632_LedMatrix::shiftCursorX(int xinc) { +void HT1632_LedMatrix::shiftCursorX(int xinc) +{ cursorX += xinc; } @@ -377,28 +387,28 @@ */ void HT1632_LedMatrix::plot (int x, int y, char val) { - if (x<0 || x>xMax || y<0 || y>yMax) - return; + if (x<0 || x>xMax || y<0 || y>yMax) + return; - uint8_t chipno = chip_number(x,y); - char addr = chip_byte_address(x,y); // compute which memory word this is in - char shadowAddress = addr >>1; + uint8_t chipno = chip_number(x,y); + char addr = chip_byte_address(x,y); // compute which memory word this is in + char shadowAddress = addr >>1; - char bitval = 1<<(y&7); // compute which bit will need set + char bitval = 1<<(y&7); // compute which bit will need set - if (val) { // Modify the shadow memory - shadowram[shadowAddress +32*chipno] |= bitval; - } - else { - shadowram[shadowAddress +32*chipno] &= ~bitval; - } - // Now copy the new memory value to the display - sendcol(chipno, addr, shadowram[shadowAddress +32*chipno]); + if (val) { // Modify the shadow memory + shadowram[shadowAddress +32*chipno] |= bitval; + } else { + shadowram[shadowAddress +32*chipno] &= ~bitval; + } + // Now copy the new memory value to the display + sendcol(chipno, addr, shadowram[shadowAddress +32*chipno]); } -void HT1632_LedMatrix::setCustomChar( int charNum, unsigned char cgchar[] ) { +void HT1632_LedMatrix::setCustomChar( int charNum, unsigned char cgchar[] ) +{ for(int i=1; i<7; i++ ) { cgram[charNum][i] = (uint8_t)cgchar[i]; } @@ -406,7 +416,8 @@ cgram[charNum][0] = 6; } -void HT1632_LedMatrix::setCustomChar( int charNum, unsigned char cgchar[], uint8_t numCols ) { +void HT1632_LedMatrix::setCustomChar( int charNum, unsigned char cgchar[], uint8_t numCols ) +{ numCols = max(numCols, 6 ); for(int i=1; i<=numCols; i++ ) { cgram[charNum][i] = (uint8_t)cgchar[i]; @@ -417,12 +428,10 @@ void HT1632_LedMatrix::scrollLeft(uint8_t numberCols) { - for (int i=0; i<128-numberCols-1; i++) - { + for (int i=0; i<128-numberCols-1; i++) { shadowram[i]=shadowram[i+numberCols]; } - for (int i=128-numberCols; i<128; i++) - { + for (int i=128-numberCols; i<128; i++) { shadowram[i]=0; } cursorX -= numberCols; @@ -437,8 +446,7 @@ void HT1632_LedMatrix::putShadowRam(uint8_t chipno) { - for (int i=0; i<64; i+=2) - { + for (int i=0; i<64; i+=2) { sendcol(chipno,i,shadowram[(i>>1)+32*chipno]); } } @@ -453,7 +461,8 @@ * Return value : none */ void HT1632_LedMatrix::drawLine(unsigned char x1, unsigned char y1, - unsigned char x2, unsigned char y2, unsigned char c) { + unsigned char x2, unsigned char y2, unsigned char c) +{ int dx, dy, stepx, stepy, fraction; /* Calculate differential form */ @@ -525,11 +534,12 @@ * Description : Draw a rectangle given to top left and bottom right points * Argument(s) : x1, y1 - Absolute pixel coordinates for top left corner * x2, y2 - Absolute pixel coordinates for bottom right corner - * c - either PIXEL_ON, PIXEL_OFF + * c - either PIXEL_ON, PIXEL_OFF * Return value : none */ void HT1632_LedMatrix::drawRectangle(unsigned char x1, unsigned char y1, - unsigned char x2, unsigned char y2, unsigned char c){ + unsigned char x2, unsigned char y2, unsigned char c) +{ drawLine( x1, y1, x2, y1, c ); drawLine( x1, y1, x1, y2, c ); drawLine( x1, y2, x2, y2, c ); @@ -547,7 +557,8 @@ * Return value : none */ void HT1632_LedMatrix::drawFilledRectangle(unsigned char x1, unsigned char y1, - unsigned char x2, unsigned char y2, unsigned char c) { + unsigned char x2, unsigned char y2, unsigned char c) +{ for(int i=y1; i <= y2; i++ ) { drawLine( x1, i, x2, i, c ); } @@ -556,22 +567,23 @@ /* * Name : drawCircle - * Description : Draw a circle using Bresenham's algorithm. + * Description : Draw a circle using Bresenham's algorithm. * Some small circles will look like squares!! * Argument(s) : xc, yc - Centre of circle * r - Radius * c - either PIXEL_ON, PIXEL_OFF - * Return value : None + * Return value : None */ void HT1632_LedMatrix::drawCircle(unsigned char xc, unsigned char yc, - unsigned char r, unsigned char c) { + unsigned char r, unsigned char c) +{ int x=0; int y=r; int p=3-(2*r); - plot( xc+x,yc-y, c); + plot( xc+x,yc-y, c); - for(x=0;x<=y;x++) { + for(x=0; x<=y; x++) { if (p<0) { y=y; p=(p+(4*x)+6);