0

This is a simple usart program in avr c which just transmits a character.

#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 16000000UL
#define BAUD 9600 
#define BAUD_PRESCALLER ((F_CPU / (BAUD * 16UL)) - 1)
void send_val(unsigned char);
int main() {


UBRR0H = (uint8_t)(BAUD_PRESCALLER>>8);
UBRR0L = (uint8_t)(BAUD_PRESCALLER);
UCSR0B = (1<<TXEN0);
unsigned char x = 'B';
while(1) {

    send_val(x);
    _delay_ms(1000);
}

return 0;
}

void send_val(unsigned char v) {
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = v;

}

when I upload this code via the Arduino IDE, everything is fine and the code works as expected.The LED labeled "L" on the PCB is still.

but, when I upload the code using the following Makefile, the code uploads successfully but the outcome is unexpected. I see a weird character(see EDIT) and the LED "L" blinks a couple of times in that 1 sec delay.

CC=avr-gcc
OBJCOPY=avr-objcopy

CFLAGS=-Os -DF_CPU=16000000UL -mmcu=atmega328p
PORT=/dev/ttyACM0

led.hex: led.elf
    ${OBJCOPY} -O ihex -R .eeprom led.elf led.hex

led.elf: led.o
    ${CC} -o led.elf led.o

install: led.hex
    avrdude -F -V -c arduino -p ATMEGA328P -P ${PORT} -b 115200 -U flash:w:led.hex

I referred the Schematics and the led is connected to SCK but I don't understand why the makefile is causing it to trigger. that blinking of LED is what I think is causing the issue. Does the IDE have some other specific flags while uploading the code or am I committing some silly mistake?

EDIT: I wrote a small program to see the values in the device node /dev/ttyACM0. the ASCII value of the weired character(looks like a question mark) is actually 255.

another issue I noticed is that when I touch the solder beneath the pin 13 (only pin 13) the led L goes off!

As led L is connected to pin 13 I thought this is some hardware issue with my board but then I uploaded the blink led example code, touched the solder and everything is fine.

what could be the actual issue? this is getting mysterious.

1
  • The LED issue is normal and has already been covered here. Short answer: it's powered by an op-amp with an input that is floating unless you pinMode(LED_BUILTIN, OUTPUT);. Commented Aug 11, 2017 at 13:37

1 Answer 1

1

The -mmcu=atmega328p compiler flag is needed not only for the compile phase, but also for the link phase. Otherwise the linker will not know which CRT (C run time) to link with your program, and it will link none. The CRT is responsible for things like initializing the stack pointer, clearing r1 (as required by the AVR calling convention) and calling your main().

Edit: the following simplified Makefile should work if you have a modern version of avrdude that understands ELF files:

CC     = avr-gcc
MCU    = atmega328p
CFLAGS = -Os -DF_CPU=16000000UL -mmcu=${MCU}
PORT   = /dev/ttyACM0

led.elf: led.c
    ${CC} ${CFLAGS} $< -o $@

install: led.elf
    avrdude -c arduino -p ${MCU} -P ${PORT} -b 115200 -U $<

Otherwise you can keep your rules for led.elf → led.hex → install.

5
  • can you show the exact line I need to add to the makefile. thanks.
    – YsK
    Commented Aug 11, 2017 at 13:29
  • using this makefile, the upload succeeded as usual but the issue is still not resolved. I have avrdude version 6.2
    – YsK
    Commented Aug 11, 2017 at 13:39
  • @YsK: delete led.elf before typing make, otherwise make will just re-upload the old faulty led.elf. Commented Aug 11, 2017 at 13:41
  • i noticed that the led still goes off when i touch the solder of pin 13. only for this program..when i try the sample blink program it works fine. is something wrong with my code?
    – YsK
    Commented Aug 11, 2017 at 13:53
  • oh sorry, i didn't notice the comment about floating node. thanks for the help
    – YsK
    Commented Aug 11, 2017 at 13:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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