16 segment display library for mbed This routine support 4, 6 and 8 digit anode-common or cathode-common LED.
Stnseg.cpp
- Committer:
- morecat_lab
- Date:
- 2015-02-08
- Revision:
- 0:420d710da1c5
File content as of revision 0:420d710da1c5:
/* Stnseg.cpp - mbed library for 4/6/8 digit Sixteen (16) segment LED driver. Copyright 2015 by morecat_lab This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include "Stnseg.h" #include <Timer.h> const uint16_t Stnseg::numConv[] = { NUM_PAT16_0, NUM_PAT16_1, NUM_PAT16_2, NUM_PAT16_3, NUM_PAT16_4, NUM_PAT16_5, NUM_PAT16_6, NUM_PAT16_7, NUM_PAT16_8, NUM_PAT16_9, NUM_PAT16_A, NUM_PAT16_B, NUM_PAT16_C, NUM_PAT16_D, NUM_PAT16_E, NUM_PAT16_F}; // 4 digit Stnseg::Stnseg(PinName data,PinName clock, PinName latch,PinName dp, PinName d1,PinName d2, PinName d3, PinName d4) : _dataPin(data), _clockPin(clock), _latchPin(latch), _dpPin(dp), _digPins(d1, d2, d3, d4) { _numOfDigs = 4; _updateInterval = (8333 / 4); _zeroSupress = true; _kcommon = false; } // 6 digit Stnseg::Stnseg(PinName data,PinName clock, PinName latch,PinName dp, PinName d1,PinName d2, PinName d3, PinName d4, PinName d5,PinName d6) : _dataPin(data), _clockPin(clock), _latchPin(latch), _dpPin(dp), _digPins(d1, d2, d3, d4, d5, d6) { _numOfDigs = 6; _updateInterval = (8333 / 6); _zeroSupress = true; _kcommon = false; } // 8 digit Stnseg::Stnseg(PinName data,PinName clock, PinName latch,PinName dp, PinName d1,PinName d2, PinName d3, PinName d4, PinName d5,PinName d6, PinName d7, PinName d8) : _dataPin(data), _clockPin(clock), _latchPin(latch), _dpPin(dp), _digPins(d1, d2, d3, d4, d5, d6, d7, d8) { _numOfDigs = 8; _updateInterval = (8333 / 8); _zeroSupress = true; _kcommon = false; } void Stnseg::begin(void) { timer.start(); clear(); } void Stnseg::setAcommon(void) { _kcommon = false; } void Stnseg::setKcommon(void) { _kcommon = true; } uint16_t Stnseg::segCh(char i) { return numConv[i]; } void Stnseg::setDot(int d) { _buffer[d] |= 0x010000; } void Stnseg::clearDot(int d) { _buffer[d] &= 0xfffe0000; } void Stnseg::writeNum(int n) { if (_numOfDigs == 4) { writeNum4(n); } else if (_numOfDigs == 6) { writeNum6(n); } else if (_numOfDigs == 8) { writeNum8((long)n); } } void Stnseg::writeNum4(int n) { if (n < 10000) { _buffer[0] = segCh((n % 10000) / 1000); _buffer[1] = segCh((n % 1000) / 100); _buffer[2] = segCh((n % 100) / 10); _buffer[3] = segCh(n % 10); supressZero(); } else { _buffer[0] = _buffer[1] = _buffer[2] = _buffer[3] = NUM_PAT16_MINUS;// overflow } } void Stnseg::writeNum6(int n) { if (n < 10000) { _buffer[0] = segCh((n % 1000000) / 100000); _buffer[1] = segCh((n % 100000) / 10000); _buffer[2] = segCh((n % 10000) / 1000); _buffer[3] = segCh((n % 1000) / 100); _buffer[4] = segCh((n % 100) / 10); _buffer[5] = segCh(n % 10); supressZero(); } else { _buffer[0] = _buffer[1] = _buffer[2] = _buffer[3] = NUM_PAT16_MINUS;// overflow } } void Stnseg::writeNum8(int n) { if (n < 1000000) { _buffer[0] = segCh((n % 100000000) / 10000000); _buffer[1] = segCh((n % 10000000) / 1000000); _buffer[2] = segCh((n % 1000000) / 100000); _buffer[3] = segCh((n % 100000) / 10000); _buffer[4] = segCh((n % 10000) / 1000); _buffer[5] = segCh((n % 1000) / 100); _buffer[6] = segCh((n % 100) / 10); _buffer[7] = segCh(n % 10); supressZero(); } else { _buffer[0] = _buffer[1] = _buffer[2] = _buffer[3] = _buffer[4] = _buffer[5] = NUM_PAT16_MINUS;// overflow } } void Stnseg::writeNum(char d1, char d2) { _buffer[0] = segCh(d1); _buffer[1] = segCh(d2); supressZero(); } void Stnseg::writeNum(char d1, char d2, char d3, char d4) { _buffer[0] = segCh(d1); _buffer[1] = segCh(d2); _buffer[2] = segCh(d3); _buffer[3] = segCh(d4); supressZero(); } void Stnseg::writeNum(char d1, char d2, char d3, char d4, char d5, char d6, char d7, char d8) { _buffer[0] = segCh(d1); _buffer[1] = segCh(d2); _buffer[2] = segCh(d3); _buffer[3] = segCh(d4); _buffer[4] = segCh(d5); _buffer[5] = segCh(d6); _buffer[6] = segCh(d7); _buffer[7] = segCh(d8); supressZero(); } void Stnseg::writeHex(long n) { if (_numOfDigs == 4) { _buffer[0] = segCh((n >> 12) & 0xf); _buffer[1] = segCh((n >> 8) & 0xf); _buffer[2] = segCh((n >> 4) & 0xf); _buffer[3] = segCh(n & 0xf); } else if (_numOfDigs == 6) { _buffer[0] = segCh((n >> 20) & 0xf); _buffer[1] = segCh((n >> 16) & 0xf); _buffer[2] = segCh((n >> 12) & 0xf); _buffer[3] = segCh((n >> 8) & 0xf); _buffer[4] = segCh((n >> 4) & 0xf); _buffer[5] = segCh(n & 0xf); } else if (_numOfDigs == 8) { _buffer[0] = segCh((n >> 28) & 0xf); _buffer[1] = segCh((n >> 24) & 0xf); _buffer[2] = segCh((n >> 20) & 0xf); _buffer[3] = segCh((n >> 16) & 0xf); _buffer[4] = segCh((n >> 12) & 0xf); _buffer[5] = segCh((n >> 8) & 0xf); _buffer[6] = segCh((n >> 4) & 0xf); _buffer[7] = segCh(n & 0xf); } supressZero(); } void Stnseg::setZeroSupress(bool t) { _zeroSupress = t; } void Stnseg::supressZero() { int i; if (_zeroSupress ) { for (i = 0 ; i < (_numOfDigs-1) ; i++) { if (_buffer[i] == segCh(0)) { _buffer[i] = _buffer[i] & 0x1000; } else { break; } } } } void Stnseg::writeRawData(uint32_t d1, uint32_t d2, uint32_t d3, uint32_t d4) { _buffer[0] = d1; _buffer[1] = d2; _buffer[2] = d3; _buffer[3] = d4; } void Stnseg::writeRawData(uint32_t d1, uint32_t d2, uint32_t d3, uint32_t d4, uint32_t d5, uint32_t d6) { _buffer[0] = d1; _buffer[1] = d2; _buffer[2] = d3; _buffer[3] = d4; _buffer[4] = d5; _buffer[5] = d6; } void Stnseg::writeRawData(uint32_t d1, uint32_t d2, uint32_t d3, uint32_t d4, uint32_t d5, uint32_t d6, uint32_t d7, uint32_t d8) { _buffer[0] = d1; _buffer[1] = d2; _buffer[2] = d3; _buffer[3] = d4; _buffer[4] = d5; _buffer[5] = d6; _buffer[6] = d7; _buffer[7] = d8; } void Stnseg::write(uint8_t d, uint32_t value) { _buffer[d] = value; } void Stnseg::clear(void) { int i; for(i=0;i<8;i++){ _buffer[i] = 0; } _dig = _numOfDigs - 1; _digPins = ( _kcommon) ? 0xff : 0; } void Stnseg::turnOff(void) { if ( _kcommon) { _digPins = 0xff; // set HIGH } else { _digPins = 0; // set LOW } } void Stnseg::turnOn(void) { if ( _kcommon) { _digPins = ~(1 << _dig); // set LOW } else { _digPins = (1 << _dig); // set HIGH } } void Stnseg::updateSeg(void) { if( (++_dig) >= _numOfDigs) _dig = 0; _latchPin = 0; for (int col = 0 ; col < 16 ; col++) { // forward order _clockPin = 0; if(_buffer[_dig] & (1 << col)){ _dataPin = 1; } else { _dataPin = 0; } _clockPin = 1; } _latchPin = 1; if ((_buffer[_dig] & 0x10000) != 0) { _dpPin = 1; } else { _dpPin = 0; } } void Stnseg::updateWithDelay(int ms) { timer.reset(); // to avoid overflow 32bit counter (~=30min) int start = timer.read_ms(); _dig = _numOfDigs - 1; turnOff(); do { for (int i = 0 ; i < _numOfDigs ; i++) { updateSeg(); turnOn(); wait(0.001f); // wait 1ms turnOff(); } if ((timer.read_ms() - start) >= ms) { break; } } while(1); } void Stnseg::updateOnce(void) { uint8_t i; _dig = _numOfDigs - 1; turnOff(); for (i = 0 ; i < _numOfDigs ; i++) { updateSeg(); turnOn(); wait(0.001f); // wait 1ms turnOff(); } } // EOF