OSL10564_74HC595

Fork of OSL10564_74HC595 by Kenji Arai

7segLed_HC595.cpp

Committer:
shivanandgowdakr
Date:
2018-08-14
Revision:
1:a3755014b7f1
Parent:
0:3373357a49f4

File content as of revision 1:a3755014b7f1:



#include "7segLed_HC595.h"

SevenSegLed::SevenSegLed
( PinName sdo, PinName sclk, PinName latch, PinName bright,
  uint8_t num_of_digit
)
    : spi_(sdo, NC, sclk), latch_(latch), pwm_(bright)
{
    num = num_of_digit;
    dot_inf = 0;
    zerosuppress = false;
    spi_.frequency(1000000);
    spi_.format(8,0);
    latch_ = 0;
    pwm_.period_ms(2);
    bright_data = 1.0f;
    pwm_.pulsewidth_us(bright_data);
}

void SevenSegLed::put_num(int32_t dt)
{
    wrk = dt;
    for(uint32_t i = 0; i < num; i++) {
        buf[i] = wrk % 10;  // set each digit value
        wrk /= 10;          // next digit
    }
    num_mode = true;        // set number display mode
    seven_seg_n_digt();     // convert to seven segment element and send SPI
}

void SevenSegLed::put_ascii(const char *data)
{
    char dt;

    dot_inf = 0;            // clear all dot
    for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
        buf[i] = 0;
    }
    int32_t po = num - 1;
    for(uint32_t pi = 0; ; pi++) {
        dt = *(data + pi);
        //pc.putc(dt);
        if (dt == 0) {
            break;          // end of strings
        }
        if (dt == '.') {    // check dot
            if (pi == 0) {
                buf[po] = 0;
                po--;
                dot_inf |= 1U << num - 1; // set dot
            } else {
                dot_inf |= 1U << (po + 1); // set dot
            }
            pi++;
            dt = *(data + pi);
        }
        buf[po] = dt - '0';// convert ASCII number to value
        po--;
        if (po == -1) {
            break;
        }
    }
    num_mode = false;       // set none number display mode
    seven_seg_n_digt();     // convert to seven segment element and send SPI
}

void SevenSegLed::put_raw(uint8_t *data)
{
    for(uint32_t i = 0; i < num; i++) {
        uint8_t dt = *(data + i);
        if (dt == 0) {
            break;
        }
        seg[i] = dt;
    }
    spi_out();
}

void SevenSegLed::put_dot(uint16_t position)
{
    dot_inf = position;
}

void SevenSegLed::clear_all_dot()
{
    dot_inf = 0;
}

void SevenSegLed::zero_suppress(bool mode)
{
    zerosuppress = mode;
}

void SevenSegLed::brightness(float bright)
{
    bright_data = bright;
    pwm_.pulsewidth_us((int)(2000 * (1.0f - bright)));
}

void SevenSegLed::frequency(int32_t freq)
{
    spi_.frequency((int)freq);
}

void SevenSegLed::seven_seg_n_digt()
{
    uint8_t const seg_bit[10] =
    {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x27, 0x7f, 0x67};
    //  0     1     2     3     4     5     6     7     8     9

    for(uint32_t i = 0; i < num; i++) {
        seg[i] = seg_bit[buf[i]];   // convert number to segment data
    }
    if ((num_mode == true) && (zerosuppress == true)) { // zero suppress
        for(uint32_t i = 0; i < num; i++) {
            if (seg[num -1 - i] == 0x3f) {  // if zero then zero suppress
                if ((num -1 - i) == 0) {
                    break;
                }
                seg[num -1 - i] = 0;
            } else {
                break;
            }
        }
    }
    set_dot();
    spi_out();
}

void SevenSegLed::set_dot()
{
    for(uint8_t i = 0; i < num; i++) {
        if ((dot_inf >> i) & 0x0001) {      // check dot request
            seg[i] |= 0x80;                 // add dot
        }
    }
    for(uint8_t i = 0; i < num; i++) {
        if (seg[num -1 - i] & 0x80) {       // check dot is on or off
            if (seg[num -1 - i] == 0x80) {  // did zero suppress condition
                seg[num -1 - i] = 0xbf;     // set zero+dot
                for(i++; i < num; i++) {
                    if (seg[num -1 - i] == 0) { // check zero suppress
                        seg[num -1 - i] = 0x3f; // set zero
                    }
                }
                break;
            }
        }
    }
}

void SevenSegLed::spi_out()
{
    pwm_.pulsewidth_us(0);
    for(uint32_t i = 0; i < num; i++) {
        spi_.write(seg[i]);     // send SPI line
    }
    latch_ = 1;                 // set latch pulse
    wait_us(2);
    latch_ = 0;
    pwm_.pulsewidth_us((int)(2000 * (1.0f - bright_data)));
}

//------------------------------------------------------------------------------
// Alphabet on 7segment
// refernce
//  WentWayUp: WebLog
//    http://wentwayup.tamaliver.jp/e400000.html
//------------------------------------------------------------------------------

#define OFFSET  0x20

char const alphabet_7seg[] = {
    // space
    0x00,
    // !     "     #     $     %     &     '     (     )     *
    0x0a, 0x22, 0x7e, 0x2d, 0x24, 0x3c, 0x20, 0x61, 0x43, 0x63,
    // +     ,     -     .     /
    0x44, 0x0c, 0x40, 0x10, 0x52,
    // 0     1     2     3     4     5     6     7     8     9
    0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67,
    // :     ;     <     =     >     ?
    0x09, 0x51, 0x59, 0x48, 0x4d, 0x4b,
    // @
    0x5f,
    // A     B     C     D     E     F     G     H     I  J (another C=0x39)
    0x77, 0x7c, 0x58, 0x5e, 0x79, 0x71, 0x3d, 0x74, 0x04, 0x1e,
    // K     L     M     N     O     P     Q     R     S     T
    0x75, 0x38, 0x55, 0x54, 0x5c, 0x73, 0x6b, 0x50, 0x6c, 0x78,
    // U     V     W     X     Y     Z (another W=0x7e)
    0x1c, 0x1d, 0x2a, 0x49, 0x6e, 0x1b,
    // [     \     ]     ^     _
    0x39, 0x64, 0x0f, 0x23, 0x08,
    // `
    0x02,
    // a     b     c     d     e     f     g     h     i     j
    0x77, 0x7c, 0x58, 0x5e, 0x79, 0x71, 0x3d, 0x74, 0x04, 0x1e,
    // k     l     m     n     o     p     q     r     s     t
    0x75, 0x38, 0x55, 0x54, 0x5c, 0x73, 0x6b, 0x50, 0x6c, 0x78,
    // u     v     w     x     y     z
    0x1c, 0x1d, 0x2a, 0x49, 0x6e, 0x1b,
    // {     |     }     ~
    0x46, 0x30, 0x70, 0x01
};

void SevenSegLed::put_strings(const char *data)
{
    for(uint32_t i = 0; i < num; i++) {
        char c = *(data + i);
        if (c <= OFFSET) {          // control charcters
            seg[num -1 - i] = 0;
        } else if ( c > '~') {      // over '~' characters
            seg[num -1 - i] = 0;
        } else {                    // serach table
            seg[num -1 - i] = alphabet_7seg[c - OFFSET];
        }
    }
    spi_out();
}