我遇到了一些麻烦,我不知道这是我对Atmel语法、Atmel Studio 6.0或程序本身的理解。我似乎无法让中断处理程序接收一个简单的字符串,然后执行一些操作。当USART接收到一个字符打开LED时,我成功地实现了一个字符打开LED,然后如果它收到一个不同的字符,就会关闭LED。顺便说一下,我有一个设计板,程序在到达接收子例程时遇到了一些问题,因为主程序中的发送代码太大了,所以建议我利用中断来解决这个问题。顺便说一句,我正在EVK1100 AVR32板单片机上试用这个程序:AT32UC3A0512-U,不知道你们中是否有人以前玩过这些,但它们非常棒。不过,我不太喜欢Atmel语法。不管怎么说,你可以看到,我正在做的主要是在目前,直到我得到接收部分工作。
在爱特梅尔的世界里,我是刚被打断的。
任何帮助都将不胜感激。我只对ASF中构建的"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.
*/
}
} 发布于 2013-09-10 16:29:58
尽量缩短中断处理程序。中断处理程序或ISR通常在中断禁用的情况下执行。他们的目标是进去,做点什么,然后迅速离开。如果您在运行其他中断(例如,实时时钟),则在ISR期间它们会被屏蔽,这可能会导致诸如丢失中断之类的问题。
这里最好的方法是将输入缓冲区声明为全局静态。还定义一个static uchar_t have_line或类似的,在ISR中,保存每个字符直到缓冲区满(一个重要的检查!),或者您收到一个CR (\r)。还检查换行符(\n)。将零保存为null-终止缓冲区,然后设置have_line = 1。
在主循环中,等待have_line为非零,然后处理输入缓冲区中的内容。最后,将have_line设置为零。
这样,您的ISR是简短和相当健壮的。
在示例代码中,函数usart_write_line是否需要启用中断?
糟了!对不起,我注意到您的索引不是静态变量。这意味着每次调用例程时,它都将初始化为零。在int索引前面添加一个静态声明符,这应该会解决这个问题。
https://stackoverflow.com/questions/15691293
复制相似问题