// by Ido Gendel, 2020 // Share and enjoy! #include char msg[] = "Hello World! \n"; // Includes room for numbers const uint8_t lastDigitPos = 19; volatile char *cp; // Do not read directly - use millis() volatile uint32_t _millis = 0; const uint8_t DEBOUNCE_MS = 10; volatile uint8_t debounceMSLeft; uint8_t oldButtonState = 1; // This function is called immediately after reset, in SILABS_STARTUP.A51 void SiLabs_Startup (void) { // Disable watchdog WDTCN = 0xDE; WDTCN = 0xAD; } uint32_t millis(void) { uint32_t result; IE_EA = 0; // Disable interrupts result = _millis; IE_EA = 1; // Re-enable interrupts return result; } void setup(void) { P1MDOUT |= P1MDOUT_B4__PUSH_PULL; // Set built-in LED pin (P1.4) to push-pull output // Built-in button pin (P0.2) digital input by default // Weak pull-ups enabled by default. P0_B2 = 1;// Turn WPU on for button input // Default clock is internal 24.5MHz div 8 // As a default, timers 0/1 uses system clock div 12 prescaler TMOD |= TMOD_T1M__MODE2; // Set Timer1 mode to 8-bit auto-reload TH1 = 243; // Set reload value to produce OVF @19.2KHz TCON_TR1 = 1; // Enable timer1 TMOD |= TMOD_T0M__MODE1; // Set Timer0 mode to 16-bit TH0 = 0xFF; // Set Timer0 counter to overflow after 255 "ticks" TL0 = 0x01; TCON_TR0 = 1; // Enable timer0 // Enable UART in crossbar; TX pin (P0.4) will become output automatically XBR0 |= XBR0_URT0E__ENABLED; // Enable crossbar XBR2 = 0x40; IE_ET0 = 1; // Enable timer0 interrupt IE_ES0 = 1; // Enable UART0 interrupt IE_EA = 1; // Enable interrupts globally } void populateSecondsText(void) { uint8_t i = lastDigitPos; uint32_t s = millis() / 1000; do { msg[i--] = s % 10 + 48; s = s / 10; } while (s > 0); } int main (void) { setup(); for ( ; ; ) { if ((0 == debounceMSLeft) && (P0_B2 != oldButtonState)) { debounceMSLeft = DEBOUNCE_MS; oldButtonState = P0_B2; if (P0_B2) { P1_B4 = 0; // LED ON populateSecondsText(); cp = &msg[1]; SBUF0 = msg[0]; // Start UART transmission } } } } SI_INTERRUPT (TIMER0_OVF_ISR, TIMER0_IRQn) { // Interrupt flag is cleared automatically TH0 = 0xFF; // Reload counter value TL0 = 0x01; ++_millis; if (debounceMSLeft) { --debounceMSLeft; } } SI_INTERRUPT (UART0_ISR, UART0_IRQn) { // Transmit interrupt flag must be cleared in firmware: SCON0_TI = 0; // Anything left to transmit? (assuming null-terminated string) if (0 != *cp) { SBUF0 = *cp++; } else { P1_B4 = 1; // LED OFF } }