Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

help.. this is my first program with c in winavr

Status
Not open for further replies.

mohseni

New Member
hello,

this is simple code whose task is checking the portb.0. if the port is set, it turns on a LED connected with porta.7. otherwise it turns it off. I compiled it and it hasn't any error but I don't know why this simple code dosent work. whould s.o please tell me where is the problem?

**********************************************
#include <avr/io.h>
#include<stdio.h>

#define LED_ON() PORTA|=0x80
#define LED_OFF() PORTA&= ~0x80


int main()
{

for(;;) //while(1)

{

DDRB=0x00; // set the portb as input

if ((PINB&=0b00000001)==0b00000001) // if the portb.0 is set turn on the led
{
LED_ON();

}
else
{
LED_OFF();

}

}
}
 
Last edited:
Inputs won't blink, you never set port A as an output, the default startup mode is input.
so you need a DDRA=0xFF statement



Also your using LED_ON() which is a function that isn't prototyped anywhere, at least not in your code, the #define precompiler directive does not work like that, why it doesn't generate errors I don't know.
remove those two #define lines and fix the mixxing DDR statement

Code:
DDRA=0xFF;
DDRB=0x00;

while(1)PORTA = PINB;
if ((PINB&=0b00000001)==0b00000001) //

Doesn't make much sense, it could be rewritten
if(PINB == 0b00000001)

I'm not sure why you wrote it as above.
The simple while loop I showed above will turn the I/O pins on PORTA on if any of the matching bits on PORTB are high. You should probably brush up on your basic C and watch your syntax as well, both of the #define lines have syntax errors in them (spaces in the wrong place)
 
Last edited:
You should probably brush up on basic C syntax and programming conventions.
 
Code:
#define LED_ON()  PORTA|=0x80
#define LED_OFF() PORTA&= ~0x80
Work as macros, as intended. But a lot of people (including myself) don't like using macros like this. It confuses me when a macro looks like a function call. But it's perfectly valid.
Code:
DDRA=0x80
is required to set port A bit 7 as output. Use DDRA=0xFF if you want the entire port as output.

The following statement doesn't make sense because you can't write to PINB:
Code:
if ((PINB&=0b00000001)==0b00000001) // cannot write PINB
if ((PINB&0b00000001)==0b00000001) // much better.
Funny, the simulator thinks you can write to PINB.
 
You can write to pinB. If that port pin is set to output writing a 1 to the PINB value will cause a logic not on the output pin, It's a nifty little feature they tacked on after some of the early AVRs, in high speed I/O code it can be very useful because you don't have to read PINB not the returned value and write it to portb it's an atomic operation, for bit twiddling it can dramatically increase the number of cycles available.

Works as a macro huh? Well I guess you learn something new every day =)

I guess the code is more valid than I thought, it just seems like a VERY roundabout way of writing something that should be much simpler.
 
Last edited:
I know you can read/modify/write PORTB as an atomic operation, but when you do that to PINB, where does the write operation go? Isn't it lost on the next IOCLK cycle?
 
Yes it is, it's not designed to store anything it simply toggles the PORT pin associated with it. This action is only taken if you write a 1, if you write a 0 I don't think anything happens. They just sort of tacked it on after they got a lot of suggestions from users that you shouldn't have to read a port invert it and write it back out again, instead of being three clocks it's one and you don't need to know what the state is. It's a very cool feature for people that need precise timing control or very high frequency output. Although you wouldn't be able to use jumps you could write a code block that could send out pulses on an I/O line up to half the clock speed of the AVR, on a 16mhz AVR that would allow pulse trains up to 8mhz possible.
 
Hi mohseni, you might have find the solution for your problem...

Here is the code written in my style (this might be complicated, but I write like this)

Code:
#include <avr/io.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif

#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int main(void)
{
    cbi(DDRB,0);
    sbi(DDRA,7);
    
    while(1)
    {
        if(bit_is_clear(PINB,0))
        {
            cbi(PORTA,7);
        }
        else
        {
            sbi(PORTA,7);
        }
    }
}
 
it seems like you are professional programmer. i tank you for the codes. I would be appreciate if you explain your code a little. the compiler how to realize the " if(bit_is_clear(PINB,0)) ". you didn't define "bit_is_clear" for compiler?
 
The existing version of WinAVR deals with those functions nativly as variables.

**broken link removed**

The particular function format you're using in your code rushy was obsoleted almost 3 years ago.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top