6
\$\begingroup\$

I created a simple program to be put onto a ATMega328P chip (Datasheet). I wrote my first program in ATMEL studio that I wanted to use to Blink an LED at a rate of 0.5Hz with extremely low power usage. Here's my code:

/*
 * GccApplication1.c
 *
 * Created: 11/12/2017 8:56:49 PM
 * Author : Brice
 */ 

#include <avr/io.h>
#include <util/delay.h>
#include <avr/power.h>

int main(void)
{
    clock_prescale_set(clock_div_128); //set the clock to use the 8MHz internal clock divided by 128 for an internal frequency of 250KHz, consumes 0.4mA while not sleeping.

    while (1) 
    {
        PORTD4 == 1;//Set pin 13 of the micro to high.
        _delay_ms(1000);
        PORTD4 == 0;//Set pin 13 of the micro to low;
        _delay_ms(1000);
    }
}

What I expect this code to do to this micro-controller is to turn PORTD register 4 on for 1 second, then turn it off for a second.

currently, The PortD4 will not have any voltage changes to it, and remains grounded while the device is powered.

Any explanation of this would be appreciated!

For this instance, I'm using the Arduino Pro mini board for prototyping..

pin 4 of the Pro mini is connected to the common Anode of an RGB led, and the G pin of the LED is connected from a 510 Ohm resistor to GND. I've tested the wiring with a working arduino, and the led even lights at 3.3 Volts pretty brightly.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ How do you have the LED wired up? \$\endgroup\$ – Ron Beyer Nov 14 '17 at 4:07
  • 1
    \$\begingroup\$ PORTD4 == 1; //CHECK IF pin 13 of the micro to high. It doesn't set pin 13. \$\endgroup\$ – immibis Nov 14 '17 at 4:40
  • 1
    \$\begingroup\$ The datasheet you linked to is for the ATmega32, not the ATmega328! These are completly seperate processors. if you use the 32's datasheet as a reference, you're going to have a very hard time :-) This is the right one: atmel.com/images/… \$\endgroup\$ – Tobias Mädel Nov 14 '17 at 7:12
  • 2
    \$\begingroup\$ You need to enable compiler warnings. This code should not have compiled cleanly on any decent compiler. \$\endgroup\$ – Lundin Nov 14 '17 at 8:00
  • 1
    \$\begingroup\$ It should say something like "value computation is not used" and point at the bugs. \$\endgroup\$ – Lundin Nov 14 '17 at 9:08
5
\$\begingroup\$
int main(void)
{
    clock_prescale_set(clock_div_128); //set the clock to use the 8MHz internal clock divided by 128 for an internal frequency of 250KHz, consumes 0.4mA while not sleeping.

    while (1) 
    {
        PORTD4 == 1;//Set pin 13 of the micro to high.
        _delay_ms(1000);
        PORTD4 == 0;//Set pin 13 of the micro to low;
        _delay_ms(1000);
    }
}

The problem is how you "set" the port, you are using == which is a comparison operator, not an assignment. Try just using =.

void main()
{
    DDRD = 0xFF;         //PD as output
    PORTD= 0x00;         //keep all LEDs off

    while(1)
    {
        PORTD &= 0b11110111;       //turn LED off
        _delay_ms(500);   //wait for half second
        PORTD |= 0b00001000;       //turn LED on 
        _delay_ms(500);   //wait for half second
    }        
}

You may also have to set the direction of the port somewhere. You would do this by setting the DDRD to be 0b00001000, which should set Pin 4 of Port D to an output.

\$\endgroup\$
  • \$\begingroup\$ See my edit, you can write to PORTD directly, I showed the easiest way, but you can also do some bit manipulation, like PORTD &= ~(1 << 4) \$\endgroup\$ – Ron Beyer Nov 14 '17 at 4:22
  • \$\begingroup\$ No, I'll remove it, was just a typo that doesn't create a compiler error. \$\endgroup\$ – Ron Beyer Nov 14 '17 at 4:24
  • \$\begingroup\$ What does "|=" mean? \$\endgroup\$ – Krishna Shweta Nov 14 '17 at 4:31
  • \$\begingroup\$ @KrishnShweta "Or Equals", it is another way of writing: PORTD = PORTD | 0b00001000; \$\endgroup\$ – Ron Beyer Nov 14 '17 at 4:32
  • \$\begingroup\$ I understand "==" and "=" concept but what's the need to write &= and |=? \$\endgroup\$ – Krishna Shweta Nov 14 '17 at 4:37
2
\$\begingroup\$

Three problems:

  1. If you're delay.h, you need to define the CPU speed. #define F_CPU 8000000UL in your case.
  2. Port D needs to be set as an output by setting bit 4 in the DDRD register, typically before the superloop. DDRD = 0b00010000
  3. PORTD4 is not how you access that port pin. You would use PORTD, similarly to how I demonstrated the DDRD register above. Personally, I would rewrite your superloop to:

    while (1) 
    {
        PORTD ^= 0b00010000;
        _delay_ms(1000);
    }
    
\$\endgroup\$
  • \$\begingroup\$ ^= is the xor op, right? Also, your bit that you set differs from Ron's.. He uses the fourth from the left, why do you use the 4th from the right? \$\endgroup\$ – tuskiomi Nov 14 '17 at 4:33
  • \$\begingroup\$ @tuskiomi that's it \$\endgroup\$ – Matt Young Nov 14 '17 at 4:36
  • \$\begingroup\$ Also, would I want to change the value of F_CPU since I'm using a clock divider to save power? \$\endgroup\$ – tuskiomi Nov 14 '17 at 4:39
  • 1
    \$\begingroup\$ @tuskiomi Set F_CPU to whatever the clock frequency is in Hz. I wouldn't bother with the clock divider. The power savings at that level are negligible. \$\endgroup\$ – Matt Young Nov 14 '17 at 4:42
-2
\$\begingroup\$

In the end, the only thing that was wrong with the code were the fixes, but the canonical main problem of this situation was a faulty arduino board. a simple replacement fixed the issue.

\$\endgroup\$
  • \$\begingroup\$ Why the down votes? This is what fixed the issue \$\endgroup\$ – tuskiomi Nov 14 '17 at 16:02
  • \$\begingroup\$ I didn't downvote, but you aren't specific enough. What were the changes? This isn't a good answer \$\endgroup\$ – laptop2d Nov 14 '17 at 16:09
  • \$\begingroup\$ @laptop2d the arduino pro mini was bricked. I used a new one to fix the issue. what's not to understand? \$\endgroup\$ – tuskiomi Nov 14 '17 at 16:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.