Yoshitaka Kuwata / sseg

Dependents:   7segMbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Sseg.cpp Source File

Sseg.cpp

00001 /*
00002   Sseg.cpp - mbed library for 2/4/8 digit seven segment LED driver.
00003   Copyright 2013,2014,2015 by morecat_lab
00004  
00005   base on Dots library.
00006   Copyright 2010 arms22. All right reserved.
00007   
00008   This library is distributed in the hope that it will be useful,
00009   but WITHOUT ANY WARRANTY; without even the implied warranty of
00010   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
00011 */
00012 
00013 #include "Sseg.h"
00014 #include <Timer.h>
00015 
00016 const int Sseg::numConv[] = {
00017     NUM_PAT_0, NUM_PAT_1, NUM_PAT_2, NUM_PAT_3,
00018     NUM_PAT_4, NUM_PAT_5, NUM_PAT_6, NUM_PAT_7,
00019     NUM_PAT_8, NUM_PAT_9, NUM_PAT_A, NUM_PAT_B,
00020     NUM_PAT_C, NUM_PAT_D, NUM_PAT_E, NUM_PAT_F};
00021 
00022 // 2 digit
00023 Sseg::Sseg(PinName a,PinName b,PinName c,PinName d,
00024            PinName e,PinName f,PinName g,PinName dp,
00025            PinName d1,PinName d2) 
00026 {
00027     _numOfDigs = 2;
00028     PinName segPins[8] = {a, b, c, d, e, f, g, dp};
00029     PinName digPins[2] = {d1, d2};
00030 
00031     for (int i=0; i<8; i++) {
00032         _segPins[i] = new DigitalOut(segPins[i]);
00033     }
00034 
00035     for (int i=0; i<_numOfDigs; i++) {
00036         _digPins[i] = new DigitalOut(digPins[i]);
00037     }
00038 
00039     _updateInterval = (8333 / 2);
00040     _zeroSupress = true;
00041     _kcommon = false;
00042     _sinkDriver = false;
00043 }
00044 
00045 // 4 digit
00046 Sseg::Sseg(PinName a,PinName b,PinName c,PinName d,
00047            PinName e,PinName f,PinName g,PinName dp,
00048            PinName d1,PinName d2,PinName d3,PinName d4)
00049 {
00050     _numOfDigs = 4;
00051     PinName segPins[8] = {a, b, c, d, e, f, g, dp};
00052     PinName digPins[4] = {d1, d2, d3, d4};
00053 
00054     for (int i=0; i<8; i++) {
00055         _segPins[i] = new DigitalOut(segPins[i]);
00056     }
00057 
00058     for (int i=0; i<_numOfDigs; i++) {
00059         _digPins[i] = new DigitalOut(digPins[i]);
00060     }
00061     _updateInterval = (8333 / 4);
00062     _zeroSupress = true;
00063     _kcommon = false;
00064     _sinkDriver = false;
00065 }
00066 
00067 // 8 digit
00068 Sseg::Sseg(PinName a,PinName b,PinName c,PinName d,
00069            PinName e,PinName f,PinName g,PinName dp,
00070            PinName d1,PinName d2,PinName d3,PinName d4,
00071            PinName d5,PinName d6,PinName d7,PinName d8)
00072 {
00073     _numOfDigs = 8;
00074     PinName segPins[8] = {a, b, c, d, e, f, g, dp};
00075     PinName digPins[8] = {d1, d2, d3, d4, d5, d6, d7, d8};
00076 
00077     for (int i=0; i<8; i++) {
00078         _segPins[i] = new DigitalOut(segPins[i]);
00079     }
00080 
00081     for (int i=0; i<_numOfDigs; i++) {
00082         _digPins[i] = new DigitalOut(digPins[i]);
00083     }    _updateInterval = (8333 / 8);
00084     _zeroSupress = true;
00085     _kcommon = false;
00086     _sinkDriver = false;
00087 }
00088 
00089 
00090 void Sseg::begin(void) {
00091     timer.start();
00092     clear();
00093 }
00094 
00095 void Sseg::setAcommon(void) {
00096     _kcommon = false;
00097 }
00098 
00099 void Sseg::setKcommon(void) {
00100     _kcommon = true;
00101 }
00102 
00103 void Sseg::setSinkDriver(void) {
00104     _sinkDriver = true;
00105 }
00106 
00107 char Sseg::segCh(char i) {
00108     return Sseg::numConv[i];
00109 }
00110 
00111 void Sseg::setDot(int d) {
00112     _buffer[d] |= 0x01;
00113 }
00114 
00115 void Sseg::clearDot(int d) {
00116     _buffer[d] &= 0xfe;
00117 }
00118 
00119 void Sseg::writeNum(int n) {
00120     if (_numOfDigs == 2) {
00121         writeNum2(n);
00122     } else if (_numOfDigs == 4) {
00123         writeNum4(n);
00124     } else if (_numOfDigs == 8) {
00125         writeNum8((long)n);
00126     }
00127 }
00128 
00129 void Sseg::writeNum2(int n) {
00130     if (n < 100) {
00131         _buffer[0] = segCh((n % 100) / 10);
00132         _buffer[1] = segCh(n % 10);
00133         Sseg::supressZero();
00134     } else {
00135         _buffer[0] = _buffer[1] = 0x02;// overflow
00136     }
00137 }
00138 
00139 void Sseg::writeNum4(int n) {
00140     if (n < 10000) {
00141         _buffer[0] = segCh((n % 10000) / 1000);
00142         _buffer[1] = segCh((n % 1000) / 100);
00143         _buffer[2] = segCh((n % 100) / 10);
00144         _buffer[3] = segCh(n % 10);
00145         Sseg::supressZero();
00146     } else {
00147         _buffer[0] = _buffer[1] = _buffer[2] = _buffer[3] = 0x02;// overflow
00148     }
00149 }
00150 
00151 void Sseg::writeNum8(int n) {
00152     _buffer[0] = segCh((n % 100000000) / 10000000);
00153     _buffer[1] = segCh((n % 10000000) / 1000000);
00154     _buffer[2] = segCh((n % 1000000) / 100000);
00155     _buffer[3] = segCh((n % 100000) / 10000);
00156     _buffer[4] = segCh((n % 10000) / 1000);
00157     _buffer[5] = segCh((n % 1000) / 100);
00158     _buffer[6] = segCh((n % 100) / 10);
00159     _buffer[7] = segCh(n % 10);
00160     Sseg::supressZero();
00161 }
00162 
00163 void Sseg::writeNum(char d1, char d2) {
00164     _buffer[0] = segCh(d1);
00165     _buffer[1] = segCh(d2);
00166     Sseg::supressZero();
00167 }
00168 
00169 void Sseg::writeNum(char d1, char d2, char d3, char d4) {
00170     _buffer[0] = segCh(d1);
00171     _buffer[1] = segCh(d2);
00172     _buffer[2] = segCh(d3);
00173     _buffer[3] = segCh(d4);
00174     Sseg::supressZero();
00175 }
00176 
00177 void Sseg::writeNum(char d1, char d2, char d3, char d4,
00178                     char d5, char d6, char d7, char d8)
00179 {
00180     _buffer[0] = segCh(d1);
00181     _buffer[1] = segCh(d2);
00182     _buffer[2] = segCh(d3);
00183     _buffer[3] = segCh(d4);
00184     _buffer[4] = segCh(d5);
00185     _buffer[5] = segCh(d6);
00186     _buffer[6] = segCh(d7);
00187     _buffer[7] = segCh(d8);
00188     Sseg::supressZero();
00189 }
00190 
00191 void Sseg::writeHex(int n) {
00192     if(_numOfDigs == 2) {
00193         _buffer[0] = segCh((n >> 4) & 0xf);
00194         _buffer[1] = segCh(n & 0xf);
00195     } else if (_numOfDigs == 4) {
00196         _buffer[0] = segCh((n >> 12) & 0xf);
00197         _buffer[1] = segCh((n >> 8) & 0xf);
00198         _buffer[2] = segCh((n >> 4) & 0xf);
00199         _buffer[3] = segCh(n & 0xf);
00200     }
00201     Sseg::supressZero();
00202 }
00203 
00204 void Sseg::writeHex(long n) {
00205     _buffer[0] = segCh((n >> 28) & 0xf);
00206     _buffer[1] = segCh((n >> 24) & 0xf);
00207     _buffer[2] = segCh((n >> 20) & 0xf);
00208     _buffer[3] = segCh((n >> 16) & 0xf);
00209     _buffer[4] = segCh((n >> 12) & 0xf);
00210     _buffer[5] = segCh((n >> 8) & 0xf);
00211     _buffer[6] = segCh((n >> 4) & 0xf);
00212     _buffer[7] = segCh(n & 0xf);
00213     Sseg::supressZero();
00214 }
00215 
00216 void Sseg::setZeroSupress(bool t) {
00217     _zeroSupress = t;
00218 }
00219 
00220 void Sseg::supressZero() {
00221     int i;
00222     if (_zeroSupress ) {
00223         for (i = 0 ; i < (_numOfDigs-1) ; i++) {
00224             if (_buffer[i] == segCh(0)) {
00225                 _buffer[i] = _buffer[i] & 0x1;
00226             } else {
00227                 break;
00228             }
00229         }
00230     }
00231 }
00232 
00233 void Sseg::writeRawData(char d1, char d2) {
00234     _buffer[0] = d1;
00235     _buffer[1] = d2;
00236 }
00237 
00238 void Sseg::writeRawData(char d1, char d2, char d3, char d4) {
00239     _buffer[0] = d1;
00240     _buffer[1] = d2;
00241     _buffer[2] = d3;
00242     _buffer[3] = d4;
00243 }
00244 
00245 void Sseg::writeRawData(char d1, char d2, char d3, char d4,
00246                         char d5, char d6, char d7, char d8)
00247 {
00248     _buffer[0] = d1;
00249     _buffer[1] = d2;
00250     _buffer[2] = d3;
00251     _buffer[3] = d4;
00252     _buffer[4] = d5;
00253     _buffer[5] = d6;
00254     _buffer[6] = d7;
00255     _buffer[7] = d8;
00256 }
00257 
00258 void Sseg::write(uint8_t x, uint8_t y, uint8_t value) {
00259     uint8_t tmp,msk;
00260     tmp = _buffer[y];
00261     msk = 0x80 >> x;
00262     tmp = tmp & ~msk;
00263     tmp = tmp | (value ? msk : 0);
00264     _buffer[y] = tmp;
00265 }
00266 
00267 void Sseg::write(uint8_t d, uint8_t value) {
00268     _buffer[d] = value;
00269 }
00270 
00271 void Sseg::write(uint8_t y, const uint8_t values[], uint8_t size) {
00272     uint8_t i;
00273     for(i=0;i<size;i++)
00274         _buffer[(y++) & 0x07] = values[i];
00275 }
00276 
00277 void Sseg::clear(void) {
00278     int i;
00279     for(i=0;i<8;i++){
00280         _buffer[i] = 0;
00281     }
00282     _dig = _numOfDigs - 1;
00283 }
00284 
00285 void Sseg::turnOff(void) {
00286     _digPins[_dig] -> write((_kcommon) ? 1 : 0);
00287 }
00288 
00289 void Sseg::turnOn(void) {
00290     _digPins[_dig] -> write((_kcommon) ? 0 : 1);
00291 }
00292 
00293 void Sseg::updateSeg(void) {
00294     char i,data,mask;
00295     if( (++_dig) >= _numOfDigs)
00296         _dig = 0;
00297     data = _buffer[_dig];
00298     mask = 0x80;
00299     for(i=0;i<8;i++){
00300         if(data & mask){
00301             _segPins[i]->write(((_kcommon) || (_sinkDriver)) ? 1 : 0);
00302         }else{
00303             _segPins[i]->write(((_kcommon) || (_sinkDriver)) ? 0 : 1);
00304         }
00305         mask >>= 1;
00306     }
00307 }
00308 
00309 bool Sseg::update(void) {
00310     int t = timer.read_us();
00311     bool sync = false;
00312     if((t - _lastUpdateTime) > _updateInterval){
00313         turnOff();
00314         updateSeg();
00315         turnOn();
00316         _lastUpdateTime = t;
00317         sync = (_dig == 0);
00318     }
00319     return sync;
00320 }
00321 
00322 void Sseg::updateWithDelay(int ms) {
00323     timer.reset();  // to avoid overflow 32bit counter  (~=30min)
00324     int start = timer.read_ms();
00325     do {
00326         bool sync = update();
00327         if(sync){
00328             int t = timer.read_ms();
00329             if((t - start) >= ms){
00330                 break;
00331             }
00332         }
00333     } while(1);
00334 }
00335 
00336 void Sseg::updateOnce(void) {
00337     uint8_t i;
00338     _dig = _numOfDigs - 1;
00339     turnOff();
00340     for (i = 0 ; i < _numOfDigs ; i++) {
00341         updateSeg();
00342         turnOn();
00343         wait(0.001f); // wait 1ms
00344         turnOff();
00345     }
00346 }
00347 
00348 // EOF