Libraries in Atmel Studio 7/Flashing an LED on XMega A1U xPlained Pro

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

Hi everyone,

 

I've started working with AVR chips and right now am getting started with an XMega A1U xPlained Pro. I've been trying to follow this video just to turn on an LED: https://www.youtube.com/watch?v=...

 

I've tried the same code used in the video. But I keeps getting errors saying that DDRB and DDB5 are undeclared.  I think maybe the problem is that I don't have the avr/io.h header file.

 

If that's the case, can anyone tell me how to install and properly include it in Atmel Studio 7? Otherwise, could someone give me a hand with some code just to flash an LED with this device?

 

Thanks to everyone who takes the time to read and respond.

 

Thanks,

Al

 

Some links to potentially useful documentation:

 

http://www.atmel.com/tools/atxme...

http://www.microchip.com/wwwprod...

 

I've copied the code used in the video: 

#include <avr/io.h>

 

int main(void) 

{

DDRB |= (1<<DDB5);

while(1) 

{

PORTB |= (1<<PORTB5);

}

}

 

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

ADelapore wrote:
But I keeps getting errors saying that DDRB and DDB5 are undeclared.
Because you are using an Xmega not an AVR. The (original) Tiny and Mega chips all have simple IO registers like DDRB (direction), PORTB (output), PINB (input).

 

The Xmega chips are quite different. They have more registers to control the IO though they can be operated with just three. The Xmega equivalent of the three I just listed are effectively:

 

DDRB = PORTB_DIR

PORTB = PORTB_OUT

PINB = PORTB_IN

 

(there's also things like PORTB_TGL, PORTB_CLR and so on but you can ignore them at first).

 

Same goes for bit numbers. I don't think they define things like PORTB5 and DDB5 but as all those things are simply defined as 5 anyway you might as well just use that:

int main(void)
{
  PORTB_DIR |= (1 << 5);

  while(1)
  {
     PORTB_OUT |= (1 << 5);
  }
}

However this is a bit of a "do nothing" program. First time through it will raise the PORTB.5 signal but after that nothing changes. When first learning it's much easier to "see stuff happen" if you actually keep changing a pin. So maybe:

int main(void)
{
  PORTB_DIR |= (1 << 5);

  while(1)
  {
     PORTB_OUT |= (1 << 5);
     PORTB_OUT &= ~(1 << 5);
  }
}

which will switch the output on-off all the time. Only thing is that without an oscilloscope this will all happen so fast you won't "see" anything. So perhaps:

#undef F_CPU
#define F_CPU 2000000UL // set this to the actual speed you are running at
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
  PORTB_DIR |= (1 << 5);

  while(1)
  {
     PORTB_OUT |= (1 << 5);
     _delay_ms(100);
     PORTB_OUT &= ~(1 << 5);
     _delay_ms(100);
  }
}

This will now switch the outputs so slowly that if an LED is attached it will switch at a rate that even a human being will be able to detect.

 

Oh and before someone mentions it I deliberately used |= and &= ~ to show the traditional way to set a bit high an low. As I say the Xmega has new features so you could use:

#undef F_CPU
#define F_CPU 2000000UL // set this to the actual speed you are running at
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
  PORTB_DIR |= (1 << 5);

  while(1)
  {
     PORTB_TGL = (1 << 5);
     _delay_ms(100);
  }
}

The TGL is for "toggle". This time you don't use |= but a simple = and each time it is written the output switches state ("toggles" - hence "TGL").

Last Edited: Fri. Jun 30, 2017 - 04:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

Thanks so much for your excellent post, I was able to get my LED flashing using the "traditional" version of your code. Interestingly, the TGL function wouldn't work for me, I got the following error: 

 

Error 'PORTB_TGL' undeclared (first use in this function)

 

But I'm happy enough to have gotten it working. 

 

I'm used to working with Arduino where the library commands are pretty neatly listed on their website. Is there anything similar for XMega where I can find a list of the different functions?

 

Next step for me is to try to get an ADC reading.

 

Thanks so much again.

 

 

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

I don't really do Xmega (seems like a pointless chip family to me) so maybe I mis-remembered the _TGL thing? Just checking the headers for the chip:

C:\SysGCC\avr\avr\include\avr>grep PORTB_ iox128a1u.h | grep _SFR
#define PORTB_DIR  _SFR_MEM8(0x0620)
#define PORTB_DIRSET  _SFR_MEM8(0x0621)
#define PORTB_DIRCLR  _SFR_MEM8(0x0622)
#define PORTB_DIRTGL  _SFR_MEM8(0x0623)
#define PORTB_OUT  _SFR_MEM8(0x0624)
#define PORTB_OUTSET  _SFR_MEM8(0x0625)
#define PORTB_OUTCLR  _SFR_MEM8(0x0626)
#define PORTB_OUTTGL  _SFR_MEM8(0x0627)
#define PORTB_IN  _SFR_MEM8(0x0628)
#define PORTB_INTCTRL  _SFR_MEM8(0x0629)
#define PORTB_INT0MASK  _SFR_MEM8(0x062A)
#define PORTB_INT1MASK  _SFR_MEM8(0x062B)
#define PORTB_INTFLAGS  _SFR_MEM8(0x062C)
#define PORTB_PIN0CTRL  _SFR_MEM8(0x0630)
#define PORTB_PIN1CTRL  _SFR_MEM8(0x0631)
#define PORTB_PIN2CTRL  _SFR_MEM8(0x0632)
#define PORTB_PIN3CTRL  _SFR_MEM8(0x0633)
#define PORTB_PIN4CTRL  _SFR_MEM8(0x0634)
#define PORTB_PIN5CTRL  _SFR_MEM8(0x0635)
#define PORTB_PIN6CTRL  _SFR_MEM8(0x0636)
#define PORTB_PIN7CTRL  _SFR_MEM8(0x0637)

So what I called PORTB_TGL is actually PORTB_OUTTGL in fact.

 

To be honest you are better off reading about this in the datasheet. It would have told you to expect PORTx_OUTTGL.