OSL10564_74HC595

Fork of OSL10564_74HC595 by Kenji Arai

Revision:
0:3373357a49f4
Child:
1:a3755014b7f1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/7segLed_HC595.cpp	Mon Jan 22 10:23:24 2018 +0000
@@ -0,0 +1,230 @@
+/*
+ * Mbed Library / Akizuki 7-segment LED driver [OSL10564-74HC595-x]
+ *  http://akizukidenshi.com/catalog/g/gM-12643/
+ *
+ * Copyright (c) 2018 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created:    January    7th, 2018
+ *      Revised:    January   22nd, 2018
+ */
+
+#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();
+}