Code for my numitron clock. Based on the STM32F042 and using a TLC5916 per numitron to drive them.

Dependencies:   SWSPI mbed-dev

Revision:
0:d1558f6f88bf
Child:
1:c80f72f7ee20
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Nov 12 08:25:50 2016 +0000
@@ -0,0 +1,167 @@
+#include "mbed.h"
+#include "SWSPI.h"
+
+SWSPI spi( PA_2, PA_1, PA_3 );                          // create the fake SPI port
+DigitalOut OE(PA_0);                                    // Output Enable
+DigitalOut LE(PA_4);                                    // The LE pin and the number of connected chips
+BusIn buttons(PA_5, PA_6, PA_7, PB_1);                  // The 4 user buttons
+// All the digits places in an array, 0-9.
+const uint8_t numbers[10] = {0x7B, 0x60, 0x57, 0x76, 0x6C, 0x3E, 0x3F, 0x70, 0x7F, 0x7E};
+
+// A flag to control the blinking dot.
+uint8_t flipflag = 1;
+
+// Struct that contains all the numitron values. 
+// Even if this clock only uses 4 numitrons, the struct is already prepared for 6.
+typedef struct
+    {
+        uint8_t second_right;
+        uint8_t second_left;
+        uint8_t minute_right;
+        uint8_t minute_left;
+        uint8_t hour_right;
+        uint8_t hour_left;
+    }clock_typ; 
+clock_typ numiclock;
+
+// Variables for getting time
+struct tm t;
+time_t rawtime;
+
+// Ticker to update the clock.
+Ticker secondticker; 
+void updatetime(void);
+
+int main() 
+{
+    static struct tm *t3;
+    buttons.mode(PullUp);
+
+    LE = 0;
+    OE = 1;
+
+    // Set the time on 00:00:00 @ 1 jan 2016
+    t.tm_sec = 0;
+    t.tm_min = 0;
+    t.tm_hour = 0;
+    t.tm_mday = 1;
+    t.tm_mon = 1-1;
+    t.tm_year = 2016-1900;
+    set_time(mktime(&t));
+
+    // Clear the displays
+    spi.write(0x00);
+    spi.write(0x00);
+    spi.write(0x00);
+    spi.write(0x00);
+
+    // Toggle LE to latch in the values in the TLC5916
+    LE = 1;
+    wait_us(10);
+    LE = 0;
+    wait_us(10);
+
+    OE = 0;     // Enable the displays
+    secondticker.attach(&updatetime, 1);
+    
+    while( 1 )
+    {   // If any button is pressed and after 50ms still is pressed, count it as a press.
+        uint8_t bpressed = buttons;
+        wait_ms(50);
+        if((bpressed == buttons) && (bpressed != 0xf))
+        {
+            // Get the current time, see what button is pressed, update the time and use this as the new time.
+            rawtime = time(NULL);
+            t3 = localtime(&rawtime);
+            bpressed = (~bpressed)&0x0f;    // The buttons are high when unpressed, invert it to make the code a bit easier.
+            switch(bpressed)
+            {
+                case 0x01:                  // Button most left pressed, add 10 hours to the current time
+                    t3->tm_hour += 10;
+                    if(t3->tm_hour >= 30)   // Keep in mind that the maximum for hours is 23.
+                    {
+                        t3->tm_hour -= 30;
+                    }
+                    else if(t3->tm_hour >= 24)
+                    {
+                        t3->tm_hour -= 20;
+                    }
+                break;
+                case 0x02:                  // Button second left, add 1 hour
+                    t3->tm_hour += 1;
+                    if((t3->tm_hour%10) == 0)
+                    {
+                        t3->tm_hour -= 10;
+                    }
+                    else if(t3->tm_hour >= 24)
+                    {
+                        t3->tm_hour -= 4;
+                    }                       
+                break;
+                case 0x04:                  // Button second right, add 10 minutes
+                    t3->tm_min += 10;
+                    if(t3->tm_min >= 60)
+                    {
+                        t3->tm_min -= 60;
+                    }
+                break;  
+                case 0x08:                  // Button most right, add 1 minute.
+                    t3->tm_min += 1;
+                    if((t3->tm_min%10) == 0)
+                    {
+                        t3->tm_min -= 10;
+                    }
+                break;
+            }
+            set_time(mktime(t3));
+            flipflag = 0;                   // Update the display without the blinking dot.
+            updatetime();               
+            flipflag = 1;
+            wait_ms(150);                   // extra delay so a press is only seen once.
+        }
+    }
+}
+
+// When called this function retrieves the current time
+// and places this in the numiclock struct.
+// It then sends the data to the SPI bus to display the change
+void updatetime(void)
+{
+    static uint8_t flipbit;
+    static struct tm *t2;
+    rawtime = time(NULL);
+    t2 = localtime(&rawtime);
+
+    numiclock.second_right = t2->tm_sec%10;
+    numiclock.second_left = (t2->tm_sec - numiclock.second_right)/10;
+    numiclock.minute_right = t2->tm_min%10;
+    numiclock.minute_left = (t2->tm_min - numiclock.minute_right)/10;
+    numiclock.hour_right = t2->tm_hour%10;
+    numiclock.hour_left = (t2->tm_hour-numiclock.hour_right)/10;
+
+    spi.write(numbers[numiclock.hour_left]);
+    if(flipflag)
+    {
+        if(flipbit == 1)
+        {
+                spi.write((numbers[numiclock.hour_right])+0x80);
+                flipbit = 0;
+        }
+        else
+        {
+                spi.write(numbers[numiclock.hour_right]);
+                flipbit = 1;
+        }
+    }
+    else
+    {
+        spi.write(numbers[numiclock.hour_right]);
+    }
+    spi.write(numbers[numiclock.minute_left]);
+    spi.write(numbers[numiclock.minute_right]);
+        
+    LE = 1;
+    wait_us(10);
+    LE = 0;
+    wait_us(10); 
+}