7 segment display library for mbed This routine support 2,4 and 8 digit anode-common or cathode-common LED.

Dependents:   7segMbed

Revision:
0:6bf4ee8ee342
Child:
1:12daa491059c
diff -r 000000000000 -r 6bf4ee8ee342 Sseg.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sseg.cpp	Sun Oct 20 05:59:40 2013 +0000
@@ -0,0 +1,311 @@
+/*
+  Sseg.cpp - mbed library for 7seg 4digit/8digit LED matrix.
+  Copyright 2013 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;
+}
+
+// 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;
+}
+
+// 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;
+}
+
+
+void Sseg::begin(void) {
+    timer.start();
+    clear();
+}
+
+void Sseg::setAcommon(void) {
+    _kcommon = false;
+}
+
+void Sseg::setKcommon(void) {
+    _kcommon = 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 y, uint8_t value) {
+    _buffer[y] = 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) ? _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) {
+    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