2
\$\begingroup\$

On ATMEGA168PA I have problems with interrupt-driven character reception over UART. When I include the line setup_interrupt() it seems that program execution stops after one iteration in the while-loop (one blink and one "HOWDY"). Optionally it executes continuous interrupts.

The uC stops in the sense that it appears not to be doing anything. No blink. No "HOWDY" sent out on the UART.

The UART works. I have verified that it can send and receive characters (receive using polling).

Same interrupt-driven reception worked well on ATMEGA64.

What can possibly cause the program to stop execution? Any help appreciated.

#include "project.h"
#include "drivers.h"
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "uart.h"
#include "util.h"
#include "leds.h"

// Parameters for serial port
#define BAUD            2400
#define MYUBRR          F_CPU/16/BAUD-1

// Parameters for menu
volatile char action             = 0;

// Global debug flag
uint8_t           debug_global   = 1;

int main(void)
{
   setup_portb();
   green_off();
   cli();
   uart_init( MYUBRR );
   setup_interrupt();
   while ( 1 )
   {
      blink_025_sec();
      UART_sendLine("HOWDY!");
   }
}

ISR( USART_RX_vect )
{
   blink_05_sec();
   char receivedByte;
   receivedByte = UDR0;           // Fetch the received byte value into the variable "ByteReceived"
   if ( debug_global )
   {
      UART_sendChar( receivedByte ); // Echo the received byte back to the computer
   }
   action = receivedByte;
}

void setup_interrupt()
{
   //EIMSK |= _BV(INT0);  // Enable INT0
   // Set Global interrupt ENABLE flag
   sei();
}

My UART init looks like this:

#include <avr/io.h>
#include "drivers.h"

void uart_init(unsigned int ubrr)
{
   // Set baud rate
   UBRR0H = (unsigned char)(ubrr>>8);
   UBRR0L = (unsigned char)ubrr;
   // Enable receiver and transmitter; enable RX interrupt
   UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
}

The execution stops even if there are no data on the UART RX line (no interrupt is triggered)? – Bence Kaulics 5 hours ago

-Yes. It does not react to incoming chars from the serial port.

UPDATE: The comment from "user57709" was the key: I commented out the line EIMSK |= _BV(INT0); // Enable INT0

That made the program work as expected. If I understand the data sheet correctly, there is no need to enable any external interrupts like this one when using the RXCIE flag in the UART. The specific pin is not connected to anything.

Apparently the uC got stuck executing continuous interrupts because of this.

Thanks for the help, "user57709"

\$\endgroup\$
  • \$\begingroup\$ The execution stops even if there are no data on the UART RX line (no interrupt is triggered)? \$\endgroup\$ – Bence Kaulics May 26 '16 at 7:53
  • \$\begingroup\$ My localised facial narcosis doesn't let me focus on enough code at once to really help, so I'll stick to pointing out that you'd be wise to put brackets around any defined constant that has maths going on inside it. Not having that habit will cost you hours of debugging some time in the future. (#define d stuff gets replaced by what's behind it, without brackets the total resulting operation may have a different outcome than you expect) \$\endgroup\$ – Asmyldof May 26 '16 at 8:17
  • 2
    \$\begingroup\$ You're enabling an external interrupt. What is connected to the INT0 pin? Is this triggering an interrupt? Do you have a handler for it? When you say it stops, what do you mean exactly? Do you mean that it just doesn't keep sending "HOWDY!"? Have you tried halting execution using the debugger? \$\endgroup\$ – user57709 May 26 '16 at 8:19
  • 1
    \$\begingroup\$ What does the blink_05_sec(); function code look like? Also, you should be checking the UART receive data flag before reading UDR0 otherwise if there is nothing in the buffer you will just spew out nonsense. Finally you really shouldn't be doing things like using delays and calling functions from an interrupt. \$\endgroup\$ – Tom Carpenter May 26 '16 at 12:52
  • 3
    \$\begingroup\$ In the edit, you've put quotation marks instead of brackets. Have you tried commenting-out the line that enables the external interrupt (EIMSK |= _BV(INT0);)? \$\endgroup\$ – user57709 May 26 '16 at 16:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.