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
Yoshitaka Kuwata