0
\$\begingroup\$

I am learning about AVR programming via the "Learning AVR Programming". Going through chapter Serial Communication, I am stuck with a small issue.

The setup is like this: enter image description here

The AVR Pins: enter image description here I am using the depicted FTDI cable and connected it with my mac. I can connect successfully with my serial terminal on my mac via the cable. When hitting a button on the keyboard, I see the TX signal sent in my terminal, but the RX is not sending.

Then I thought it might be the cable. So I connected the TX cable directly to the RX pin in the FTDI cable to loop back and it successfully works. I also switched the cable on for the RX Pin to another one without results.

Even the initial code "hello world" is not displayed on the terminal so the RX is not working. Can someone help me here please?

Update Sam, you were right. The code was not correctly sent to the ATMega. So now the program starts but the output is weired. Instead of "Hello World!" I receive this output on the screen: enter image description here

The code stayed the same, but the output looks not like what I expected?

The code is this:

// ------- Preamble -------- //
#include <avr/io.h>
#include <util/delay.h>
#include "pinDefines.h"
#include "USART.h"

int main(void) {
  char serialCharacter;

  // -------- Inits --------- //
  LED_DDR = 0xff;                            /* set up LEDs for output */
  initUSART();
  printString("Hello World!\r\n");                          /* to test */

  // ------ Event loop ------ //
  while (1) {

    serialCharacter = receiveByte();
    transmitByte(serialCharacter);
    LED_PORT = serialCharacter;
                           /* display ascii/numeric value of character */

  }                                                  /* End event loop */
  return 0;
}

The USART.c file contains:

#include <avr/io.h>
#include "USART.h"
#include <util/setbaud.h>

void initUSART(void) {                                /* requires BAUD */
  UBRR0H = UBRRH_VALUE;                        /* defined in setbaud.h */
  UBRR0L = UBRRL_VALUE;
#if USE_2X
  UCSR0A |= (1 << U2X0);
#else
  UCSR0A &= ~(1 << U2X0);
#endif
                                  /* Enable USART transmitter/receiver */
  UCSR0B = (1 << TXEN0) | (1 << RXEN0);
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);   /* 8 data bits, 1 stop bit */
}


void transmitByte(uint8_t data) {
                                     /* Wait for empty transmit buffer */
  loop_until_bit_is_set(UCSR0A, UDRE0);
  UDR0 = data;                                            /* send data */
}

uint8_t receiveByte(void) {
  loop_until_bit_is_set(UCSR0A, RXC0);       /* Wait for incoming data */
  return UDR0;                                /* return register value */
}


                       /* Here are a bunch of useful printing commands */

void printString(const char myString[]) {
  uint8_t i = 0;
  while (myString[i]) {
    transmitByte(myString[i]);
    i++;
  }
}

void readString(char myString[], uint8_t maxLength) {
  char response;
  uint8_t i;
  i = 0;
  while (i < (maxLength - 1)) {                   /* prevent over-runs */
    response = receiveByte();
    transmitByte(response);                                    /* echo */
    if (response == '\r') {                     /* enter marks the end */
      break;
    }
    else {
      myString[i] = response;                       /* add in a letter */
      i++;
    }
  }
  myString[i] = 0;                          /* terminal NULL character */
}

void printByte(uint8_t byte) {
              /* Converts a byte to a string of decimal text, sends it */
  transmitByte('0' + (byte / 100));                        /* Hundreds */
  transmitByte('0' + ((byte / 10) % 10));                      /* Tens */
  transmitByte('0' + (byte % 10));                             /* Ones */
}

void printWord(uint16_t word) {
  transmitByte('0' + (word / 10000));                 /* Ten-thousands */
  transmitByte('0' + ((word / 1000) % 10));               /* Thousands */
  transmitByte('0' + ((word / 100) % 10));                 /* Hundreds */
  transmitByte('0' + ((word / 10) % 10));                      /* Tens */
  transmitByte('0' + (word % 10));                             /* Ones */
}

void printBinaryByte(uint8_t byte) {
                       /* Prints out a byte as a series of 1's and 0's */
  uint8_t bit;
  for (bit = 7; bit < 255; bit--) {
    if (bit_is_set(byte, bit))
      transmitByte('1');
    else
      transmitByte('0');
  }
}

char nibbleToHexCharacter(uint8_t nibble) {
                                   /* Converts 4 bits into hexadecimal */
  if (nibble < 10) {
    return ('0' + nibble);
  }
  else {
    return ('A' + nibble - 10);
  }
}

void printHexByte(uint8_t byte) {
                        /* Prints a byte as its hexadecimal equivalent */
  uint8_t nibble;
  nibble = (byte & 0b11110000) >> 4;
  transmitByte(nibbleToHexCharacter(nibble));
  nibble = byte & 0b00001111;
  transmitByte(nibbleToHexCharacter(nibble));
}

uint8_t getNumber(void) {
  // Gets a numerical 0-255 from the serial port.
  // Converts from string to number.
  char hundreds = '0';
  char tens = '0';
  char ones = '0';
  char thisChar = '0';
  do {                                                   /* shift over */
    hundreds = tens;
    tens = ones;
    ones = thisChar;
    thisChar = receiveByte();                   /* get a new character */
    transmitByte(thisChar);                                    /* echo */
  } while (thisChar != '\r');                     /* until type return */
  return (100 * (hundreds - '0') + 10 * (tens - '0') + ones - '0');
}
\$\endgroup\$
14
  • 1
    \$\begingroup\$ I only have this picture from the book, but added the pin layout \$\endgroup\$
    – sesc360
    Commented Nov 14, 2016 at 20:01
  • 3
    \$\begingroup\$ @sesc360 - As I understand your info, rather than interpreting that no Rx data (i.e. data from the ATMega) is being received by your Mac, I think the cause could be simply that your firmware on the ATMega isn't running at all. This might be for the reason that Bence Kaulics has kindly highlighted, or for another reason. Have you considered the "no code running" possibility? Have you run any tests to eliminate this possibility (e.g. by running a successful simple flashing LED program)? \$\endgroup\$
    – SamGibson
    Commented Nov 14, 2016 at 20:43
  • 2
    \$\begingroup\$ A common cure for serial communications problems is: Exchange the TX and RX connections. Does your FTDI cable use RS-232 levels or "TTL" levels? You need "TTL" levels to connect directly to the ATMega. \$\endgroup\$ Commented Nov 14, 2016 at 20:45
  • 2
    \$\begingroup\$ Also some baud rates might be too fast for the tolerance of the internal oscillator. \$\endgroup\$
    – Wesley Lee
    Commented Nov 14, 2016 at 21:16
  • 2
    \$\begingroup\$ @PeterBennett the quasi-standard five pin FTDI cable header is logic level, not RS232. And the TX/RX connections are shown correctly connected. \$\endgroup\$ Commented Nov 14, 2016 at 21:59

0

Browse other questions tagged or ask your own question.