Programing in Atmega using AVR Studio 4

Status
Not open for further replies.

nXn

Newbie level 3
Joined
Dec 30, 2009
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
UAE
Activity points
1,339
Hi...
I am new to avr programing.I had gone throught some data sheets and have made some attempt to proraming.Starting off with the basic program of reading if a pin is set to high and then if high set another pin to high.

When i use the below code and try it doesnt give a output.The best part is that the compiler neither shows an error.

if PINC.0==1
PORTB=0xff;

i am not sure if the PINC.0 statement is right .plz help...
 

hi... uu can use the following code...


if(bit_is_set(PINC,0))

for reading a pin value..
 

make sure you set the data direction registers..
 

continuing to nXn question:
i had the same question
sakthisa said a solution but what is the rule why didn't it work as in nXn code?and what if i wanted the opposite like i wanted it low not high?
thanks
 

You can't use a bit of the port using code like PINA.0 or PORTA.2 , this can only be done in codevisionAVR because the compiler is made to recognize this, in AVRstudio it doesn't compile.
If you want to use code like this you can write


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// structure to allow bit field operations, name conversions: PORTA.0 -> PORT_A.b0  PORTB.7 -> PORT_B.b7
typedef struct{ uint8_t b0:1;
                uint8_t b1:1;
                uint8_t b2:1;
                uint8_t b3:1;
                uint8_t b4:1;
                uint8_t b5:1;
                uint8_t b6:1;
                uint8_t b7:1; } bits;
 
// define all the ports of your microcontroller
#define PORT_A (* (volatile bits *) &PORTA)
#define PIN_A (* (volatile bits *) &PINA)
#define DDR_A (* (volatile bits *) &DDRA)
 
#define PORT_B (* (volatile bits *) &PORTB)
#define PIN_B (* (volatile bits *) &PINB)
#define DDR_B (* (volatile bits *) &DDRB)
 
// then you can use specific bits like this to write or read specific bits
PORT_A.b0=1;   // write value to PORTA bit 0
PIN_B.b4=0;   // write value to PINB bit 4



A better way and faster is to use this

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// add this defines
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT)) 
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) 
#define FLIPBIT(ADDRESS,BIT) (ADDRESS ^= (1<<BIT)) 
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT)) 
#define WRITEBIT(RADDRESS,RBIT,WADDRESS,WBIT) (CHECKBIT(RADDRESS,RBIT) ? SETBIT(WADDRESS,WBIT) : CLEARBIT(WADDRESS,WBIT))
 
// and then you can use
SETBIT(PORTX,2);  // set bit2 of portx (set to 1)
SETBIT(PORTY,0);  // set bit0 of porty
 
CLEARBIT(PORTX,5); // clear bit5 of portx (set to 0)
 
FLIPBIT(PORTX,2);  // invert bit2 of portX, if it was 1 it becomes 0, and if 0 becomes 1
                    // example for portx 0x10101010 the result is 0x10101110
                    
if (CHECKBIT(PORTX,4)) {} else {} // result is true if bit4 of portx is 1, false if it is 0
if (!CHECKBIT(PORTX,4)) {} else {} // result is true if bit4 of portx is 0, false if it is 1
 
 
WRITEBIT(PORTX,0,PORTY,2);   // copy the bit0 of portx to bit2 of porty



About the solution given from sakthisa, these two macros are already defined in sfr_defs.h

Code C - [expand]
1
2
if(bit_is_set(PINC,0))   //this can check if a bit is 1
if(bit_is_clear(PINC,0))  // this can check if a bit is 0



Alex
 
Last edited:

i tried the first code but it didn't work.... i wrote it like this:
int main(void)
{
typedef struct{ uint8_t b0:1;
uint8_t b1:1;
uint8_t b2:1;
uint8_t b3:1;
uint8_t b4:1;
uint8_t b5:1;
uint8_t b6:1;
uint8_t b7:1; } bits;

// define all the ports of your microcontroller
#define PORT_A (* (volatile bits *) &PORTA)
#define PIN_A (* (volatile bits *) &PINA)
#define DDR_A (* (volatile bits *) &DDRA)

#define PORT_B (* (volatile bits *) &PORTB)
#define PIN_B (* (volatile bits *) &PINB)
#define DDR_B (* (volatile bits *) &DDRB)

// then you can use specific bits like this
//PORTA.b0=1;
//PINB.b4=0;

DDRA=0xFF;
DDRD=0xFF;
DDRC=0x00;
while(1){
if(PINB.b4=0)
PORTD=0xFF;
if(bit_is_clear(PINC,0))
PORTA=0xFF;
}
return 0;
}
also bit_is_clear(PINC,0) didn't work
but anyway do u know the best way on how to know and understand the c language on avr studio like ebooks , note that i know programming c++ on consle application....
thanks....
 

Yes that was my mistake, you have to use PORT_B.b0 or PORT_A.b1 or use your own custom names but they must be undefined (for example PORTA is already used and cant be used)

so if you change the lines to

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct{ uint8_t b0:1;
uint8_t bit1:1;
uint8_t bit2:1;
uint8_t bit3:1;
uint8_t bit4:1;
uint8_t bit5:1;
uint8_t bit6:1;
uint8_t bit7:1; } bits;
 
// define all the ports of your microcontroller
#define APORT (* (volatile bits *) &PORTA)
#define APIN (* (volatile bits *) &PINA)
#define ADDR (* (volatile bits *) &DDRA)


then you can use APORT.bit0=1;

You would also want to define these in the first lines of the code after #include<avr\io.h> so that they are available in any function before main.

something like if bit_is_clear(PORTB,1) {}; works fine for me.

For tutorials you can take a look at AVRfreaks forum

Alex
 

i tried the code again without the mistakes but it is still does't work....:
#include <avr/io.h>
int main(void)
{
typedef struct{ uint8_t b0:1;
uint8_t b1:1;
uint8_t b2:1;
uint8_t b3:1;
uint8_t b4:1;
uint8_t b5:1;
uint8_t b6:1;
uint8_t b7:1; } bits;

// define all the ports of your microcontroller
#define PORT_A (* (volatile bits *) &PORTA)
#define PIN_A (* (volatile bits *) &PINA)
#define DDR_A (* (volatile bits *) &DDRA)

#define PORT_B (* (volatile bits *) &PORTB)
#define PIN_B (* (volatile bits *) &PINB)
#define DDR_B (* (volatile bits *) &DDRB)

// then you can use specific bits like this
//PORTA.b0=1;
//PINB.b4=0;

DDRA=0xFF;
DDRD=0xFF;
DDRC=0x00;
while(1){
if(PIN_B.b4==0)
PORTD=0xFF;
if bit_is_clear(PORTC,0) {};
PORTA=0xFF;
}
return 0;
}
it should turn all the leds on the port D off when i connect the pin B4 to the ground and so turns all the leds on the portA when i connect the pin C0.....but what is happening is that all the leds r lighting since i turn on the power.....
foxbrain
 


Code C - [expand]
1
2
3
4
5
6
7
8
9
if (PIN_B.b4==0) PORTD=0xFF; //works fine in the AVRstudio debbuger
 
if bit_is_clear(PORTC,0) {};  // you haven't added the code to be executed when this is true  
PORTA=0xFF;  // this is always executed
 
// you probably wanted to do 
if bit_is_clear(PORTC,0) {PORTA=0xFF;};
//or
if bit_is_clear(PORTC,0) PORTA=0xFF;



When i use the below code and try it doesnt give a output.The best part is that the compiler neither shows an error.

if PINC.0==1
PORTB=0xff;

i am not sure if the PINC.0 statement is right .plz help...
As i said in the previous post you can't use this way with AVRstudio, and this doesn't compile in my AVRstudio4, I get an error ../test3.c:36: error: called object '1' is not a function

Alex
 

    V

    Points: 2
    Helpful Answer Positive Rating
The correct way to read a pin is when you denounce the signal. If the pin it is connected to a switch or a device usually there are spikes on real signals. To make sure that you read the desired level you have to read the pin for a period of time. The logic value is obtain by the majority of samples in the denounce period. In this way you avoid unintended spikes.
 

i'm sorry because i'm late for answering.....
alexan_e :your way (code) worked thanks a lot but
when i used :
if bit_is_clear(PORTC,1)
{
PORTA=0xFF;
}
else
{
PIN_A.b7==0;
}
it didn't work,the led is always turned on.!
so what's wrong with it?
blind_man :what u r talking about is to take a clear signal without any disturbance but i don't need this on my circuit because i'm aiming on using a switch when it is connnected to the ground (0v)
anyway thanks to u all......
 

PINA reads the input state of the port, you have to use PORTA to control the output.
Another note is that you use == instead of =. To set the value you need to use =

Alex

---------- Post added at 21:14 ---------- Previous post was at 20:56 ----------

My recommendation would be to use the SETBIT, CLEARBIT etc like I have posted above, they are very easy to use.

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT)) 
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) 
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT)) 
 
if CHECKBIT(PINC,1) // check if bit1 of portC is 1, or use !CHECKBIT(PINC,1) to check if it is 0
 {
    SETBIT(PORTA,7);  // I assume that you want to set one bit only and not all bits of portA
 }
else
 {
    CLEARBIT(PORTA,7);
 }



I think you are a little confused about the three registers that control the ports.
DDRA, DDRB etc control the port direction, when a bit is 0 then the pin is input and when it is 1 the pin is output

PINA, PINB etc can read the logic state of a pin of the port, it doesn't matter if the pin is input or output.

PORTA, PORTB etc control the output state of the pin when the pin is set as output or the use or pullup resistor (1=use internal pullup, 0=no pullup) when the pin is set as input

Alex

---------- Post added at 21:30 ---------- Previous post was at 21:14 ----------

Take a look at this tutorial, it has very nice explanation



Alex
 

thanks that was good alex but the one that to use "!" before CHECKBIT to check if it is 0 didn't work
 

!CHECKBIT works fine.
I suppose that you didn't use parenthesis, the if statement must be enclosed in parenthesis (), the CHECKBIT macro is already defined as a code that has parenthesis but if you add the ! in front then you have to add a parenthesis like this if (!CHECKBIT(PINC,1))

Alex
 

if (!CHECKBIT(PINC,1))
{
SETBIT(PORTD,4);
}
else
{
CLEARBIT(PORTD,4);
}}
that looks it's about to work but what's happening is that the led is always lighting but when i but c1 to 0 it lights higher.
 

Have you set PORTD bit 4 as an output? (using SETBIT(DDRD,4))
If you didn't then the pin is still an input and all that you do is enable/disable the internal pullup resistor for bit 4 of port D.

Alex
 

well i set all ports in D as output by using : DDRD=0xFF;
should it be specified by the pin?
 

No, it is the same thing.
can you post the schematic of the led connection to the mcu?

Alex
 

As I thought, you didn't use a resistor to limit the current of the led and this is something you should do to any circuit having a led.
Assuming that your Vcc is 5v and the led has about 2v forward voltage drop then the resistor can be calculated using R=(Vcc-Vf_led)/I
Usually the current used is about 10-15mA so for 10mA we have (5v-2v)/0.01=300 ohm (a typical led resistor for 5v is about 220-300 ohm depending on the led color and current)
You must always limit the output current of the ports to avoid damage to the mcu.

Alex
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…