我有一个简单的示例,其中我将 UART0 配置为在 RX 和 TX 上中断。
TX 中断工作得很好,但无论我放入什么,RX 中断处理程序都会挂起。
如果我删除中断处理程序,那么它会正确崩溃。如果我关闭中断,它就不会再挂起。一旦我打开中断并添加 ISR,它就会在接收字符时挂起。然后看门狗重置设备。
我检查了 Arduino Core 实现,看不到他们正在做而我没有做的任何事情。
有什么想法吗?
/* USART Interrupts */
#define USART_RX_vect __vector_18
#define USART_UDRE_vect __vector_19
#define USART_TX_vect __vector_20
void usart_init_hardware(USART_CONFIG_T cfg)
{
usart_set_mode(cfg.mode);
usart_set_baud(cfg.baud);
usart_set_parity(cfg.parity);
usart_set_stop_bits(cfg.stop_bits);
usart_set_character_size(cfg.character_size);
if (USART_MODE_SYNCHRONOUS == cfg.mode) {
/* This bit is used for synchronous mode only.
* - ATmega328P Datasheet page 162 */
usart_set_clock_polarity(cfg.clock_polarity);
}
/* Enable interrupts on RX and TX */
UCSR0B.bits.RXCIEn = TRUE;
UCSR0B.bits.TXCIEn = TRUE;
UCSR0B.bits.UDRIEn = FALSE;
/* Enable TX and RX */
UCSR0B.bits.RXENn = TRUE;
UCSR0B.bits.TXENn = TRUE;
}
ISR(USART_RX_vect)
{
volatile U8_T c;
/* Clear interrupt flag */
c = UDR0.byte;
}
我尝试从 ISR 中删除所有内容,这应该会因重复调用中断而导致挂起。
然后我将
UDR0
检索添加回 ISR,这应该可以解决挂起问题,因为它会禁用中断标志。
我尝试手动禁用中断标志。
似乎没有什么可以治愈挂起。
UDR0
是映射到 0xC6
的并集
typedef union {
struct {
VBOOL_T bit0 : 1;
VBOOL_T bit1 : 1;
VBOOL_T bit2 : 1;
VBOOL_T bit3 : 1;
VBOOL_T bit4 : 1;
VBOOL_T bit5 : 1;
VBOOL_T bit6 : 1;
VBOOL_T bit7 : 1;
} bits;
VU8_T byte;
} REGISTER_T;
extern volatile REGISTER_T UDR0;
和
SECTIONS
{
/* USART */
UCSR0A = 0xC0;
UCSR0B = 0xC1;
UCSR0C = 0xC2;
UBRR0 = 0xC4;
UDR0 = 0xC6;
...
问题是我用
interrupt
而不是 signal
来定义 ISR。我仍在研究这种差异的含义,但据我所知,它与禁用入口时的全局中断有关。
#define ISR(vect) \
void vect(void) __attribute__((interrupt, used, externally_visible)); \
void vect(void)
应该是
#define ISR(vect) \
void vect(void) __attribute__((signal, used, externally_visible)); \
void vect(void)