/** * \file * * \brief megaAVR STK600 GPIO Example * * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. * * \asf_license_start * * \page License * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The name of Atmel may not be used to endorse or promote products derived * from this software without specific prior written permission. * * 4. This software may only be redistributed and used in connection with an * Atmel microcontroller product. * * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * \asf_license_stop * */ /** * \mainpage * \section intro Introduction * This example demonstrates GPIO port access, pin access, pin interrupt and * pin pull up configuration. * * \section files Files: * - mega_gpio_example.c: megaAVR GPIO example application * - conf_example.h: Example configuration * * \section setup Setup * This example is made for STK600 with two 10-pin cables in the following * strap configuration: * - PORTB <-> SWITCHES * - PORTD <-> LEDS * * \section description Description * The example will utilize different registers for setting and reading port * and pin GPIOs. These GPIOs are connected to switches and LEDs on the STK600. * * In the end of the example pin change interrupts are enabled and can be * tested with STK600 SW0. This will toggle LED0 from the interrupt handler. * Not all megaAVR devices supports pin change interrupts, so for those this * is disabled. * * For the best demonstration it's recommended to run this in a debug session * and single step through the different operations. * * \section compinfo Compilation Info * This software was written for the GNU GCC * for AVR. \n * Other compilers may or may not work. * * \section contactinfo Contact Information * For further information, visit * Atmel.\n */ /* * Support and FAQ: visit Atmel Support */ #include "compiler.h" #include #include "conf_example.h" // Only use Pin Change Interrupt handler for devices supporting this. #ifdef EXAMPLE_PCINT_vect /** * \brief Pin change interrupt handler for PB0 * * Create breakpoint here and then run. Press SW0 in order to test * this. */ ISR(EXAMPLE_PCINT_vect) { /* Toggle PD0 (LED0) * * Note that it will toggle both on button press and release. */ PIND = (1 << PIND0); } #endif /** * \brief Main routine */ int main(void) { // Variable to put switch input into uint8_t val; /* Use port D for output to control the STK600 LEDs. * * First set the data direction register to 0xff in order to set all * port pins to output function. */ DDRD = 0xff; // Set output levels high. Will turn off STK600 LEDs. PORTD = 0xff; // Set output levels low. Will turn on STK600 LEDs. PORTD = 0; /* For input we use port B in order to read input from the STK600 * switches. * * We don't need to set these pins to input after reset since they * are default set as inputs after reset. * * But a typical requirement when reading switches are pull-ups. STK600 * don't require these, but we enable the internal pull-ups just to be * on the safe side. */ PORTB = 0xff; /* Read STK600 switches on port B inputs into a variable. * * Press any of the STK600 switches in order to see a difference here. * A press will be seen as bit value 0 and not press is 1 due to * pull-ups. */ val = PINB; /* It's also possible to control a single or a set of pins on a port. * * Setting pin PD0 high in order to turn off LED0. */ PORTD |= (1 << PORTD0); // Setting pin PD1 low in order to turn on LED1. PORTD &= ~(1 << PORTD1); // Toggle both pin PD0 and PD1, which toggles LED0 and LED1. #if defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ || defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) /* For older megaAVR devices read-modify-write PORT register. * This isn't safe for interrupts. */ PORTD ^= (1 << PIND0) | (1 << PIND1); #else // Use PIN register to toggle on newer megaAVR devices PIND = (1 << PIND0) | (1 << PIND1); #endif // Only use Pin Change Interrupt handler for devices supporting this. #ifdef EXAMPLE_PCICR /* Enable pin change interrupt for PB0 which is controlled by SW0 * * First we need to enable pin change interrupt for the wanted port. */ EXAMPLE_PCICR = (1 << EXAMPLE_PCIE); // Then we need to set the pin change port mask to get the bit we want. EXAMPLE_PCMSK = (1 << PCINT0); #endif // Enable interrupts sei(); /* Busy loop, and a breakpoint can be used in the interrupt handler to * see interrupts being triggered by SW0. */ while (true); }