0
\$\begingroup\$

My ATmega1284 MCU appears to behave strangely in a number of ways. I know, I'm nuts, but here it goes... I'm using a usbtiny AVR pocket programmer with avrdude on Ubuntu Linux 15.10. I am wondering if the MCU is failing.

  • If I try to use function prototypes with a function definition (the "test2" function), the compiler doesn't complain but appears to program the MCU, and the MCU will randomly seem to apply power at different pins on PORTD (from what I've seen). I'm not being specific because it does appear to be a specific problem.

  • For some reason when I've tried flashing an LED using the "_delay_ms();" function with "avr/io.h" included, everything will appear to compile fine, but no matter what value I pass in as a parameter, it doesn't seem to make a difference in the flashing speed of the LED whether it's 500 or 5000000. I've also tried change the value of F_CPU several times, but that didn't change anything.

  • Now, what I am specifically trying to do for kicks, is light up an LED on a 7 segment LED display with a single pin on port D to start, when I have continuity between PORTB1 and ground. But, again the compiler doesn't complain and it just acts strange. It almost doesn't seem to compile the if statement at times, and will just flash the single led very quickly regardless of the continuity on PINB1. I know, my explanation is stupid, and I would hate my explanation too if I were you, but I really don't know what to think.

Here's the code:

    #define F_CPU 6000000UL  // 6 MHz

    #include "avr/io.h"

    void test2(void);

    int main(void) {
        DDRB &= ~(1 << PINB1);
        PORTB |= 1 << PINB1;

        while (1) {
            if(bit_is_clear(PINB, 1)){
                DDRD |= (1 << PIND6);
                PORTD &= ~(1 << PIND6);
            } else {
                DDRD &= ~(1 << PIND6);
                PORTD |= (1 << PIND6);
            }
        }

        return 0;
    }

    void test2(void){
    }

Here's everything I'm doing to compile and program the MCU:

avr-gcc -O -mmcu=atmega1284 -c main.c -o main.o

avr-objcopy -j .text -j .data -O ihex main.o main.hex

sudo avrdude -c usbtiny -p m1284 -U flash:w:main.hex

EDIT:
Ok, I didn't understand how F_CPU worked... Thanks... I tried looking to the datasheet to see what frequency the MCU operates at by default and I couldn't find it, so I'm just going to skip that till I figure that out... Here's an example something else I tried. I just now tried deploying with this code and the led blinks quickly as expected:

    #include <avr/io.h> // AVR IO library

    //void test(void);

    int main(void) {
        DDRD |= (1 << PIND6); // set D6 (LED) to output
        while (1) {
        PORTD ^= (1 << PIND6); // toggle D6 (LED)
        }
        return 0; // never reached
    }

    //void test(void){
    //}

Then I try with the function prototype and definition uncommented as shown below and it stays on steadily:

    #include <avr/io.h> // AVR IO library

    void test(void);

    int main(void) {
        DDRD |= (1 << PIND6); // set D6 (LED) to output
        while (1) {
        PORTD ^= (1 << PIND6); // toggle D6 (LED)
        }
        return 0; // never reached
    }

    void test(void){
    }

I just don't get why there's so much inconsistency there... It makes me think there's either a problem with the MCU or the compiler

update:
Well, I just ditched the AVR and got a TI MSP430FR6989 and it's terrific! Love texas instruments! Good documentation, everything works as expected!

\$\endgroup\$
  • \$\begingroup\$ Do you have a pull-up resistor on your Port B input pin? If not, the pin value will be random when you are not grounding it. You should set the port D Data Direction Register just once, to make your desired output pin an output. \$\endgroup\$ – Peter Bennett Feb 19 '16 at 6:05
  • \$\begingroup\$ According to the datasheet, it appears that the MCU has pull-up resistors built in. Sorry I'm a noob, but it appears the pull up resistors are automatically activated when a pin is set to input... \$\endgroup\$ – Jeff Neufeld Feb 20 '16 at 6:20
  • \$\begingroup\$ Hmm. The function prototype misbehaviour is strange, I'll have to think about that. Does that first code snippet visibly blink? Without the delay call, it should be blinking very fast, so something's awry. In the meantime, what board are you using? The MCU operating frequency is likely set by a crystal on the board. If you can link to the board or a picture of it, I can help you figure it out. Or are you just putting it directly in a breadboard? \$\endgroup\$ – uint128_t Feb 20 '16 at 6:50
  • \$\begingroup\$ I'm just putting it on a breadboard, its just operating at whatever frequency the internal clock does by default and I haven't figured out what that is yet. Yes the first code does visibly blink but I'm guessing thats because something in the hardware of the LED is keeping it from blinking at the rate close the MCU speed (which obviously wouldn't be visible). \$\endgroup\$ – Jeff Neufeld Feb 20 '16 at 7:01
  • \$\begingroup\$ Either way, its the fact that it's visibly steady with a function, and blinks when its commented out that puzzles me. I read something about a compatibility mode fuse that can cause odd behavior but this chip doesn't appear to have anything like that... \$\endgroup\$ – Jeff Neufeld Feb 20 '16 at 7:02
2
\$\begingroup\$

First off, your statement

I've also tried change the value of F_CPU several times

makes me suspect you are misunderstanding F_CPU. To ensure sane operation, F_CPU must be set equal to your MCU clock frequency, i.e. you can't say #define F_CPU 6000000UL to make the MCU operate at 6MHz, you need a 6MHz clock source. Are you sure that your board uses a 6MHz clock? It's not the most common clock frequency (unless you're a USB keyboard, but I digress).

To isolate the issue, reduce your code a bit. A simple blinking program with no input would be appropriate. Also, there is no need to change the port direction constantly when blinking an LED, you can simply set it to output and leave it (in fact, this may be causing some weirdness). Oh, and #include "avr/io.h" doesn't seem quite right, it should be in your standard library headers. I'd suggest the following code:

#define F_CPU 6000000UL  // 6 MHz (is it really 6MHz)

#include <avr/io.h> // AVR IO library
#include <util/delay.h> // AVR busy wait delay loops

int main(void) {
    DDRD |= (1 << PIND6); // set D6 (LED) to output
    while (1) {
        PORTD ^= (1 << PIND6); // toggle D6 (LED)
        _delay_ms(250); // wait 250ms
    }
    return 0; // never reached
}

This is just about the simplest debugging "blink" code you can write, short of assembly. Try to get this working correctly, and then build on it from there.

\$\endgroup\$
  • \$\begingroup\$ Hey uint, I commented in the answer below. Thanks! \$\endgroup\$ – Jeff Neufeld Feb 20 '16 at 6:30

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.