Various C programming in Arduino questions

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

Hello,

 

I have a few questions, which it would be great if anybody could answer:

 

1. Could anybody point me to a place, where I can find a program written in C, where if you press a button, a led lights up?

I need it, so I can see it and compare it to how we make it in the Arduino IDE.

I am especially looking for how to declare a pin as INPUT, and how to check if it's high or low.

So this tutorial would be perfect for it.

 

2. I already found out that to set a pin as OUTPUT, we have to do it like this:

DDRE    |= ((1 << DDE4));

But didn't quite understand why shifting a bit, and doing an OR operation, can set the pin as OUTPUT.

 

Also, to set a pin to LOW, we do _SFR_BYTE(sfr) &= ~_BV(bit) and _SFR_BYTE(sfr) |= _BV(bit) for high. This is more clear to me.

_BV shifts the bit, then we do an AND or OR operation.

 

3. And also, what's the difference between DDRB and PORTB? I noticed that both can be placed as sfr arguments (in the above operations), and both have the same result.

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

Search the tutorials for bit manipulation.
_BV is just a macro that does the bit shift, so your teo examples are the same.

Why the shift? You have 8 bits to choose from and you want to set/clear one of them. The shift converts the bit number to a bit mask.
DDRx is the data direction register. A 1 bit is output, 0 is input
PORTx is the port register. Write to this to set a port pin high or low if it is an output.
PINx is the port input register
See the Atmel datasheet for a complete explanation.

You don't need to do _sfr_byte() as all the special registers are defined in the header file that Arduino includes for you. PORTB gets translated into _sfr... For you.

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

DDR (A,B,C,D...) = DATA DIRECTION REGISTER. A 0 in a bit position designates the corresponding I/O pin as an input. A 1 in a bit position designates the corresponding I/O pin as an output.

 

PORT (A,B,C,D) = PORT OUTPUT REGISTER. IF the corresponding DDR bit is set, then the designated I/O pin will reflect the value of the bit in the PORT register. 

 

PIN (A,B,C,D) = PORT INPUT REGISTER. Reflects the current state of the corresponding I/O pin, regardless of DDR or Alternate function.

 

Note that the PORT value will be over-ridden if the I/O pin is configured for an Alternate use. As an example, the TX pin will be taken over by the USART if the USART is enabled.

 

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

I already found out that to set a pin as OUTPUT, we have to do it like this:

DDRE    |= ((1 << DDE4));

But didn't quite understand why shifting a bit, and doing an OR operation, can set the pin as OUTPUT.

The pins of a microcontroller are not something that the CPU can just manipulate directly.   There is some hardware circuitry in between the CPU and the actual pins that controls how the pins behave.   Typically, there are several "registers" (essentially memory locations) whose bits are connected to logic gates in the circuitry in various ways, that have various effects.   The AVR has a nice diagram of this circuitry, which might be interesting if you have a HW background, but you can usually just treat it at a higher level.  As other have said, the DDRx register controls whether the pin will be an input or an output, the PORTx register controls the output signal, and the PINx register reads an input signal.  Other microcontrollers can have many more control registers, but the basic principles are the same.

 

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

1) If you are talking about a "plain C" program you want to put into an Arduino Uno to make the LED do something then first you need to know that the LED on an Arduino is on pin 13. Next you need to know that is bit 7 of port C. With that in mind you can write something like:

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

int main(void) {
    DDRC = (1 << 7) ; //make bit 7 of PORTC an output
    while(1) {
        PORTC = PORTC ^ (1 << 7); // switch the state of output pin 7 on C
        _delay_ms(100);
    }
}

That should cause the LED to flash 5 times per second.

 

2) read the "bit manipulation 101" thread in the Tutorial Forum here. As my example shows I use (1 << 7) that means take 1 (also known as 0b00000001) and shift it 7 places to the left. That is 0b10000000. So this creates a byte that has bit 7 set t 1 and all the other bits set to 0. If I then used this with | (or) then it would cause the destination to have this bit set to 1 with the other bits unaffected.

 

3) read the datasheet. DDR sets the direction (0 = input (default), 1 = output). PORT actually drives the pins to Gnd or Vcc (if DDR says it is output) - 0 = Gnd, 1 = Vcc.

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

Thank you everybody, you made everything more clear to me now!!!!