UART RX Interrurpt fired too early

593 views Asked by At

I'm doing a small project, where I want to transmit a text via a cable to my Atmega328p.
I first created the project on an Arduino Uno (with pure C), where the transmission works.
Now I switched to a standalone 328p and tried it there.

But now the Problem is, that my RX-Complete Interrupt is fired too early. In fact it is even fired, when nothing has been transmitted. It will fired when I just touched the cable (the isolated parts) .

#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
}

Edit: Picture of my Setup:

My Setup

I use the Arduiono just for Powering my Breadboard. 5V and GND are connected. The AVR MKII ISP is Connected via some Pins to flash the µC. The two cables are used for UART RX.
The Pushbutton is just for RESET

Edit 2: I just tried to power it via an external source and a raspberrypi. There is the same effect everywhere

3

There are 3 answers

2
Mike Armstrong On

Without looking at your setup it's hard to tell what's going wrong, but if you're touching an isolated cable and getting a response from the processor, then I would check common grounds between the devices if you're powering the ATMega via a battery, make sure the battery ground is touching the device that's receiving and transmitting, as any potential difference in power levels could cause the little magnetic field that you give off to be amplified into something that the core registers as a high bit.If possible, post a picture of your setup!

Also when programming with ATMel chips, burning the arduino bootloader and going the simple(r) C code way never hurt.

1
Rev On

The Rx line should not be floating. Its a high impedance input and should be driven to a specific level. Your cables act like an antenna and if you touch the cable it gets worse because there is capacitive coupling between the cable and your body. This may result in high frequency noise on your input which may trigger the Rx interrupt.

Further make sure that the 328p local power supply is properly decoupled. I don't see any capacitors near the controller on your breadboard. Check GND connection between Arduino and 328p (mandatory).

2
AterLux On

Of course. RXC flag is set when there are unread data in the receive buffer. This flag is used to generate the RX interrupt. Since you never read UDR inside your interrupt, this flag remains set, and, therefore just after interrupt routine is completed, it is starts again. And again. And again....