0
votes

I am having trouble with reading data sent from my laptop to the microcontroller via UART. The transmitting part works fine - I can send data to my laptop without problems, but echoing data, or reading keyboard input data from the laptop doesn't work. I have tried to implement reading both with polling and with Rx interrupt routines, but without success. The microcontroller I am using is ATMEGA2560, and I am conntected to my laptop via FTD1232 USB to TTL serial converter.

I am using Putty as a serial comm terminal, and the Arduino IDE for programming.

I am assuming that the problem is not in the hardware based on the following - I have tried initializing different USARTs and tried to use different COM ports, as well as another USB to TTL converter, various wires, but the result is the same. I have also connected another power source to supply enough voltage to all devices.

I am trying to get at least a response by turning a LED on when Rx interrupt occurs (when I type something in the terminal).

~

#define F_CPU 16000000UL //16MHz
#define BAUD 115200UL //bps
#define BAUD_PRESCALER (((F_CPU/(BAUD*8UL)))-1) //Table 101, page 212

volatile uint8_t temp;

void UART_init(){
  //Set baud rate
  UBRR0H = (uint8_t)(BAUD_PRESCALER >> 8); //Higher portion of the baud rate
  UBRR0L = (uint8_t)BAUD_PRESCALER; //Lower portion of the baud rate

  //Enable Receiver and Transmitter
  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  //Set frame format: 8-bit format, 1 stop bit, no parity
  UCSR0C |= (3 << UCSZ00);
  UCSR0C &= ~(1 << USBS0); //clear for 1 stop bit

  //Set Double Speed Asynchronous mode
  UCSR0A |= (1 << U2X0);

  UCSR0B |= (1 << RXCIE0); //Enables interrupt rxc
}

uint8_t UART_getchar(){
  //Wait for RXC flag
  while(!(UCSR0A & (1 << RXC0))){};
  return UDR0;
}

//Arduino setup()
void setup(){
  pinMode(8, OUTPUT);
  UART_init();
  sei();
}

//Arduino loop()
void loop(){
  delay(500);
  UART_putchar('a');
}

ISR(USART0_RX_vect){
  temp = UDR0;
  digitalWrite(8, HIGH);
}

It is a lenghty post, but I tried to be specific and also post the whole code. The datasheet I am using for the ATMEGA2560 can be found here.

My Putty settings:

COM Port Settings

1
I assume you have verified your LED code already (i.e. can turn on/off at will). Have you tried recv in polled mode (i.e. don't use/rely on interrupt) to verify connectivity of all including the recv pin/wire? When polled works, then debug interrupt. I have checked your init and seems okay but I'd be happier if you used explicit assignment instead of OR/AND. Ensure you're not setting 9 bit mode by mistake [see page 219] Note that the 3rd USCZ bit is in UCSRB [and not UCSRC like the lower two]. And, see register bit definitions starting on page 227. Crosscheck .h against doc.Craig Estey
Arduino is not C! See How to Ask and provide a minimal reproducible example, not just snippets.too honest for this site
Pick one: polling or RX ISR. And don't forget Arduino Serial is using ISRs too.KIIV
@CraigEstey the LED is working as it should. The only functions that are working are the putchar and putstring functions. The recv in polled isn't showing signs of life at all - same as with interrupt.soundonly01

1 Answers

0
votes

I've just tested it on my Mega board and it's working fine without interrupts enabled (simple loopback):

#define BAUD 115200UL
#define BAUD_PRESCALER (((F_CPU/(BAUD*8UL)))-1)

volatile uint8_t temp;

void UART_init(){
  //Set baud rate
  UBRR0H = (uint8_t)(BAUD_PRESCALER >> 8); //Higher portion of the baud rate
  UBRR0L = (uint8_t)BAUD_PRESCALER; //Lower portion of the baud rate

  //Enable Receiver and Transmitter
  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  //Set frame format: 8-bit format, 1 stop bit, no parity
  UCSR0C |= (3 << UCSZ00);
  UCSR0C &= ~(1 << USBS0); //clear for 1 stop bit

  //Set Double Speed Asynchronous mode
  UCSR0A |= (1 << U2X0);
//  UCSR0B |= (1 << RXCIE0); //Enables interrupt rxc
}

uint8_t UART_getchar(){
  //Wait for RXC flag
  while(!(UCSR0A & (1 << RXC0))){};
  return UDR0;
}

void UART_putchar(uint8_t data){
  //Do nothing until UDR is ready
  while(!(UCSR0A &(1 << UDRE0))){};
  UDR0 = data;
}

void UART_putstring(uint8_t *data){
  while(*data != 0x00){
    UART_putchar(*data);
    data++;
  }
}

//Arduino setup()
void setup(){
  pinMode(8, OUTPUT);
  UART_init();
  sei();
}

//Arduino loop()
void loop(){
  UART_putchar(UART_getchar());
}

/*ISR(USART0_RX_vect){
  temp = UDR0;
  digitalWrite(8, HIGH);
}*/

RX interrupt must be disabled, otherwise Serial interrupt vector is taking place and polled get char can't work as characters are readed by ISR