【发布时间】:2012-09-02 08:06:28
【问题描述】:
我的平台是 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;
}
}
}
我很确定通过 Timer2(不是上述代码的一部分)对 UART0 寄存器和计时进行的初始化是正确的,因为我可以使用阻塞功能:
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;
有人在我的设计中发现了试图使用中断的缺陷吗?或者,有人有这方面的示例代码吗?谢谢!非常感谢 jszakmeister,他回答了我关于读取 TCNT 寄存器的问题。
【问题讨论】:
-
如果我的回答有帮助,如果您接受,我将不胜感激。
-
亲爱的 Jeff,我有 ATmega128CAN 和其他 ATMEL 芯片的代码可以解决这个问题(你可以在我的网站上找到代码卫星/Cansat)。不幸的是,您对我的情况的回答中的代码“翻译”不会导致我从我的代码中得到任何其他行为:字符发送得太快。你知道如何修复我的示例代码吗?你只是说“最大的缺陷”,但只要我禁用中断,共享变量是完全安全的......我将再花一个周末试图找出我的代码有什么问题:计数中断调用等......
-
告诉我更多关于您的问题....字符的速度只能与波特率一样快,还是您需要添加字符间延迟?
-
问题是UART0_tx_available的更新位置
-
在我的世界里,禁用中断是不行的。
标签: microcontroller interrupt 8051 uart