AVR32 UC3C на основе прерывания USART

Я пытаюсь связаться с помощью USART (rs232) через AVR32 UC3C. Я следовал образцу, указанному в ссылке - http://simplemachines.it/martin/mizar32/1.6.0-AT32UC3/DRIVERS/INTC/EXAMPLE/interrupt_usart_example.c.

/* This source file is part of the ATMEL AVR32-UC3-SoftwareFramework-1.6.0 Release */

/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
 *
 * \brief Example of an interrupt-driven USART communication.
 *
 * This file contains an example using the USART module with interrupts.
 *
 * It will display a string on the screen. Refer to the usart_options structure
 * in main for configuration options for your terminal.
 *
 * Please make sure that the correct jumper(s) is/are set on your development
 * board. Refer to your hardware reference guide if necessary.
 *
 * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32
 * - Supported devices:  All AVR32 devices with an INTC module can be used.
 * - AppNote:
 *
 * \author               Atmel Corporation: http://www.atmel.com \n
 *                       Support and FAQ: http://support.atmel.no/
 *
 ******************************************************************************/

/*! \page License
 * Copyright (c) 2009 Atmel Corporation. All rights reserved.
 *
 * 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
 * AVR 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
 *
 */

/*! \mainpage
 * \section intro Introduction
 * This is the documentation for the data structures, functions, variables,
 * defines, enums, and typedefs for the interrupt controller driver. It also
 * comes bundled with a basic application as an example of usage.
 *
 * This example demonstrates how to use the INTC driver for the USART RXRDY
 * interrupt.
 *
 * Operating mode: each character typed on the PC terminal is echoed back.
 *
 * \note The IAR built-in event handling mechanism manages interrupt groups but
 * not lines. This example shows how to register an interrupt through the INTC
 * driver, which manages lines. If interrupt request lines do not have to be
 * handled separately within groups, then the IAR built-in event handling
 * mechanism can be used in this way:
 *   - remove the INTC driver files (intc.c and exception.s82) from the IAR
 *     project;
 *   - remove calls to the INTC driver functions (\ref INTC_init_interrupts and
 *     \ref INTC_register_interrupt);
 *   - add <tt>\#pragma handler = \e AVR32_xxxx_IRQ_GROUP, \e int_level</tt>
 *     above the \c __interrupt keyword;
 *   - the IAR project options can be changed to catch unhandled events under
 *     the \e Runtime tab of the <i>General Options</i> item.
 *
 * \warning The IAR built-in event handling mechanism
 *          (<tt>\#pragma exception</tt> and <tt>\#pragma handler</tt>) MUST NOT
 *          be used along with the INTC driver within a project.
 *
 * \section files Main Files
 *   - intc.c: interrupt controller driver;
 *   - intc.h: interrupt controller driver header file;
 *   - exception.S: exception and interrupt handlers assembly file for GCC;
 *   - interrupt_usart_example.c: interrupt controller example application.
 *
 * \section compilinfo Compilation Information
 * This software is written for GNU GCC for AVR32 and for IAR Embedded Workbench
 * for Atmel AVR32. Other compilers may or may not work.
 *
 * \section deviceinfo Device Information
 * All AVR32 devices with an INTC and a USART module can be used.
 *
 * \section configinfo Configuration Information
 * This example has been tested with the following configuration:
 *   - EVK1100, EVK1101, EVK1103, EVK1104, EVK1105, AT32UC3L-EK evaluation kits; STK600+RCUC3L routing card
 *   - CPU clock: 
 *        -- 12 MHz : EVK1100, EVK1101, EVK1104, EVK1105, AT32UC3L-EK evaluation kits; STK600+RCUC3L routing card;
 *        -- 16 Mhz : UC3C_EK 
 *   - USART0 (on EVK1100) or USART1 (on EVK1101 or STK1000) connected to a PC
 *     serial port via a standard RS232 DB9 cable, or USART0 (on EVK1105) or
 *     USART1 (on EVK1104) or USART2 (on EVK1103) or USART3 (on AT32UC3L-EK) abstracted
 *     with a USB CDC connection to a PC;
 *   - PC terminal settings:
 *     - 57600 bps (on EVK1100, EVK1101, AT32UC3C-EK, EVK1104, EVK1105, AT32UC3L-EK) or 115200 bps (on
 *       STK1000),
 *     - 8 data bits,
 *     - no parity bit,
 *     - 1 stop bit,
 *     - no flow control.
 *
 * \section contactinfo Contact Information
 * For further information, visit
 * <A href="http://www.atmel.com/products/AVR32/">Atmel AVR32</A>.\n
 * Support and FAQ: http://support.atmel.no/
 */


#include <avr32/io.h>
#include "compiler.h"
#include "board.h"
#include "print_funcs.h"
#include "intc.h"
#if defined (__GNUC__)
#  if   defined (__AVR32_AP7000__)
#    include "pm_at32ap7000.h"
#  else
#    include "power_clocks_lib.h"
#  endif
#elif defined (__ICCAVR32__) || defined (__AAVR32__)
#  if  defined (__AT32AP7000__)
#    include "pm_at32ap7000.h"
#  else
#    include "power_clocks_lib.h"
#  endif
#endif
#include "gpio.h"
#include "usart.h"


/*! \name USART Settings
 */
//! @{
#if BOARD == EVK1100
#  define EXAMPLE_USART                 (&AVR32_USART0)
#  define EXAMPLE_USART_RX_PIN          AVR32_USART0_RXD_0_0_PIN
#  define EXAMPLE_USART_RX_FUNCTION     AVR32_USART0_RXD_0_0_FUNCTION
#  define EXAMPLE_USART_TX_PIN          AVR32_USART0_TXD_0_0_PIN
#  define EXAMPLE_USART_TX_FUNCTION     AVR32_USART0_TXD_0_0_FUNCTION
#  define EXAMPLE_USART_IRQ             AVR32_USART0_IRQ
#  define EXAMPLE_USART_BAUDRATE        57600
#  define EXAMPLE_TARGET_PBACLK_FREQ_HZ FOSC0  // PBA clock target frequency, in Hz
#elif BOARD == EVK1101
#  define EXAMPLE_USART                 (&AVR32_USART1)
#  define EXAMPLE_USART_RX_PIN          AVR32_USART1_RXD_0_0_PIN
#  define EXAMPLE_USART_RX_FUNCTION     AVR32_USART1_RXD_0_0_FUNCTION
#  define EXAMPLE_USART_TX_PIN          AVR32_USART1_TXD_0_0_PIN
#  define EXAMPLE_USART_TX_FUNCTION     AVR32_USART1_TXD_0_0_FUNCTION
#  define EXAMPLE_USART_IRQ             AVR32_USART1_IRQ
#  define EXAMPLE_USART_BAUDRATE        57600
#  define EXAMPLE_TARGET_PBACLK_FREQ_HZ FOSC0  // PBA clock target frequency, in Hz
#elif BOARD == UC3C_EK
#  define EXAMPLE_USART                 (&AVR32_USART2)
#  define EXAMPLE_USART_RX_PIN          AVR32_USART2_RXD_0_1_PIN
#  define EXAMPLE_USART_RX_FUNCTION     AVR32_USART2_RXD_0_1_FUNCTION
#  define EXAMPLE_USART_TX_PIN          AVR32_USART2_TXD_0_1_PIN
#  define EXAMPLE_USART_TX_FUNCTION     AVR32_USART2_TXD_0_1_FUNCTION
#  define EXAMPLE_USART_IRQ             AVR32_USART2_IRQ
#  define EXAMPLE_USART_BAUDRATE        57600
#  define EXAMPLE_TARGET_PBACLK_FREQ_HZ FOSC0  // PBA clock target frequency, in Hz
#elif BOARD == EVK1104
#  define EXAMPLE_USART                 (&AVR32_USART1)
#  define EXAMPLE_USART_RX_PIN          AVR32_USART1_RXD_0_0_PIN
#  define EXAMPLE_USART_RX_FUNCTION     AVR32_USART1_RXD_0_0_FUNCTION
#  define EXAMPLE_USART_TX_PIN          AVR32_USART1_TXD_0_0_PIN
#  define EXAMPLE_USART_TX_FUNCTION     AVR32_USART1_TXD_0_0_FUNCTION
#  define EXAMPLE_USART_IRQ             AVR32_USART1_IRQ
#  define EXAMPLE_USART_BAUDRATE        57600
#  define EXAMPLE_TARGET_PBACLK_FREQ_HZ FOSC0  // PBA clock target frequency, in Hz
#elif BOARD == EVK1105
#  define EXAMPLE_USART                 (&AVR32_USART0)
#  define EXAMPLE_USART_RX_PIN          AVR32_USART0_RXD_0_0_PIN
#  define EXAMPLE_USART_RX_FUNCTION     AVR32_USART0_RXD_0_0_FUNCTION
#  define EXAMPLE_USART_TX_PIN          AVR32_USART0_TXD_0_0_PIN
#  define EXAMPLE_USART_TX_FUNCTION     AVR32_USART0_TXD_0_0_FUNCTION
#  define EXAMPLE_USART_IRQ             AVR32_USART0_IRQ
#  define EXAMPLE_USART_BAUDRATE        57600
#  define EXAMPLE_TARGET_PBACLK_FREQ_HZ FOSC0  // PBA clock target frequency, in Hz
#elif BOARD == STK1000
#  define EXAMPLE_USART                 (&AVR32_USART1)
#  define EXAMPLE_USART_RX_PIN          AVR32_USART1_RXD_0_PIN
#  define EXAMPLE_USART_RX_FUNCTION     AVR32_USART1_RXD_0_FUNCTION
#  define EXAMPLE_USART_TX_PIN          AVR32_USART1_TXD_0_PIN
#  define EXAMPLE_USART_TX_FUNCTION     AVR32_USART1_TXD_0_FUNCTION
#  define EXAMPLE_USART_IRQ             AVR32_USART1_IRQ
#  define EXAMPLE_USART_BAUDRATE        115200
#  define EXAMPLE_TARGET_PBACLK_FREQ_HZ FOSC0  // PBA clock target frequency, in Hz
#elif BOARD == NGW100
#  define EXAMPLE_USART                 (&AVR32_USART1)
#  define EXAMPLE_USART_RX_PIN          AVR32_USART1_RXD_0_PIN
#  define EXAMPLE_USART_RX_FUNCTION     AVR32_USART1_RXD_0_FUNCTION
#  define EXAMPLE_USART_TX_PIN          AVR32_USART1_TXD_0_PIN
#  define EXAMPLE_USART_TX_FUNCTION     AVR32_USART1_TXD_0_FUNCTION
#  define EXAMPLE_USART_IRQ             AVR32_USART1_IRQ
#  define EXAMPLE_USART_BAUDRATE        115200
#  define EXAMPLE_TARGET_PBACLK_FREQ_HZ FOSC0  // PBA clock target frequency, in Hz
#elif BOARD == STK600_RCUC3L0
#  define EXAMPLE_USART                 (&AVR32_USART1)
#  define EXAMPLE_USART_RX_PIN          AVR32_USART1_RXD_0_1_PIN
#  define EXAMPLE_USART_RX_FUNCTION     AVR32_USART1_RXD_0_1_FUNCTION
// For the RX pin, connect STK600.PORTE.PE3 to STK600.RS232 SPARE.RXD
#  define EXAMPLE_USART_TX_PIN          AVR32_USART1_TXD_0_1_PIN
#  define EXAMPLE_USART_TX_FUNCTION     AVR32_USART1_TXD_0_1_FUNCTION
// For the TX pin, connect STK600.PORTE.PE2 to STK600.RS232 SPARE.TXD
#  define EXAMPLE_USART_IRQ             AVR32_USART1_IRQ
#  define EXAMPLE_USART_BAUDRATE        57600
#  define EXAMPLE_TARGET_PBACLK_FREQ_HZ FOSC0  // PBA clock target frequency, in Hz
#elif BOARD == UC3L_EK
#  define EXAMPLE_USART                 (&AVR32_USART3)
#  define EXAMPLE_USART_RX_PIN          AVR32_USART3_RXD_0_0_PIN
#  define EXAMPLE_USART_RX_FUNCTION     AVR32_USART3_RXD_0_0_FUNCTION
#  define EXAMPLE_USART_TX_PIN          AVR32_USART3_TXD_0_0_PIN
#  define EXAMPLE_USART_TX_FUNCTION     AVR32_USART3_TXD_0_0_FUNCTION
#  define EXAMPLE_USART_IRQ             AVR32_USART3_IRQ
#  define EXAMPLE_USART_BAUDRATE        57600
#  define EXAMPLE_TARGET_DFLL_FREQ_HZ   96000000  // DFLL target frequency, in Hz
#  define EXAMPLE_TARGET_MCUCLK_FREQ_HZ 12000000  // MCU clock target frequency, in Hz
#  undef  EXAMPLE_TARGET_PBACLK_FREQ_HZ
#  define EXAMPLE_TARGET_PBACLK_FREQ_HZ 12000000  // PBA clock target frequency, in Hz
    /*! \name Parameters to pcl_configure_clocks().
     */
    //! @{
    static scif_gclk_opt_t gc_dfllif_ref_opt = { SCIF_GCCTRL_SLOWCLOCK, 0, OFF };
    static pcl_freq_param_t pcl_dfll_freq_param =
    {
      .main_clk_src = PCL_MC_DFLL0,
      .cpu_f        = EXAMPLE_TARGET_MCUCLK_FREQ_HZ,
      .pba_f        = EXAMPLE_TARGET_PBACLK_FREQ_HZ,
      .pbb_f        = EXAMPLE_TARGET_PBACLK_FREQ_HZ,
      .dfll_f       = EXAMPLE_TARGET_DFLL_FREQ_HZ,
      .pextra_params = &gc_dfllif_ref_opt
    };
    //! @}
#endif
//! @}


/*! \brief The USART interrupt handler.
 *
 * \note The `__attribute__((__interrupt__))' (under GNU GCC for AVR32) and
 *       `__interrupt' (under IAR Embedded Workbench for Atmel AVR32) C function
 *       attributes are used to manage the `rete' instruction.
 */
#if defined (__GNUC__)
__attribute__((__interrupt__))
#elif defined(__ICCAVR32__)
__interrupt
#endif
static void usart_int_handler(void)
{
  int c;

  // In the code line below, the interrupt priority level does not need to be
  // explicitly masked as it is already because we are within the interrupt
  // handler.
  // The USART Rx interrupt flag is cleared by side effect when reading the
  // received character.
  // Waiting until the interrupt has actually been cleared is here useless as
  // the call to usart_write_char will take enough time for this before the
  // interrupt handler is leaved and the interrupt priority level is unmasked by
  // the CPU.
  usart_read_char(EXAMPLE_USART, &c);

  // Print the received character to USART.
  // It is a simple echo, so there will be no translation of '\r' to "\r\n". The
  // connected terminal has to be configured accordingly to send '\n' after
  // '\r'.
  usart_write_char(EXAMPLE_USART, c);
}


/*! \brief The main function.
 *
 * It sets up the USART module on EXAMPLE_USART. The terminal settings are 57600
 * 8N1.
 * Then it sets up the interrupt handler and waits for a USART interrupt to
 * trigger.
 */
int main(void)
{
  static const gpio_map_t USART_GPIO_MAP =
  {
    {EXAMPLE_USART_RX_PIN, EXAMPLE_USART_RX_FUNCTION},
    {EXAMPLE_USART_TX_PIN, EXAMPLE_USART_TX_FUNCTION}
  };

  // USART options.
  static const usart_options_t USART_OPTIONS =
  {
    .baudrate     = EXAMPLE_USART_BAUDRATE,
    .charlength   = 8,
    .paritytype   = USART_NO_PARITY,
    .stopbits     = USART_1_STOPBIT,
    .channelmode  = USART_NORMAL_CHMODE
  };

#if BOARD == EVK1100 || BOARD == EVK1101 || BOARD == UC3C_EK || BOARD == EVK1104 || BOARD == EVK1105 || BOARD == STK600_RCUC3L0

  // Configure Osc0 in crystal mode (i.e. use of an external crystal source, with
  // frequency FOSC0) with an appropriate startup time then switch the main clock
  // source to Osc0.
  pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);

#elif BOARD == STK1000
  pm_reset();
#elif BOARD == UC3L_EK
  // Note: on the AT32UC3L-EK board, there is no crystal/external clock connected
  // to the OSC0 pinout XIN0/XOUT0. We shall then program the DFLL and switch the
  // main clock source to the DFLL.
  pcl_configure_clocks(&pcl_dfll_freq_param);
  // Note: since it is dynamically computing the appropriate field values of the
  // configuration registers from the parameters structure, this function is not
  // optimal in terms of code size. For a code size optimal solution, it is better
  // to create a new function from pcl_configure_clocks_dfll0() and modify it
  // to use preprocessor computation from pre-defined target frequencies.
#endif

  // Assign GPIO to USART.
  gpio_enable_module(USART_GPIO_MAP,
                     sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0]));

  // Initialize USART in RS232 mode.
  usart_init_rs232(EXAMPLE_USART, &USART_OPTIONS, EXAMPLE_TARGET_PBACLK_FREQ_HZ);
  print(EXAMPLE_USART, ".: Using interrupts with the USART :.\n\n");

  // Disable all interrupts.
  Disable_global_interrupt();

  // Initialize interrupt vectors.
  INTC_init_interrupts();

  // Register the USART interrupt handler to the interrupt controller.
  // usart_int_handler is the interrupt handler to register.
  // EXAMPLE_USART_IRQ is the IRQ of the interrupt handler to register.
  // AVR32_INTC_INT0 is the interrupt priority level to assign to the group of
  // this IRQ.
  // void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_level);
  INTC_register_interrupt(&usart_int_handler, EXAMPLE_USART_IRQ, AVR32_INTC_INT0);

  // Enable USART Rx interrupt.
  EXAMPLE_USART->ier = AVR32_USART_IER_RXRDY_MASK;
  print(EXAMPLE_USART, "Type a character to use the interrupt handler.\n"
                       "It will show up on your screen.\n\n");

  // Enable all interrupts.
  Enable_global_interrupt();

  // We have nothing left to do in the main, so we may switch to a device sleep
  // mode: we just need to be sure that the USART module will be still be active
  // in the chosen sleep mode. The sleep mode to use is the FROZEN sleep mode:
  // in this mode the PB clocks are still active (so the USART module which is
  // on the Peripheral Bus will still be active while the CPU and HSB will be
  // stopped).
  // --
  // Modules communicating with external circuits should normally be disabled
  // before entering a sleep mode that will stop the module operation: this is not
  // the case for the FROZEN sleep mode.
  // --
  // When the USART interrupt occurs, this will wake the CPU up which will then
  // execute the interrupt handler code then come back to the while(1) loop below
  // to execute the sleep instruction again.

  while(1)
  {
    // If there is a chance that any PB write operations are incomplete, the CPU
    // should perform a read operation from any register on the PB bus before
    // executing the sleep instruction.
    AVR32_INTC.ipr[0];  // Dummy read

    // Go to FROZEN sleep mode.
    SLEEP(AVR32_PM_SMODE_FROZEN);
    // When the device wakes up due to an interrupt, once the interrupt is serviced,
    // go back into FROZEN sleep mode.
  }
}

Он активировал мой USART, а также прерывания, но я постоянно получаю прерывания без какой-либо передачи данных из другого модуля. Мне сказали, что функция usart_read_char() очистит бит состояния прерывания.

Будет хорошо, если кто-нибудь направит меня сюда. У кого-нибудь есть рабочий пример кода для UART?


person Vishal    schedule 23.09.2014    source источник
comment
Было бы лучше включить ваш код в свой вопрос, а не просить пользователей SO загрузить файл вашего кода. Это также упростило бы добавление комментариев к коду и указание, где что-то работает, а где нет.   -  person skrrgwasme    schedule 23.09.2014
comment
просто глупый вопрос, но вы скрестили TX и RX? Вы проверили, выводите ли вы что-то? (с помощью осциллографа или с помощью 2 встречно-параллельных светодиодов) вам необходимо установить правильную плату, макросы чипа. правильные часы запущены, модуль GPIO и контакты настроены ... и т. д. ... если ваши контакты RX / TX установлены как GPIO, то они не подключены к последовательному порту ....   -  person Spektre    schedule 02.07.2015


Ответы (1)


От: http://www.avrfreaks.net/forum/usart-rx-interrupts-at32uc3c0

usart_read_char() НЕ очищает флаг состояния, если произошла ошибка (переполнение, ошибка кадра или четности), т. е. если usart_read_char() == USART_RX_ERROR. В этом случае вам нужно самостоятельно сбросить бит состояния, написав usart_reset_status(YOUR_USART);

так что-то вроде

if (usart_read_char(YOUR_USART, character) == USART_RX_ERROR) {
      usart_reset_status(YOUR_USART);
} else {
    //Handle the character read here
}

Обсуждение, связанное выше, предлагает еще несколько советов.

person Wilco    schedule 06.08.2015