私のプラットフォームは c8051F120 マイクロコントローラーです。割り込みを使用して UART0 経由で (=tx) バイトを送信したいと考えています。これまでの私のデザインは次のとおりです。
#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;
}
}
}
ブロッキング関数を使用できるため、UART0 レジスタと Timer2 を介したタイミング (上記のコードの一部ではない) に関する初期化が正しいと確信しています。
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;
}
もちろん、割り込み設計に切り替えたいときも設定します
ES0 = 1;
割り込みを使用しようとする私の設計の欠陥を誰かが見つけますか? または、このためのサンプルコードを持っている人はいますか? ありがとうございました!そして、TCNT レジスターの読み取りに関する私の質問に答えてくれた jzakmeister に大声で叫びました。