7-segment display with shift register. Common anode/cathode, any (eh, sort of) number of digits. Kind of framebuffer. Display has to be connected thru shift register, e.g. 4094. More details and picture in header file.
Diff: LED7segmDual4094.cpp
- Revision:
- 0:55c62e840faf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LED7segmDual4094.cpp Sat Dec 19 13:30:30 2015 +0000 @@ -0,0 +1,242 @@ +#include "mbed.h" +#include "LED7segmDual4094.h" + +signed char LED7segmDual4094::digitORascii2char (char input, bool dot) { + signed char return7seg = 0; + switch (input) { + case 0: + case '0': + case 'O': + return7seg = 0b00111111; + break; + case '1': + case 1: + return7seg = 0b00000110; + break; + case '2': + case 2: + case 'z': + case 'Z': + return7seg = 0b01011011; + break; + case 3: + case '3': + return7seg = 0b01001111; + break; + case 4: + case '4': + return7seg = 0b01100110; + break; + case 5: + case '5': + return7seg = 0b01101101; + break; + case 6: + case '6': + return7seg = 0b01111100; + break; + case 7: + case '7': + return7seg = 0b00000111; + break; + case 8: + case '8': + return7seg = 0b01111111; + break; + case 9: + case '9': + return7seg = 0b01100111; + break; + case 'a': + case 'A': + return7seg = 0b01110111; + break; + case 'b': + case 'B': + return7seg = 0b01111100; + break; + case 'c': + return7seg = 0b01011000; + break; + case 'C': + return7seg = 0b00111001; + break; + case 'd': + case 'D': + return7seg = 0b01011110; + break; + case 'e': + return7seg = 0b01111011; + break; + case 'E': + return7seg = 0b01111001; + break; + case 'f': + case 'F': + return7seg = 0b01110001; + break; + case 'g': + return7seg = 0b01101111; + case 'G': + return7seg = 0b00111101; + break; + case 'h': + return7seg = 0b01110100; + break; + case 'H': + return7seg = 0b01110110; + break; + case 'i': + return7seg = 0b00010000; + break; + case 'I': + return7seg = 0b00110000; + break; + case 'j': + return7seg = 0b00001111; + break; + case 'J': + return7seg = 0b00011111; + break; + case 'k': + return7seg = 0b01111000; + break; + case 'l': + return7seg = 0b00110000; + break; + case 'L': + return7seg = 0b00111000; + break; + case 'm': + case 'n': + return7seg = 0b01010100; + break; + case 'N': + case 'M': + return7seg = 0b00110111; + break; + case 'o': + return7seg = 0b01011100; + break; + case 'p': + case 'P': + return7seg = 0b01110011; + break; + case 'r': + case 'R': + return7seg = 0b01010000; + break; + case 's': + case 'S': + return7seg = 0b01101101; + break; + case 'q': + case 'Q': + return7seg = 0b01100111; + break; + case 't': + case 'T': + return7seg = 0b01111000; + break; + case 'u': + return7seg = 0b00011100; + break; + case 'U': + return7seg = 0b00111110; + break; + case 'v': + case 'V': + return7seg = 0b00111100; + break; + case 'w': + case 'W': + return7seg = 0b01001001; + break; + case 'x': + case 'X': + return7seg = 0b01110110; + break; + case 'y': + case 'Y': + return7seg = 0b01101110; + break; + case ' ': + return7seg = 0b00000000; + break; + default: + return7seg = -1; + break; + } + if (dot) return7seg |= (1 << 7); + // else clearing the dot ? + return return7seg; +} + +LED7segmDual4094::LED7segmDual4094(PinName data, PinName clock, PinName strobe, char numOfSegments): _data(data), _clock(clock), _strobe(strobe) { + whichSegmMux = 0; + _numOfSegments = numOfSegments; + fb = new char [_numOfSegments]; + _anodesBitMask = new unsigned int[_numOfSegments]; + for (unsigned int i = 0; i < numOfSegments; i++) + _anodesBitMask[i] = ( 1 << i ); +} +void LED7segmDual4094::setAnodesBitMask(unsigned int *tab) { + for (char i = 0; i < _numOfSegments; i++) + _anodesBitMask[i] = tab[i]; +}; +void LED7segmDual4094::draw(void){ // a version with no arguments is for internal (i.e. private) use only. the other one is exposed publicly. + if (_anodesActiveState) + load = 0; + else load = ~0; + for (char i = 0; i < 8; i++) { + if ((fb[whichSegmMux] >> i) & 0x1) load |= 1 << ( 8 + i); + else load &= ~(1 << (8+i)); + } + if (!_anodesActiveState) { + load &= ~_anodesBitMask[(_numOfSegments-1) - whichSegmMux]; + /*for (int i = 0; i < _numOfSegments; i++) + if (whichSegmMux != (_numOfSegments - 1) - i) // when ""if(whichSegmMux != i)"" then reverse direction of printing. + load |= _anodesBitMask[i]; + //load &= ~(_anodesBitMask[(_numOfSegments-1) - whichSegmMux]); + */ + } else + load |= 1 << (_numOfSegments - whichSegmMux); // sets a bit indicating which segment to light up (connect kathode (or anode, I mean positive rail)) + send4094(load); + if (++whichSegmMux > (_numOfSegments - 1)) whichSegmMux = 0; +} +/* void LED7segmDual4094::draw(char *tab) { + // whichSegmMux equals 0 on start thanks to the header file. || which segment for multiplexing + if (_anodesActiveState) + load = 0; + else load = ~0; + for (char i = 0; i < 8; i++) { + if ((tab[whichSegmMux] >> i) & 0x1) load |= 1 << ( 8 + i); + else load &= ~(1 << (8+i)); + } + if (!_anodesActiveState) { + load &= ~_anodesBitMask[(_numOfSegments-1) - whichSegmMux]; + //for (int i = 0; i < _numOfSegments; i++) + // if (whichSegmMux != (_numOfSegments - 1) - i) // when ""if(whichSegmMux != i)"" then reverse direction of printing. + // load |= _anodesBitMask[i]; + //load &= ~(_anodesBitMask[(_numOfSegments-1) - whichSegmMux]); + // + } else + load |= 1 << (_numOfSegments - whichSegmMux); // sets a bit indicating which segment to light up (connect kathode (or anode, I mean positive rail)) + send4094(load); + if (++whichSegmMux > (_numOfSegments - 1)) whichSegmMux = 0; +} +*/ + +void LED7segmDual4094::send4094(unsigned short _load) { // this shit is straight from the datasheet, just loading these 16bits to two daisy-chained 4094 shift registers + _strobe = 0; + for (signed char _i = 15; _i >= 0; _i--) { + _data = (_load >> _i) & 0x1 ; + _clock = 0; + _clock = 1; + } + _strobe = 1; +} + +void LED7segmDual4094::setAnodesActiveState(bool state) { + _anodesActiveState = state; +}