Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a Port as a variable - AVR

Tags:

c++

io

avr

Is it possible to use an AVR port as a variable which can be passed around?

For example

LED myLed(PORTA,7);   //myLED hooked to PORTA, Pin 7

I would like to make LED be able to take any PORT / Pin combination, so I would rather not hard code it in.

Note that the PORTs are defined as:

#define PINA  _SFR_IO8(0x00)
#define DDRA  _SFR_IO8(0x01)
#define PORTA _SFR_IO8(0x02)    

PORTA symbol resolves to (*(volatile uint8_t *)((0x02) + 0x20))

I believe this would allow me to do something like the following, but I am unsure whether I would need the volatile keyword or not, nor whether it will actually work as expected

class LED{
public:
    LED(volatile uint8_t* port, uint8_t pin);
    {
        Port=port;
        Pin=pin;
    }
    void write(bool val)
    {
        if(val) (*Port) |= 1 << Pin;
        else    (*Port) &= ~(1 << Pin);
    }

private:
    uint8_t  Pin
    volatile uint8_t* Port;
}

Finally, is there a way to set Port / Pin as an Output from the LED Constructor? This would involve finding the relative DDR# register for the Given PORT#. Can I assume &DDR# will always be &PORT#-1?

like image 878
DanChianucci Avatar asked Dec 04 '12 13:12

DanChianucci


2 Answers

The register macros are basically pointers to the memory location, where the appropriate register resides, so yes, you can use uint8_t volatile *. However, the compiler will not generate the most efficient code this way -- it will use indirect addressing instead of direct writes.

This is what I do instead, using avrlib.

#include <avrlib/porta.hpp>
#include <avrlib/pin.hpp>
using namespace avrlib;

typedef pin<porta, 4> led_pin;

Then you can use the led_pin typedef, e.g.

led_pin::set();
like image 73
avakar Avatar answered Sep 24 '22 05:09

avakar


This is how I did it, im not very experienced in AVR,

#include <avr/io.h>

void LED(volatile uint8_t* port, uint8_t pin)
{
    // First set DDRx ; DDRx on ATmega32 is one address below port address
    *(port -1) |= (1<< pin);
    // Now set the pin high
    *port |= (1<< pin);
}

int main(void)
{
   LED(&PORTB,1);
   LED(&PORTC,2);
   LED(&PORTD,3);
    while (1) 
    {
    }
}
like image 4
Amer Iqbal Qureshi Avatar answered Sep 21 '22 05:09

Amer Iqbal Qureshi