3

I am new to using atxmega chips (atxmega128a1 specifically) so sorry if my question is not worded in a "professional" way!

So far in order to set or clear a pin I use the following programming in C:

PORTA.OUTSET = PIN1_bm;

PORTA.OUTCLR = PIN1_bm;

The problem with this for me, is that the individual pin definition is on the right hand side of the "=" sign. I would like to be able to set a pin individually in this fashion:

PA0 = 1;

This would be useful to me as I have many individual pins on different ports that need to be "virtually grouped" in the code as they are doing related functions.

For example I have four motor "enable" pins set on different pins of 4 separate ports. Currently if i want to turn them on simultaneously I have to do this:

PORTE.OUTSET = PIN5_bm;

PORTH.OUTSET = PIN0_bm;

PORTJ.OUTSET = PIN3_bm;

PORTK.OUTSET = PIN6_bm;

I want to keep my naming conventions and port names clear and easy to read such that I can group these outputs into some sort of structure and simply write:

Motor1_Enable = 1;

How can I manipulate C to do this for me???

Hope this is clear! Thankyou!

Sam Bucca
  • 95
  • 7
  • How about a setter function? – uint128_t Feb 17 '16 at 07:33
  • Something like `motorEnableSet(n,en)` where `n` is your motor index and `en` is 0,1 for enabled,disabled. Keeps the code clean and makes your intent clear. – uint128_t Feb 17 '16 at 07:44
  • Hi, thanks! I think this may be what I will have to do. I am just commencing this project and was hoping to set some definitions from the outset, so that i do not make any pin mistakes further down the road, but it looks like i will just have to exercise mindfulness. – Sam Bucca Feb 17 '16 at 08:06

1 Answers1

2

To achieve something close to what you wish, you could define some macros. Here are separate macros for setting and clearing PA0 (assuming PA0 := port A, pin 0), and a macro that takes an argument to decide wether to clear or set the pin.

#define SET_PA0 PORTA.OUTSET = PIN0_bm
#define CLR_PA0 PORTA.OUTCLR = PIN0_bm
#define OUT_PA0(x) (x ? SET_PA0 : CLR_PA0)

int main()
{
  SET_PA0; // PA0 is set
  CLR_PA0; // PA0 is cleared

  OUT_PA0(1); // PA0 is set
  OUT_PA0(0); // PA0 is cleared

  return 0;
}

To use these, you would have to define such macros for all pins you are using. If you want to go an extra mile, you could use more generic macros like:

#define SET_PIN(port, pin) port.OUTSET = pin
#define CLR_PIN(port, pin) port.OUTCLR = pin

int main()
{
  SET_PIN(PORTA, PIN0_bm); // PA0 is set
  CLR_PIN(PORTA, PIN0_bm); // PA0 is cleared

  return 0;
}

But at this point, it would be far better practice to use a function. But you would have to search your headers for the port and pin types. I am not used to atxmega chips as well, but my guess is that they are enums. It would be something looking close to this:

void outPin(port_t port, pin_t pin, int outValue)
{
  if (outValue)
    port.OUTSET = pin;
  else
    port.OUTCLR = pin;
}

int main()
{
  outPin(PORTA, PIN0_bm, 1); // PA0 is set
  outPin(PORTA, PIN0_bm, 0); // PA0 is cleared

  return 0;
}

With these three options, your motor enabling would look like this (choose which best fits your style):

void motorEnable1()
{
  SET_PE5;
  SET_PH0;
  SET_PJ3;
  SET_PK6;
}

void motorEnable2()
{
  SET_PIN(PORTE, PIN5_bm);
  SET_PIN(PORTH, PIN0_bm);
  SET_PIN(PORTJ, PIN3_bm);
  SET_PIN(PORTK, PIN6_bm);
}

void motorEnable3()
{
  outPin(PORTE, PIN5_bm, 1);
  outPin(PORTH, PIN0_bm, 1);
  outPin(PORTJ, PIN3_bm, 1);
  outPin(PORTK, PIN6_bm, 1);
}

You can also write a struct to hold your motor pins information, and use that as argument to a motorEnable function for cleaner code when using more than one motor.

Vicente Cunha
  • 2,642
  • 8
  • 12