Society of Robots - Robot Forum

Software => Software => Topic started by: allahjane on May 11, 2012, 07:54:18 AM

Title: A beginner's problem [SOLVED]
Post by: allahjane on May 11, 2012, 07:54:18 AM
HI people !

i'm just a beginner so i started out by making a simple single LED blinking circuit with the AVR atmega 16.

it has just a voltage regulator at vcc and i have interconnected VCC with AVCC directly.

the program is to toggle HIGH/LOW  pins on PORTC high  each sec..

the program compile successfully

However on running the code on the MCU  after programming the hex on its flash all the pins of the chip whether port A,B,C or D remain HIGH constantly forever....

just to make clear for some people ..... HIGH = +5v

the code is as below.. I'm using AVR studio 4



#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 8000000

int main(){

DDRC = 0xFF;

while(1)
{
_delay_ms(1000);

PORTC=0xFF;

_delay_ms(1000);

PORTC=0;
}
return 1;
}



also i have set the frequency in AVR studio's project configuration to 8000000

why isn't it working?
Title: Re: A beginner's problem
Post by: newInRobotics on May 11, 2012, 08:25:11 AM
Hi,

i have interconnected VCC with AVCC directly.
AFAIK, You don't have to connect AVCC to anything for what You want to do, try leaving it disconnected.

Try following code:
Code: [Select]
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 8000000

int main()
{
      DDRC |= (1 << DDC0);

      for(;;;)
      {
             _delay_ms(1000);
             PORTC &= ~(1 << PORTC0);
             _delay_ms(1000);
             PORTC |= (1 << PORTC0);
      }
}

Plug Your LED to Port C pin 0;
Title: Re: A beginner's problem
Post by: joe61 on May 11, 2012, 01:24:36 PM
it has just a voltage regulator at vcc and i have interconnected VCC with AVCC directly.

This is correct.

Quote
However on running the code on the MCU  after programming the hex on its flash all the pins of the chip whether port A,B,C or D remain HIGH constantly forever....

Your code looks ok for what it does, and I don't see how it could affect the other ports. Can you post a schematic?

Quote
also i have set the frequency in AVR studio's project configuration to 8000000

What does studio do when that's set? I assume it changes the fuse byte, but can you post what it's setting it to?

Joe
Title: Re: A beginner's problem
Post by: allahjane on May 13, 2012, 01:40:56 AM
Hi,

i have interconnected VCC with AVCC directly.
AFAIK, You don't have to connect AVCC to anything for what You want to do, try leaving it disconnected.

Try following code:
Code: [Select]
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 8000000

int main()
{
      DDRC |= (1 << DDC0);

      for(;;;)
      {
             _delay_ms(1000);
             PORTC &= ~(1 << PORTC0);
             _delay_ms(1000);
             PORTC |= (1 << PORTC0);
      }
}

Plug Your LED to Port C pin 0;




THANKS A TONNN BRO! YOU'RE A GENIUS ITS WORKING NOW! ;D ;D ;D ;D ;D ;D ;D ;D
can you explain me what i was doing wrong? atleast to me i think using the vcc gnd instead of avcc gnd pin was one of the problems
also i dont get that bitwise OR and AND operations.
Title: Re: A beginner's problem [SOLVED]
Post by: newInRobotics on May 14, 2012, 04:38:11 AM
I'm glad it worked  :D

Not sure, though, what was wrong with Your setup, or code.

Bitwise manipulation allows You to SET or CLEAR (set HIGH or LOW) any single pin of microcontroller without affecting other pins, as opposed to switching whole section of pins with Your code.

I'll try to explain, so bear with me  ;D

PORTC |= (1 << PORTC0) translates into:
PORTC = PORTC | (1 << PORTC0)

To expand on the above bitwise operators work in this way:

To SET required bit You use | (OR) operator.

| (OR) operator needs at least one 1 to produce 1, if that does not make sense - read on...
00001010 |
00001101
=
00001111;


10100101 |
01010110
=
11110111;


<< (shift left) operator shifts all bits by given number to the left
00000001 << 5 = 00100000;
00000001 << 1 = 00000010;
01010101 << 1 = 10101010;


All mnemonics (memorable names for ports and pins) in our original line PORTC |= (1 << PORTC0) actually means:
Our line PORTC = PORTC | 1 << PORTC0 now translates to:
PORTC = 00000000 | (00000001 << 0) =
= 00000000 | 00000001 =
= 00000001;


Can You see now that this way You do not affect other pins apart from the one You need?

To CLEAR required bit You use & (AND) operator and ~(NOT) operator:
PORTC &= ~(1 << PORTC0), which translates to PORTC = PORTC & ~(1 << PORTC0).

& (AND) operator requires two 1s to produce 1...
00000101 &
11110110
=
00000100;


~ (NOT) operator inverts all bits changing all 1s to 0s and all 0s to 1s.
~00000000 is equal to 11111111;
~01010101 is equal to 10101010;
~00000001 is equal to 11111110;


Lets say that Your LED is shining now meaning that Pin 0 of Port C is set HIGH, therefore PORTC = 0b00000001;

Our line PORTC = PORTC & ~(1 << PORTC0) now translates to:
PORTC = 00000001 & ~(00000001 << 0) =
= 00000001 & ~(00000001) =
= 00000001 & 11111110 =
= 00000000;


Once again, You can CLEAR one pin only without having effect on others.

Info provided here is based on Bitwise Operators in C and C++: A Tutorial (http://www.cprogramming.com/tutorial/bitwise_operators.html) by Alex Allain (https://plus.google.com/113987539774523532573/posts).

Hope this was clear enough to understand.