NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Code weird errors?

February 04, 2012
by wadaltmon
wadaltmon's Avatar

I have some code here, with a button attached to my ATMEGA168. INPIN is the button input, OUTPIN is the output by LED.

#include <avr/io.h>
#define INPIN (1<<PD2)
#define OUTPIN (1<<PB2)

void main(int)
    {
        int fp;
        fp = 0;
        int fd;
        fd = 0;
        int bt;
        bt = 0;
        int sp;
        sp = 0;
        int sd;
        sd = 1;
        DDRD &= ~(1<<PD2);
        DDRB |= (1<<PB2);
    }
while (1)
    {
        if (sd = 1) & (PIND & INPIN)
            {
                fp = fp + 1;
                sd = 0;
            }
        else
        if (11>fp>0) & (PIND & INPIN) & (fd = 0)
            {
                fd = 1;
            }
        else
        if (fp>10) & (fd = 0)
            {
                return 0;
            }
        else
        if (fd = 1) & (bt = 0) & !(PIND)
            {
                bt = bt+1;
            }
        else
        if (10>bt>0) & (PIND & INPIN)
            {
                PINB |= ((1<<PB2);
                sp = sp+1;
            }
        else
        if (sp > 0) & !(PIND)
            {
                PINB &= ~(1<<PB2);
                sd = 1;
                return 0;
            }
        else
            {
                return 0;
            }
        }

It gives me a few weird errors when I make it: 6: warning: return type of 'main' is not 'int' 6: 'main' takes only zero or two arguments IN function 'main': error: parameter name omitted AT top level: expected identifier or '(' before 'while'

Can anyone shed some light on this? Thanks, Dalton

February 04, 2012
by pcbolt
pcbolt's Avatar

Hi Dalton,

It's the main(int) code that is causing the problem. First, you're returning from main() before even executing the while loop (the closing brace is before the while loop). Second, I don't think the compiler will like main taking an "int" argument in this case (I could be wrong though, I'd just take it out to be safe). Third, the compiler likes to see a return statement at the end of main(), even though it should never reach it.

Another thing that may be a problem is the "return 0;" statements in your while loop. If they get executed the program stops and unknown things may happen. If you just want to jump to the beginning of the while loop again, use "continue;" instead of "return 0;"

February 05, 2012
by pcbolt
pcbolt's Avatar

One other thing Dalton...

I noticed in your "if" statements you're using the "&" symbol between your two different condition statements. The single "&' is used as a bit-wise operator which computes a result. I think you're looking for the logical AND operator, which is "&&". So in your code for example:

if (sd = 1) & (PIND & INPIN)

should be replaced by (notice the extra parenthesis):

if ((sd = 1) && (PIND & INPIN))

Good luck!

February 11, 2012
by wadaltmon
wadaltmon's Avatar

Thanks, pcbolt! Your code helped a lot! Here's my current code:

#include <avr/io.h>
#include <stdio.h>
#define INPIN (1<<PD2)
#define OUTPIN (1<<PB2)

int main()
    {
        int fp;
        fp = 0;
        int fd;
        fd = 0;
        int bt;
        bt = 0;
        int sp;
        sp = 0;
        int sd;
        sd = 1;
        DDRD &= ~(1<<PD2);
        DDRB |= (1<<PB2);

while (1)
    {
        if ((sd = 1) && (PIND & INPIN))
            {
                fp = fp + 1;
                sd = 0;
            }
        else
        if ((11>fp) && (0 < fp) && (PIND & INPIN) && (fd = 0))
            {
                fd = 1;
            }
        else
        if ((fp > 10) && (fd = 0))
            {
                continue;
            }
        else
        if ((fd = 1) && (bt = 0) & !(PIND))
            {
                bt = bt+1;
            }
        else
        if ((10 > bt) && (0 < bt) && (PIND & INPIN))
            {
                PINB |= (1<<PB2);
                sp = sp+1;
            }
        else
        if ((sp > 0) && !(PIND))
            {
                PINB |= (1<<PB2);
                sd = 1;
                continue;
            }
        else
            {
                continue;
            }
        }
        }

But, I'm still receiving that error from before: at line 7, return type of 'main' is not 'int'. I can't seem to fix it. Any ideas?

February 12, 2012
by pcbolt
pcbolt's Avatar

Hi Dalton -

Try putting "return 0;" on a separate line between the last 2 braces.

February 12, 2012
by wadaltmon
wadaltmon's Avatar

Thanks! That seemed to work. But, will this do what I wish it to do? As in, if you have the button pushed for less than 10 milliseconds, then have it released for less than 10 milliseconds, then press it again, the LED will only light up while the second push is held? and then reset the cycle after the second push is released?

Also, which pins of the pushbutton that is included with the kit should I connect to which pins on the MCU to make this program work?

Thanks,

Dalton

February 12, 2012
by BobaMosfet
BobaMosfet's Avatar

You do realize, that you are not checking equality (==) right? You're assigning a value to the variable (=):

if ((fd = 1) && (bt = 0) & !(PIND))      /* bad code */

Also, check your '&&' .v. '&'... which someone else mentioned above.

If it is supposed to be '==' and '&&' on the above line, it can be rewritten thusly (little quicker/easier):

if(fd && !bt && !PIND)

Lastly, try putting 'return(1);' at the bottom of your main(), even though it'll never get there. That may be what the compiler is looking for.

BM

February 17, 2012
by wadaltmon
wadaltmon's Avatar

Thanks guys; all the code really helped! However, I think the problem is my button setup. I have the middle pin of the button that comes with the kit, connected up to GND. Then I have the longest pin connected up to PC4, which I have set up as the new input. Then I have the anode of an LED connected up to PB2, which I have set up as the new output. The cathode of the LED is connected to GND. Yet, this basic code does not work:

#define MYPIN  (1<<PC4) 
#define OUTPIN (1<<PB2)
#include <avr/io.h>
#include <inttypes.h>

int main()
{
    PORTC |= (MYPIN);
    PORTB |= (OUTPIN); 
    while (1)
    {
        if (PINC & MYPIN)
        {
            DDRB |= (1<<PB2);
        }
        else
        {
            return 0;;
        }
    return 0;
    }
}

Help would be cool :). Thanks in advance,

Dalton

February 17, 2012
by wadaltmon
wadaltmon's Avatar

Excuse me,

if (PINC && MYPIN)
February 17, 2012
by wadaltmon
wadaltmon's Avatar

Excuse me again, disregard that last part.

February 17, 2012
by pcbolt
pcbolt's Avatar

Hi Dalton -

I think you may need to set the Data Direction Registers (DDR) for your pins. The output pin (your LED - PB2) you can set as:

DDRB |= OUTPIN;

And the input pin (your button PC4) you can set as:

DDRC &= ~(MYPIN);

Both of those statements only need to be executed once, so you put them after main() and before while(1). You won't need these other statements:

PORTC |= (MYPIN);
PORTB |= (OUTPIN);

Inside the "if" statement, (assuming you want to turn the LED once and keep it on) use:

PORTC |= OUTPIN;

The else statement "return 0;" will end the program - use "continue;" instead or just delete the entire else block (braces and all). If you want the LED off when the button is released, use:

else{
 PORTC &= ~(OUTPIN);
}
February 17, 2012
by wadaltmon
wadaltmon's Avatar

Still not working. How strange; the code seems to work in the compiler, and transfers to the MCU okay, but still it doesn't work.

February 17, 2012
by pcbolt
pcbolt's Avatar

Hi Dalton -

The middle leg of the button and the long leg of the button will never make a connection (I had to check myself with a multimeter). The short leg and the long leg will be connected when the button is not pressed and the short leg and middle leg will be connected when you press the button.

Also, when you make the connection to ground, you are setting PC4 to low. If you want to set it high when a connection is made, don't wire it to ground, wire it to the positive rail. If you still want to use ground, you will have to set the pull-up resistor on pin PC4 after you set it as an output pin. That will make it high until a connection to ground is made. So after you set it as input:

DDRC &= ~(MYPIN);

Enable the internal pull-up resistor like this

PORTC |= MYPIN;

Even though you are writing to an input pin, the result is the pin will report HI or 1 with nothing connected, and LO or 0 when connected externally to ground.

Post a Reply

Please log in to post a reply.

Did you know that any circuit of voltage sources and resistors can be simplified to a "Thevenin" equivalent circuit? Learn more...