我遇到了一些麻烦,我不知道这是我对 Atmel 语法、Atmel Studio 6.0 还是程序本身的理解。我似乎无法让中断处理程序接收一个简单的字符串然后做点什么。当 USART 接收到一个字符时,它会打开 LED,然后如果它接收到不同的字符,它会关闭 LED,我成功地实现了单个字符打开 LED。顺便说一句,我有一个设计板,程序在进入接收子例程时遇到了一些麻烦,因为主程序中的发送代码太大,所以建议我利用中断来解决这个问题。顺便说一句,我正在 EVK1100 AVR32 板 MCU:AT32UC3A0512-U 上试用这个程序,不知道你们中是否有人玩过这些,但它们非常棒。不确定我是否喜欢 Atmel 语法。反正,
我对 Atmel 世界的中断还很陌生。
任何帮助将非常感激。我只对内置的 ASF USART 中断“INTC”项目示例进行了一些修改。
谢谢,
#include <string.h>
#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"
//#include "conf_example.h"
# define EXAMPLE_TARGET_PBACLK_FREQ_HZ FOSC0 // PBA clock target frequency, in Hz
#if BOARD == EVK1100
# 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_CLOCK_MASK AVR32_USART1_CLK_PBA
# define EXAMPLE_PDCA_CLOCK_HSB AVR32_PDCA_CLK_HSB
# define EXAMPLE_PDCA_CLOCK_PB AVR32_PDCA_CLK_PBA
# define EXAMPLE_USART_IRQ AVR32_USART1_IRQ
# define EXAMPLE_USART_BAUDRATE 57600
#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)
{
static char Cmnd[30];
int index = 0;
int c;
usart_read_char(EXAMPLE_USART, &c);
Cmnd[index++] = c;
if (c = '\r')
{
Cmnd[index] = '\0';
usart_write_line(EXAMPLE_USART, Cmnd);
}
}
/**
* \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 = 57600,
.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 \
|| BOARD == STK600_RCUC3D
/*
* 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.
*/
#end if
// 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 :.\r\n\r\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.
*/
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."
"\r\nIt will show up on your screen.\r\n\r\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
/*
* When the device wakes up due to an interrupt, once the
* interrupt has been serviced, go back into FROZEN sleep mode.
*/
}
}