Search code examples
cmicrocontrolleravruartatmega

ATMEGA 2560 uart code not giving out correct output on minicom


#include <avr/io.h>
#include <util/delay.h>

#define BAUDRATE 115200
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

//Declaration of our functions
void USART_init(void);
unsigned char USART_receive(void);
void USART_send( unsigned char data);

int main(void){
USART_init();        //Call the USART initialization code

while(1){        //Infinite loop
 USART_send('A');
 _delay_ms(1000);        //Delay for 5 seconds so it will re-send the string every 5 seconds
 }

return 0;
}

void USART_init(void){

 UBRR1H = (uint8_t)(BAUD_PRESCALLER>>8);
 UBRR1L = (uint8_t)(BAUD_PRESCALLER);
 UCSR1B = (1<<RXEN1)|(1<<TXEN1);
 UCSR1C = (3<<UCSZ10);
}

unsigned char USART_receive(void){

 while(!(UCSR1A & (1<<RXC1)));
 return UDR1;

}

void USART_send( unsigned char data){

 while(!(UCSR1A & (1<<UDRE1)));
 UDR1 = data;

}

minicom on Ubuntu set to 115200 8N1

I am using Elegoo ATMEGA2560, TX1 and RX1 and GND pins from communication port. https://github.com/enthusiasticgeek/Elegoo_Mega_2560

I intend to send 'A' from ATMEGA and expect to see it on minicom on PC. But I am receiving ' _ ' on minicom. I changed the minicom setting to 115200 7N1 and still receiving ' _ '. Then I changed to 115200 6N1 then I get a different binary character. I tried changing minicom settings but to no avail. Any idea what I am going wrong?

This is what I am seeing when I send different characters.

Expected (AVR sends) ASCII 0x56 [01010110] (V)

Observed (PC receives) ASCII 0x2A [00101010] (*)

Expected (AVR sends) ASCII 0x41 [01000001] (A)

Observed (PC receives) ASCII 0x5F [01011111] (_)

Expected (AVR sends) ASCII 0x42 [01000010] (B)

Observed (PC receives) ASCII 0x2F [00101111] (/)

Expected (AVR sends) ASCII 0x55 [01010101] (U)

Observed (PC receives) ASCII 0x55 [01010101] (U)

Here are my fuse settings https://github.com/enthusiasticgeek/Elegoo_Mega_2560/blob/master/avrdude.conf

    memory "lfuse"
    size            = 1;
    write           = "1 0 1 0  1 1 0 0  1 0 1 0  0 0 0 0",
                      "x x x x  x x x x  i i i i  i i i i";

    read            = "0 1 0 1  0 0 0 0  0 0 0 0  0 0 0 0",
                      "x x x x  x x x x  o o o o  o o o o";
    min_write_delay = 9000;
    max_write_delay = 9000;
      ;

    memory "hfuse"
    size            = 1;
    write           = "1 0 1 0  1 1 0 0  1 0 1 0  1 0 0 0",
                      "x x x x  x x x x  i i i i  i i i i";

    read            = "0 1 0 1  1 0 0 0  0 0 0 0  1 0 0 0",
                      "x x x x  x x x x  o o o o  o o o o";
    min_write_delay = 9000;
    max_write_delay = 9000;
      ;

    memory "efuse"
    size            = 1;
    write           = "1 0 1 0  1 1 0 0  1 0 1 0  0 1 0 0",
                      "x x x x  x x x x  x x x x  x i i i";

    read            = "0 1 0 1  0 0 0 0  0 0 0 0  1 0 0 0",
                      "x x x x  x x x x  o o o o  o o o o";
    min_write_delay = 9000;
    max_write_delay = 9000;
;

Here is what happens when I load the fw

avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega2560 -c -o test.o test.c
avr-gcc -mmcu=atmega2560 test.o -o test
#EEPROM
#avr-objcopy -O ihex -R .eeprom test test.hex
#FLASH
avr-objcopy -O ihex -R .flash test test.hex
sudo avrdude -c wiring -p m2560 -P /dev/ttyACM0 -b 115200 -V -U flash:w:test.hex -D

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9801 (probably m2560)
avrdude: reading input file "test.hex"
avrdude: input file test.hex auto detected as Intel Hex
avrdude: writing flash (366 bytes):

Writing | ################################################## | 100% 0.08s

avrdude: 366 bytes of flash written

avrdude: safemode: Fuses OK (E:FD, H:D8, L:FF)

avrdude done.  Thank you.

Note: I am using CP-US-03 serial adapter which I assume would have FTD232 chip. I also get the same results from the Arduino sketch using the code

void setup() {

// initialize both serial ports:
Serial1.begin(115200);

}

void loop() {

// read from port 1, send to port 0:
//if (Serial1.available()) {
//  int inByte = Serial1.read();
//  Serial.write(inByte);
//
 }

// read from port 0, send to port 1:
//if (Serial1.available()) {
  int inByte = 0x41;//Serial.read();
  Serial1.write(inByte);
  delay(1000);
//}
}

Hence, now I have started to look if this is TTL or logic level conversion issue.


Solution

  • Turns out the problem was nothing related to my code. I ended up ordering the following USB 2.0 to TTL UART 6PIN CP2102 Module Serial Converter and everything was hunky dory.

    https://www.amazon.com/gp/product/B01LRVQIFQ/ref=oh_aui_detailpage_o01_s00?ie=UTF8&psc=1

    The regular USB to serial CP-US-03 wouldn't work.