4
\$\begingroup\$

I have been messing with AVR's XMEGA line. They are pretty amazing microcontrollers. However, Atmel changed much with this new line. I am trying to detect a pin going low.

I have tried to set the PINnCTRL register to every combination with no luck. I can detect the pin going HIGH but not the other way around. Below is the working code for turning on the LED on pin 5 when pin 6 goes high. However, I wanted to do the same thing, just instead of when pin 6 goes high, I would like to have pin 6 go low and turn on the LED on pin 5.

Anyhow, I have not seen a lot of XMEGA stuff on here, so I thought I would try.

I am using AVR Studio and the ATXmega256A3 microcontroller.


AVR PINnCTRL Configuration Register Table (at least for the pull sections 0b00xxx000) FULL DATASHEET HERE: http://www.atmel.com/dyn/resources/prod_documents/doc8077.pdf.

On page 131 (section 13.4) this lists the definition of all of table below. NOTE: the PINxCTRL register contains more than just the pullups for settings. The bits I am working with are these: 00xxx000 The x's correspond with the listing below.

Table 13-4. Output/Pull Configuration
                                                          Description
  OPC[2:0]  Group Configuration       Output configuration        Pull configuration
     000    TOTEM                     Totempole                   (N/A)
     001    BUSKEEPER                 Totempole                   Bus keeper
     010    PULLDOWN                  Totempole                   Pull-down (on input)
     011    PULLUP                    Totempole                   Pull-up (on input)
     100    WIREDOR                   Wired OR                    (N/A)
     101    WIREDAND                  Wired AND                   (N/A)
     110    WIREDORPULL               Wired OR                    Pull-down
     111    WIREDANDPULL              Wired AND                   Pull-up

#include <stdio.h>
#include <avr\io.h>
#define F_CPU 32000000UL
#include <util\delay.h>

void Config32MHzClock(void);

int main(void)
{
    //Init stuff..
    Config32MHzClock();
    CLK.PSCTRL = 0x00; // No division on peripheral clock.
    PORTCFG.CLKEVOUT = PORTCFG_CLKOUT_PE7_gc;

    PORTA.DIR = (1 << 5);  //Sets pin5 as an output (led)

    //011 PULLUP Totempole Pull-up (on input) is what is set
    PORTA.PIN6CTRL = (0x30);  //Sets pullup on input on pin 6.
    PORTA.OUT = (1<<5);       //Turn on the LED

    while(1){                   //Never ending main loop.
        if (PORTA.IN & (1<<6))  //If pin 6 goes HIGH.
            PORTA.OUT = (0x00); //Turn off LED.

        PORTA.OUT = (1 << 5); //Turn LED back on.
    }
}

//Function to setup clock..
void Config32MHzClock(void)
{
    CCP = CCP_IOREG_gc; //Security signature to modify clock
    // Initialize clock source to be 32 MHz internal oscillator (no PLL).
    OSC.CTRL = OSC_RC32MEN_bm; // Enable internal 32 MHz oscillator.
    while(!(OSC.STATUS & OSC_RC32MRDY_bm)); // Wait for oscillator ready
    CCP = CCP_IOREG_gc; //Security signature to modify clock
    CLK.CTRL = 0x01; //Select sysclock 32 MHz oscillator
};
\$\endgroup\$
5
  • \$\begingroup\$ What logic test are you using to detect (unsuccessfully) pin 6 going low? Also, can you detect the pin going low with a multimeter or scope? Might it need a pull-down resistor? \$\endgroup\$
    – pingswept
    Commented May 5, 2010 at 14:42
  • \$\begingroup\$ For logic testing I just used ~ . So, if (PORTA.IN & ~(1<<6)) Pulldown mode = 010 I have tried this but perhaps my ~(1<<6) is the wrong way to read this. I have not tested this on a multi-meter. I will when I get home. Does that help? \$\endgroup\$
    – ril3y
    Commented May 5, 2010 at 15:13
  • \$\begingroup\$ My initial instinct was like pingswept said, check to see if you need a pull-down resistor. \$\endgroup\$
    – Kellenjb
    Commented May 5, 2010 at 15:17
  • \$\begingroup\$ @ril3y - you do not want to use (PORTA.IN & ~(1 << 6)). That would be like (PORTA.IN & 0xBF), which will be true if any pin except pin 7 is high. I believe what you meant to try is !(PORTA.IN & (1 << 6)) \$\endgroup\$
    – ajs410
    Commented May 5, 2010 at 20:39
  • \$\begingroup\$ How to access the Pin directly to read or write data? If I want to write data on pin6 how can I do that..Or I want to read data from a specific pin.. Thanks \$\endgroup\$ Commented Oct 11, 2012 at 10:10

1 Answer 1

1
\$\begingroup\$

There are a few concerns I have.

1) Unless you start counting pins from 0, (1 << 5) is actually pin 6.

2) According to the code, pin 6 going high causes the LED to turn off.

3) Immediately after turning the LED off, you turn it back on. Turning it back on should probably be in an else block.

4) This part of your question is confusing.

I wanted to do the same thing just instead of when pin6 goes high I would like to have pin 6 go low and turn on the led on pin5.

The reason it is confusing is because you say that pin 6 is an input, and then you say you want to drive pin 6 low (which implies an output).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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