7 segment display library for mbed This routine support 2,4 and 8 digit anode-common or cathode-common LED.
Sseg.cpp
- Committer:
- morecat_lab
- Date:
- 2015-01-12
- Revision:
- 9:6d3229c8dc0f
- Parent:
- 7:a19431131213
- Child:
- 10:1b8dbe52e5a8
File content as of revision 9:6d3229c8dc0f:
/* Sseg.cpp - mbed library for 2/4/8 digit seven segment LED driver. Copyright 2013,2014 by morecat_lab base on Dots library. Copyright 2010 arms22. All right reserved. 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 "Sseg.h" #include <Timer.h> const int Sseg::numConv[] = { NUM_PAT_0, NUM_PAT_1, NUM_PAT_2, NUM_PAT_3, NUM_PAT_4, NUM_PAT_5, NUM_PAT_6, NUM_PAT_7, NUM_PAT_8, NUM_PAT_9, NUM_PAT_A, NUM_PAT_B, NUM_PAT_C, NUM_PAT_D, NUM_PAT_E, NUM_PAT_F}; // 2 digit Sseg::Sseg(PinName a,PinName b,PinName c,PinName d, PinName e,PinName f,PinName g,PinName dp, PinName d1,PinName d2) : _segPins( dp, g, f, e, d, c, b, a), _digPins(d1, d2) { _numOfDigs = 2; _updateInterval = (8333 / 2); _zeroSupress = true; _kcommon = false; _sinkDriver = false; } // 4 digit Sseg::Sseg(PinName a,PinName b,PinName c,PinName d, PinName e,PinName f,PinName g,PinName dp, PinName d1,PinName d2,PinName d3,PinName d4) : _segPins( dp, g, f, e, d, c, b, a), _digPins(d1, d2, d3, d4) { _numOfDigs = 4; _updateInterval = (8333 / 4); _zeroSupress = true; _kcommon = false; _sinkDriver = false; } // 8 digit Sseg::Sseg(PinName a,PinName b,PinName c,PinName d, PinName e,PinName f,PinName g,PinName dp, PinName d1,PinName d2,PinName d3,PinName d4, PinName d5,PinName d6,PinName d7,PinName d8) : _segPins( dp, g, f, e, d, c, b, a), _digPins(d1, d2, d3, d4, d5, d6, d7, d8) { _numOfDigs = 8; _updateInterval = (8333 / 8); _zeroSupress = true; _kcommon = false; _sinkDriver = false; } void Sseg::begin(void) { timer.start(); clear(); } void Sseg::setAcommon(void) { _kcommon = false; } void Sseg::setKcommon(void) { _kcommon = true; } void Sseg::setSinkDriver(void) { _sinkDriver = true; } char Sseg::segCh(char i) { return Sseg::numConv[i]; } void Sseg::setDot(int d) { _buffer[d] |= 0x01; } void Sseg::clearDot(int d) { _buffer[d] &= 0xfe; } void Sseg::writeNum(int n) { if (_numOfDigs == 2) { writeNum2(n); } else if (_numOfDigs == 4) { writeNum4(n); } else if (_numOfDigs == 8) { writeNum8((long)n); } } void Sseg::writeNum2(int n) { if (n < 100) { _buffer[0] = segCh((n % 100) / 10); _buffer[1] = segCh(n % 10); Sseg::supressZero(); } else { _buffer[0] = _buffer[1] = 0x02;// overflow } } void Sseg::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); Sseg::supressZero(); } else { _buffer[0] = _buffer[1] = _buffer[2] = _buffer[3] = 0x02;// overflow } } void Sseg::writeNum8(int n) { _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); Sseg::supressZero(); } void Sseg::writeNum(char d1, char d2) { _buffer[0] = segCh(d1); _buffer[1] = segCh(d2); Sseg::supressZero(); } void Sseg::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); Sseg::supressZero(); } void Sseg::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); Sseg::supressZero(); } void Sseg::writeHex(int n) { if(_numOfDigs == 2) { _buffer[0] = segCh((n >> 4) & 0xf); _buffer[1] = segCh(n & 0xf); } else 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); } Sseg::supressZero(); } void Sseg::writeHex(long n) { _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); Sseg::supressZero(); } void Sseg::setZeroSupress(bool t) { _zeroSupress = t; } void Sseg::supressZero() { int i; if (_zeroSupress ) { for (i = 0 ; i < (_numOfDigs-1) ; i++) { if (_buffer[i] == segCh(0)) { _buffer[i] = _buffer[i] & 0x1; } else { break; } } } } void Sseg::writeRawData(char d1, char d2) { _buffer[0] = d1; _buffer[1] = d2; } void Sseg::writeRawData(char d1, char d2, char d3, char d4) { _buffer[0] = d1; _buffer[1] = d2; _buffer[2] = d3; _buffer[3] = d4; } void Sseg::writeRawData(char d1, char d2, char d3, char d4, char d5, char d6, char d7, char 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 Sseg::write(uint8_t x, uint8_t y, uint8_t value) { uint8_t tmp,msk; tmp = _buffer[y]; msk = 0x80 >> x; tmp = tmp & ~msk; tmp = tmp | (value ? msk : 0); _buffer[y] = tmp; } void Sseg::write(uint8_t d, uint8_t value) { _buffer[d] = value; } void Sseg::write(uint8_t y, const uint8_t values[], uint8_t size) { uint8_t i; for(i=0;i<size;i++) _buffer[(y++) & 0x07] = values[i]; } void Sseg::clear(void) { int i; for(i=0;i<8;i++){ _buffer[i] = 0; } _dig = _numOfDigs - 1; } void Sseg::turnOff(void) { if ( _kcommon) { _digPins = _digPins & (1 << _dig); // set LOW } else { _digPins = _digPins | (~(1 << _dig)); // set HIGH } } void Sseg::turnOn(void) { if ( _kcommon) { _digPins = _digPins | (~(1 << _dig)); // set HIGH } else { _digPins = _digPins & (1 << _dig); // set LOW } } void Sseg::updateSeg(void) { if( (++_dig) >= _numOfDigs) _dig = 0; _segPins = (( _kcommon) || (_sinkDriver)) ? _buffer[_dig] : ~_buffer[_dig]; } bool Sseg::update(void) { int t = timer.read_us(); bool sync = false; if((t - _lastUpdateTime) > _updateInterval){ turnOff(); updateSeg(); turnOn(); _lastUpdateTime = t; sync = (_dig == 0); } return sync; } void Sseg::updateWithDelay(int ms) { timer.reset(); // to avoid overflow 32bit counter (~=30min) int start = timer.read_ms(); do { bool sync = update(); if(sync){ int t = timer.read_ms(); if((t - start) >= ms){ break; } } } while(1); } void Sseg::updateOnce(void) { uint8_t i; _dig = _numOfDigs - 1; turnOff(); for (i = 0 ; i < _numOfDigs ; i++) { updateSeg(); turnOn(); wait(0.001f); // wait 1ms turnOff(); } } // EOF