UART RX 中断过早触发
Posted
技术标签:
【中文标题】UART RX 中断过早触发【英文标题】:UART RX Interrurpt fired too early 【发布时间】:2015-06-11 14:48:14 【问题描述】:我正在做一个小项目,我想通过电缆将文本传输到我的 Atmega328p。 我首先在 Arduino Uno(使用纯 C)上创建了该项目,传输工作在那里。 现在我切换到独立的 328p 并在那里尝试。
但现在的问题是,我的 RX 完成中断被触发得太早了。事实上,它甚至会在没有传输任何内容时被触发。当我刚刚触摸电缆(隔离部分)时它会发射。
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/setbaud.h>
void setup(void)
CLKPR = 0;
//Set Output
DDRC |= (1 << PC0) | (1 << PC1) |(1 << PC2) |(1 << PC3) |(1 << PC4) | (1 << PC5);
DDRD |= (1 << PD6) | (1 << PD7);
// Interrupts
sei();
// Init UART
// Set baud
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
#if USE_2X
UCSR0A |= (1 << U2X0);
#else
UCSR0A &= ~(1 << U2X0);
#endif
// Enable UART Receive and Receivecomplete Interrupt
UCSR0B = (1<<RXEN0) | (1 << RXCIE0);
// Set frameformat to 8 Data and 1 Stopbit
UCSR0C = ((1<<UCSZ00)|(1<<UCSZ01));
int main(void)
setup();
while(1)
return 0;
ISR(USART_RX_vect)
// Enable some LEDs
编辑:我的设置图片:
我使用 Arduiono 只是为我的面包板供电。 5V 和 GND 连接。 AVR MKII ISP 通过一些引脚连接到闪存 µC。这两条电缆用于UART RX。 按钮仅用于 RESET
编辑 2:我只是尝试通过外部源和 raspberrypi 为其供电。到处都是一样的效果
【问题讨论】:
"nothing has been transmission" -- 你检查中断状态寄存器来确认中断源了吗?您检查 RX 状态寄存器是否有任何错误? 【参考方案1】:当然。当接收缓冲区中有未读数据时,设置 RXC 标志。 该标志用于产生 RX 中断。 由于您从未在中断中读取 UDR,因此该标志保持设置状态,因此在中断例程完成后,它会再次启动。然后再次。再说一遍......
【讨论】:
我实际上阅读了 URD,我只是把它漏掉了。但问题有点不同。并不是说 ISR 不会退出。问题是,即使没有传输任何内容,也会触发中断。 好的。然后检查 RX 引脚上的连接。如果连接不好,它可能会错误地检测到低电平(作为起始位)(在您的照片上,此引脚悬空,没有任何上拉)【参考方案2】:Rx 线不应浮动。它是一个高阻抗输入,应该被驱动到一个特定的电平。您的电缆就像天线一样,如果您触摸电缆,情况会变得更糟,因为电缆和您的身体之间存在电容耦合。这可能会导致您的输入出现高频噪声,从而触发 Rx 中断。
进一步确保 328p 本地电源正确解耦。我在面包板上的控制器附近没有看到任何电容器。检查 Arduino 和 328p 之间的 GND 连接(强制)。
【讨论】:
“随机”中断的问题似乎可以通过连接电缆来解决。但是我的 µC 仍然没有收到正确的文本。也许时钟是错误的,但我想我需要为此阅读文档。没错,没有任何电容器。我到底需要它们做什么?【参考方案3】:如果不查看您的设置,很难判断出了什么问题,但如果您触摸隔离电缆并从处理器获得响应,那么如果您通过以下方式为 ATMega 供电,我会检查设备之间的共同点电池,请确保电池接地接触正在接收和发送的设备,因为功率水平的任何电位差都可能导致您发出的小磁场被放大成核心记录为高位的东西。如果可能,张贴您的设置图片!
此外,在使用 ATMel 芯片进行编程时,烧录 arduino 引导加载程序并采用简单 (r) C 代码方式也不会受到伤害。
【讨论】:
我添加了图片和描述。 电位差实际上会产生电场,而不是磁场。缺少 GND 连接主要会由于缺少公共参考而不是由于耦合而导致逻辑电平偏移。以上是关于UART RX 中断过早触发的主要内容,如果未能解决你的问题,请参考以下文章