My platform is the c8051F120 microcontroller. I would like to send (= tx) bytes via UART0 using interrupts. So far, my project is as follows:
#define UART0_TX_SIZE 16 char UART0_tx[UART0_TX_SIZE]; short UART0_tx_uart = 0; short UART0_tx_main = 0; short UART0_tx_available = 0; void UART0_putChar(char value) { char SAVE_SFRPAGE; bit EA_SAVE = EA; // potentially blocking code while (UART0_tx_available == UART0_TX_SIZE) ; // disable interrupts EA = 0; EA = 0; if (UART0_tx_available) { UART0_tx[UART0_tx_main] = value; ++UART0_tx_main; if (UART0_tx_main == UART0_TX_SIZE) UART0_tx_main = 0; ++UART0_tx_available; } else { SAVE_SFRPAGE = SFRPAGE; SFRPAGE = UART0_PAGE; SBUF0 = value; SFRPAGE = SAVE_SFRPAGE; } // reenable if necessary EA = EA_SAVE; } // (return void works for other interrupts) void UART0_Interrupt() interrupt (4) { if (RI0 == 1) { RI0 = 0; } if (TI0 == 1) { // cause of interrupt: previous tx is finished TI0 = 0; // Q: Should this clear tx interrupt flag be further down? if (SSTA0 & 0x20) { // Errors tx collision SSTA0 &= 0xDF; } if (UART0_tx_available) { // If buffer not empty --UART0_tx_available; // Decrease array size SBUF0 = UART0_tx[UART0_tx_uart]; //Transmit ++UART0_tx_uart; //Update counter if (UART0_tx_uart == UART0_TX_SIZE) UART0_tx_uart = 0; } } }
I am sure that the initialization regarding the UART0 registers and synchronization via Timer2 (not part of the above code) is correct, because I can use the lock function:
char putchar_Blocking(char value) { char SFRPAGE_SAVE = SFRPAGE; SFRPAGE = UART0_PAGE; while (!TI0) // while TI0 == 1 wait for transmit complete ; TI0 = 0; SBUF0 = value; SFRPAGE = SFRPAGE_SAVE; return value; }
When I want to switch to interrupt design, of course, I also set
ES0 = 1;
Does anyone find a flaw in my design that is trying to use interupt? Or does anyone have some sample code for this? Thanks! And a big cry for jszakmeister that answered my question regarding reading the TCNT register.
source share