Code for my numitron clock. Based on the STM32F042 and using a TLC5916 per numitron to drive them.
Diff: main.cpp
- 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); +}