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.

LED7segmDual4094.cpp

Committer:
amateusz
Date:
2015-12-19
Revision:
0:55c62e840faf

File content as of revision 0:55c62e840faf:

#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;
}