4
\$\begingroup\$

I'm trying to send two commands to my raspberry over serial. I have the following code:

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

#define F_CPU 8000000UL
#define BAUD  9600

int main( void ) 
{
    // BAUD RATE (bits per second)
    UBRR0 = ( ( F_CPU / 8 / BAUD ) - 1 ); // 01100111

    // CONFIGURATION REGISTERS
    UCSR0B = 0b00001000; // enable transmitter (TXEN0)
    UCSR0C = 0b00000110; // set 8-bit data frame size  

    char buf[2][222] = 
            {
                { "AT" },
                { "AT+CWSAP=\"AVRAP\",\"abcd\",11,0" }
            };

    int i = 0;
    int x = 0;

    while( 1 )
    {

        if( x == sizeof( buf ) )
        {
            break;
        }

        if( i<strlen( buf[ x ] ) )
        {
            UDR0 = buf[x][i];
            i++;
        }
        else
        {
            UDR0 = 13;
            UDR0 = 10;
            x++;
            i = 0;

            _delay_ms( 10000 );
        }


        _delay_ms( 50 );
    }

    return 0;
}

And I'm using the following makefile:

CC=/usr/bin/avr-gcc
MEGA=328p
CFLAGS=-g -Os -Wall -mcall-prologues -mmcu=atmega$(MEGA)
OBJ2HEX=/usr/bin/avr-objcopy 
PROG=/usr/bin/avrdude
TARGET=serial

program : $(TARGET).hex
        $(PROG) -c avrispv2 -p m$(MEGA) -P /dev/ttyACM0 -e -U lfuse:w:0xe2:m -U hfuse:w:0xd9:m
        $(PROG) -c avrispv2 -p m$(MEGA) -P /dev/ttyACM0 -U flash:w:$(TARGET).hex

%.obj : %.o
        $(CC) $(CFLAGS) $< -o $@

%.hex : %.obj
        $(OBJ2HEX) -R .eeprom -O ihex $< $@

clean :
        rm -f *.hex *.obj *.o

Note that I'm setting the fuses to use internal clock, so it should run at 8Mhz:

-U lfuse:w:0x62:m

The CPU speed is defined as 8Mhz the BAUD rate is set to 9600, but when I run the following command on my raspberry, all I see is junk:

picocom /dev/ttyAMA0 -b 9600


picocom v1.7

port is        : /dev/ttyAMA0
flowcontrol    : none
baudrate is    : 9600
parity is      : none
databits are   : 8
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv
imap is        : 
omap is        : 
emap is        : crcrlf,delbs,

Terminal ready
�`�怘��`枆�~������▒�x�x�x�x�x�x�▒��▒�x�x�x�▒������怘�

I don't want to run the micro-controller with external oscillator, can I still use the serial communication at slow rates without using it?

\$\endgroup\$
  • 1
    \$\begingroup\$ Well, what is the garbage? You're only showing a broken UTF-8 version. \$\endgroup\$ – pipe Sep 27 '16 at 20:14
  • 1
    \$\begingroup\$ That's exactly how I see it in the terminal. are you referring to hex dump of the output? \$\endgroup\$ – 0x29a Sep 27 '16 at 20:17
  • \$\begingroup\$ Yes, you can't debug anything from that output. If you don't have an oscilloscope, you have to find at least some way to identify if it's a baud rate issue or not. \$\endgroup\$ – pipe Sep 27 '16 at 20:21
  • \$\begingroup\$ You can't work with embedded systems development without an oscilloscope. You would find the problem in less than a minute if you just measure the baudrate. \$\endgroup\$ – Lundin Sep 28 '16 at 11:30
  • \$\begingroup\$ @Lundin if I added an oscilloscope, how would I measure the baud rate coming from the micro-controller? Can Linux detect that? \$\endgroup\$ – 0x29a Sep 28 '16 at 11:59
10
\$\begingroup\$

Your issue is that you are calculating the baud rate divisor for "double speed mode" but you are neglecting to enable that mode by setting bit 1 of UCRS0A, which defaults to 0. This means that the UART bad divider is operating in single speed mode, for which your divisor value is twice what it should be. Thus your serial port operates at half the intended speed.

You should either:

  • Divide by 16 in your divisor calculation and leave/set UCRS0A bit 1 at the reset default of cleared.

  • Divide by 8 in your divisor calculation and explicitly set bit 1 of UCRS0A.

\$\endgroup\$
3
\$\begingroup\$

Strangely changing BAUD rate to 4800 in Linux terminal solved the problem:

picocom /dev/ttyAMA0 -b 4800
picocom v1.7

port is        : /dev/ttyAMA0
flowcontrol    : none
baudrate is    : 4800
parity is      : none
databits are   : 8
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv
imap is        : 
omap is        : 
emap is        : crcrlf,delbs,

Terminal ready
AT
AT+CWSAP="AVRAP","abcd",11,0

I guess the fuses are setting the ATMEGA to run at 4MHZ not 8MHZ.

\$\endgroup\$
  • 1
    \$\begingroup\$ The problem is not the clock, but misconfiguration of the UART. \$\endgroup\$ – Chris Stratton Sep 27 '16 at 20:31
  • 4
    \$\begingroup\$ Though testing baud rates off by a power of two was indeed great debugging instinct! \$\endgroup\$ – Chris Stratton Sep 27 '16 at 21:36

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.