ATMEGA 168 I/P

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HI,

So I want to change the duty cycle  to 50% of an LED connected to PORTB .The input is being given in PORTD.

So if there's an input in PORTD then the LED should glow at 50% duty cycle, if not then it should perform the LED blink.

The following is my code; is it correct?

#include <avr/io.h>
#define F_CPU 4000000UL
#include<util/delay.h> 
#include<stdio.h>
  
int main(void)
{
DDRD = 0b00000000;    //All pins in PORTD are inputs

if(PIND0==0)
{
    DDRB |= (1 << DDB3); // PB3 is now an output

    OCR0A = 64;// set PWM for 100% duty cycle

    TCCR0A |= (1 << COM0A1);//  non-inverting mode

    TCCR0A |= (1 << WGM01) | (1 << WGM00);//  fast PWM Mode

    TCCR0B |= (1 << CS01); // prescaler to 8 

    while (1);
    {
        
    }
}

else
{
    DDRB=0xff;
    while(1)
    {

        PORTB = 0xff;
        _delay_ms(500);
        PORTB = 0x00;
        _delay_ms(500);
    }
}

}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
if(PIND0==0)

Incorrect. The header file has:

#define PIND0 0

so that line simply says:

if(0==0)

which is al3ways true so it will never use the else{} block (in fact no code will be generated for it). To read bit 0 of PIND you need:

if (PIND & (1 << PIND0)) {

If you don't know why then go to the tutorial form and read the thread about "Bit manipulation 101"

 

BTW as written this code would just check PIND bit 0 once a few microseconds after power is applied and then never again. Are you sure you have your while(1) loop(s) in the right place?

 

Also if you are only using 50% PWM then it's not really PWM at all is it?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, it is not correct. Eg you have 

While (1);

Which will make your program hang. 

 

Also, you cant simply use 

if (PIND0)... 

to test the state of the input. PIND0 is simply the number of the pin bit in the register. It's like you've coded

if (0)... 

Go over to the Tutorials forum and read the piece on "Bit manipulation". Required reading for anyone programming AVRs in C. 

 

That's two quick findings. There might be more. 

Is this school work? 

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Mon. Jun 26, 2017 - 08:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
go to the tutorial form and read the thread about "Bit manipulation 101"
 

JohanEkdahl also wrote:
Go over to the Tutorials forum and read the piece on "Bit manipulation". Required reading for anyone programming AVRs in C. 

 

It's here: https://www.avrfreaks.net/forum/tut-c-bit-manipulation-aka-programming-101?page=all

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank u for ur help.  Thank u for pointing out the mistake in while loop.

so can you tell me if this code could check if there is an input in the pin 2(PD0) :    if (PIND & (1 << PIND0))

If there is an input I want the statements in  if to be executed.I am using ATMEGA 168

Last Edited: Mon. Jun 26, 2017 - 09:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

OK..

 

1) Your code will not even compile correctly.

 

[EDIT: I was wrong here. It compiles. I was confused by the indentation structure of your code above. My apologies!]

 

Nevertheless..

 

Please do not post code that you just sketched out. Code in your editor/IDE of preference, and then compile. If it does not compile without errors/warnings then fix that. Or ask here if you are not able to fix. 

 

We are not interested in reading or helping with things just typed in. That will just be a waste of time.

 

The main effort is on you. This means YOU will have to use your editor+compiler (e.g. Atmel Studio) to produce something we can work with. If you do not follow this advice everyone (you, me and everyone else) will just get frustrated. For us, there is a simple solution if this happens. We can just walk away..

 

2) As I said earlier re

    DDRB |= (1 << DDB3); // PB3 is now an output
    OCR0A = 64;// set PWM for 100% duty cycle
    TCCR0A |= (1 << COM0A1);//  non-inverting mode
    TCCR0A |= (1 << WGM01) | (1 << WGM00);//  fast PWM Mode
    TCCR0B |= (1 << CS01); // prescaler to 8
    while (1);

once you hit that while (1); your program will hang there forever.

 

 

3) If it weren't for 2) above then, once you get into this loop,

    while(1)
    {
        PORTB = 0xff;
        _delay_ms(500);
        PORTB = 0x00;
        _delay_ms(500);
    }

you will never get out - however much you release the button.

 

4) I suppose you, at any time, want either the timer to PWM the LED with a 50% duty cycle or blink the LED at 1 Hz. Not both at the same time. Thus, it would be wise and start and stop the timer appropriately. The current structure of your program does not allow for this easily.

 

5) You need a "high-level design/structure" for your program. Disregard the details of how to start/stop the timer and how to blink the LED for now. Think in terms of higher order functions. E.g. imagine you have functions like

void start_pwm();

void stop_pwm();

void led_on();

void led_off();

and code the overall structure with those. Then implement them. For the case of blibking the LED it might seem as the trivial task, but there is actually some complications. You want to loop as long as the button is pressed, but every other time you want to turn on the LED, every other time you want it off. And it is essential that you turn it off as the last thing before the code again activates the timer to do PWM. There's more to this than the face value of it..

 

6) .. so whoever came up with this did a great job actually involving several problems regarding this high-level design/structure. There are several possible solutions, but they all require you to structure your code at a higher level first.

 

7) I asked if this is school work. I will not contribute any more details of what I said above until I get an answer. If the answer is "no" then make us believe it by telling us why you want to do what you've described. If the answer is "yes" then realize that we do not solve school assignments here. We can help you solve it, but then (again) the effort is on you.

 

8) Please understand that the light emitted from an LED is not linear proportional to the duty cycle. It is fairly sure that the LED will glow brighter than "half brightness" when PWMed at 50%. Perhaps much more.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Mon. Jun 26, 2017 - 09:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Geeth wrote:
If there is an input

There is always an input!

 

That input will either be high (1) or low (0) - but there is no such thing as no input!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I  am new to ATMEGA controllers.I have only dealt with ARM -7.This is not a school work.I am learning ATMEGA 168 for my career purposes.

So all I need to know is how to check if PORT D(PD 2), PIN 4 has an input or not.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

go on - the basics of how digital IO ports work are not fundamentally different:

 

You have some registers to configure the ports, and you have some registers to read/write the states of the pins.

 

The details of what those registers are, and how to use them, are in the datasheet.

 

EDIT

 

And, of course, the 'C' programming language is completely independent of whether you're using an ARM or an AVR or whatever.

 

(beyond the implementation-defined details).

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Jun 26, 2017 - 09:59 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Geeth wrote:
So all I need to know is how to check if PORT D(PD 2), PIN 4 has an input or not.

Clawson told you how to check the state of a port pin in post #2 . Both he and I pointed to the tutorial on bit manipulation for the details (we get the question so often so instead of answering with details every time, we have a tutorial text ready and point at that). For the details and understanding - read it.

 

Geeth wrote:
I have only dealt with ARM -7

Not in C then? Most of the problems I pointed out are not related to AVRs specifically, but are valid for C code in general (regardless of hardware platform).

 

Glad to hear that this is for your own learning process, rather than a school project. This means we're not facing an exam deadline and we can get about this in an orderly fashion, learning along the way. I would advice to move in small steps: 

 

Begin with just controlling the LED (on/off) using the button.

 

Then control the turning on and off of the PWM from the timer using the button. Modularize your code into functions as suggested above and you should be able to re-use those functions later.

 

After those, you can start thinking of the overall structure of the algorithm for doing what you originally described in your first post.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Not in C then?

Here are some 'C' reference/learning resources for you: http://blog.antronics.co.uk/2011...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NO I dnt hv any deadlines.I  have done the LED ON/OFF program.Then I  generated diff. duty cycle in diff. pins by using them as o/p .I know that i have to use three reg. to read the i/p value .which is DDRD,PORTD and PIND (for port D). I know about DDRD.But PORTD and PIND are the reg i dont know to use and set the value as i/p

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Geeth wrote:
PORTD and PIND are the reg i dont know to use 

So what does the datasheet tell you? Which part(s) of that do you find confusing or hard to understand?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Geeth wrote:
I dnt hv any deadlines

Then please take the time to write complete words.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The data sheet says: If PORTxn is written logic one when the pin is configured as an input pin,. So since I wanna read the input I wrote the command: PORTD=(1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD7).

this would make the specific pins as i/p pins. Now how do i check if PD2 has got the input or if PD3 has got the i/p.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK,SORRY

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Geeth wrote:
The data sheet says: If PORTxn is written logic one when the pin is configured as an input pin,

You've missed the second half of that sentence!

 

A sentence like that always has the form IF <some condition> THEN <the result of that condition>

 

You've missed the "THEN" part!

 

So you need to read that whole sentence to see what happens when PORTxn is written logic one when the pin is configured as an input!

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It activates the pull up resistors when the PORTxn is written logic one.So I did write the logic one for the desired reg.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Geeth wrote:
how do i check if PD2 has got the input or if PD3 has got the i/p.

 

I'll essentially repeat what clawson said in post #2 here:

 

if (PIND & (1 << PIND2)) {
    // Code here will be executed if port D pin 2 was high/1 when the if-condition
    // on the line above was tested
}

if (PIND & (1 << PIND3)) {
    // Code here will be executed if port D pin 3 was high/1 when the if-condition
    // on the line above was tested
}

Do you see the pattern here?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Geeth wrote:
It activates the pull up resistors when the PORTxn is written logic one.

Not quite - read it again, carefully!

 

IT actives the pullup when the pin is configured as an input.

 

how do i check if PD2 has got the input or if PD3 has got the i/p.

Again, "got the input" is meaningless!

 

Again, the pins have always "got input" - and, being digital, that input will be either 0 or 1.

 

This is not specific to AVR - it applies to any digital input!

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you all for your help.I have an executable code now.

 

If you are interested this is what I coded:

#include <avr/io.h>
#define F_CPU 1000000UL  
#include<util/delay.h> 
#include<stdio.h>

int main(void)
{
    DDRD |= (1 << DDD6);// PD6 as output
    DDRD = 0b01000000;// pins in PORTD are inputs
    PORTD = (1<<PD2)|(1<<PD3)|(1<<PD4);
       
    TCCR0A |= (1 << COM0A1)|(1<< COM0A0);// inverting mode
       TCCR0A |= (1 << WGM01) | (1 << WGM00);// 8bit fast PWM Mode
       TCCR0B |= (1 << CS01)|    (0<<CS00);// prescaler to 8 and starts PWM
    
    while(1)
    {
           int ipin = PIND;
           int pind2=(ipin &(1<<2))>>2;
        int pind3=(ipin &(1<<3))>>3;
        int pind4=(ipin &(1<<4))>>4;
   
           if(pind2==0)
           {    
               OCR0A=0x40;    //25% duty cycle at 8bit
            DDRB|=(1<<DDB0);
            PORTB=(1<<PB0);
        }
        else
        {
            
            DDRB=0xff;
            PORTB = 0xff;
            _delay_ms(500);
            PORTB = 0x00;
            _delay_ms(500);
        }
        
    }
}

Last Edited: Mon. Jul 3, 2017 - 11:36 AM