0

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');
}
sesc360
  • 297
  • 4
  • 12
  • I think you accidentally deleted the img URL. Setup image is not showing up. – Wesley Lee Nov 14 '16 at 19:54
  • Please add a schematic instead breadboard image. I think no one knows the pinout of the Atmeg328, so currently it is just useless, pretty picture. – Bence Kaulics Nov 14 '16 at 19:58
  • 1
    I only have this picture from the book, but added the pin layout – sesc360 Nov 14 '16 at 20:01
  • 1
    First, connect all GND pin of the module to GND, pin 22 is unconnected. Connect AVCC, pin 20 as well to supply voltage. – Bence Kaulics Nov 14 '16 at 20:40
  • 3
    @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)? – SamGibson Nov 14 '16 at 20:43
  • 2
    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. – Peter Bennett Nov 14 '16 at 20:45
  • 2
    Also some baud rates might be too fast for the tolerance of the internal oscillator. – Wesley Lee Nov 14 '16 at 21:16
  • 2
    @PeterBennett the quasi-standard five pin FTDI cable header is logic level, not RS232. And the TX/RX connections are shown correctly connected. – Chris Stratton Nov 14 '16 at 21:59
  • @SamGibson - You were right! The code was not running. But now I get some strange output delivered on the screen. I updated the question. – sesc360 Nov 16 '16 at 10:53
  • 1
    @sesc360 - Thanks for the update. As you have now [opened a new question about your incorrect serial output](http://electronics.stackexchange.com/questions/269658/serial-output-returns-wrong-ascii), it would be a waste of time to duplicate effort replying to that new problem here. – SamGibson Nov 16 '16 at 12:51
  • yes I agree. I thought it would be more a new topic – sesc360 Nov 16 '16 at 12:52
  • @sesc360 - To help to make this question have some reusable knowledge for others in future, please can you explain how you fixed this original "no code running" problem? If it was the unconnected power pins issue highlighted by *Bence Kaulics*, for example, then he should get the credit and readers in future might solve their own problems, once the original cause in your case is clear. Thanks. – SamGibson Nov 16 '16 at 13:11
  • 1
    Actually I used a plugin for sublime using the crossavr package. that didnt properly run the code. then I switched to avrdude in terminal directly and the code was running – sesc360 Nov 16 '16 at 14:08
  • 1
    @sesc360 - Thanks for that update (you could write that fix in an answer on this question!). Even so, the earlier comment from *Bence* is completely correct and those missing power connections should be added, even if your circuit *appears* to work without them - strange behaviours may sometimes be seen otherwise. Assuming that your image of the breadboard is from the book, it is disappointing they seem to be giving you an unreliable circuit to use. :-( This previous topic about [minimum ATMega328P circuits](http://electronics.stackexchange.com/q/53713) may also be useful for you. Good luck. – SamGibson Nov 16 '16 at 15:24

0 Answers0