Code for my numitron clock. Based on the STM32F042 and using a TLC5916 per numitron to drive them.
main.cpp
- Committer:
- riktw
- Date:
- 2016-11-12
- Revision:
- 0:d1558f6f88bf
- Child:
- 1:c80f72f7ee20
File content as of revision 0:d1558f6f88bf:
#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); }