2016-05-16 166 views
0

在解释的专业开发板上发现Atmel SAMB11存在问题。我已经加载了一个来自Atmel的非常简单的例子,其中32KHz定时器被初始化以从睡眠中唤醒μC并打开LED。问题是,控制器根本没有睡觉。它只是立即激活LED,不会等待中断。Cortex M0未进入睡眠模式

#include <asf.h> 

// Callback Func to enable LED 
static void aon_sleep_timer_callback(void) 
{ 
    gpio_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE); 
} 
//Configure LED 
static void configure_gpio_pins(void) 
{ 
    struct gpio_config config_gpio_pin; 
    gpio_get_config_defaults(&config_gpio_pin); 
    config_gpio_pin.direction = GPIO_PIN_DIR_OUTPUT; 
    gpio_pin_set_config(LED_0_PIN, &config_gpio_pin); 
    gpio_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE); 
} 
// Configure Timer with 10sec to overflow 
static void configure_aon_sleep_timer(void) 
{ 
    struct aon_sleep_timer_config config_aon_sleep_timer; 
    aon_sleep_timer_get_config_defaults(&config_aon_sleep_timer); 
    config_aon_sleep_timer.counter = 320000; // Wait about 10sec 
    aon_sleep_timer_init(&config_aon_sleep_timer); 
} 
// Configure Callback and enable Interrupt 
static void configure_aon_sleep_timer_callback(void) 
{ 
    aon_sleep_timer_register_callback(aon_sleep_timer_callback); 
    NVIC_EnableIRQ(AON_SLEEP_TIMER_IRQn); 
} 

int main(void) 
{ 
    // Setup Clock, LED and Timer 
    system_clock_config(CLOCK_RESOURCE_XO_26_MHZ, CLOCK_FREQ_26_MHZ); 
    configure_gpio_pins(); 
    configure_aon_sleep_timer(); 
    configure_aon_sleep_timer_callback(); 

    // wait for timer to be active 
    while(!aon_sleep_timer_sleep_timer_active()); 
    // Go to sleep 
    asm volatile ("wfi"); 
    asm volatile ("nop"); 
    // Enable LED immediately if sleep doesn't work 
    gpio_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE); 
    while (true) {} 
} 

代码似乎不言自明,但WFI命令在这里不起作用。任何人都可以帮忙

+1

'aon_sleep_timer_sleep_timer_active()'做了什么 - 它只是轮询一个状态寄存器或什么?使用两个不同的LED会很方便,因此您可以判断您是实际上是在立即采取中断还是由于其他事件而中断。 – Notlikethat

回答

0

WFI调用起作用,它在调用后几乎立即收到一个中断,这会导致WFI调用停止阻塞,然后继续执行到下一行。

你可以安全地删除所有低于// Go to sleep的东西,这将允许主函数返回。 AON计时器仍然会执行其回调。但是,这种方法存在一些潜在的缺点:

  • 这将不允许SAMB11转换到较低功耗模式。
  • 这将删除您在主循环结束时的while循环。在当前状态下,while循环不是必需的,但您可能有计划稍后添加代码。

下面是配置AON,配置SAMB11使用低功耗模式,然后循环等待平台和/或BLE事件的示例。目前没有任何循环接收事件。如果您希望回路接收事件,则可以修改AON回调以使用at_ble_event_user_defined_post函数发布事件或修改main()以在进入回路之前配置BLE模块。

使用ASF向导将任何BLE模块添加到您的项目中以编译此示例。

#include <asf.h> 
#include "platform.h" 

// Configure LED 
static void configure_gpio_pins(void) 
{ 
    struct gpio_config config_gpio_pin; 
    gpio_get_config_defaults(&config_gpio_pin); 
    config_gpio_pin.direction = GPIO_PIN_DIR_OUTPUT; 
    gpio_pin_set_config(LED_0_PIN, &config_gpio_pin); 
    gpio_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE); 
} 

// Callback Func to toggle LED 
static bool led_is_on = false; 
static void aon_sleep_timer_callback(void) 
{ 
    configure_gpio_pins(); 
    if(led_is_on) { 
     gpio_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE); 
     led_is_on = false; 
    } else { 
     gpio_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE); 
     led_is_on = true; 
    } 
} 

// Configure Timer to fire periodically 
static void configure_aon_sleep_timer(void) 
{ 
    struct aon_sleep_timer_config config_aon_sleep_timer; 
    aon_sleep_timer_get_config_defaults(&config_aon_sleep_timer); 
    config_aon_sleep_timer.counter = 32000; // Wait about 1 sec 
    config_aon_sleep_timer.mode = AON_SLEEP_TIMER_RELOAD_MODE; 
    aon_sleep_timer_init(&config_aon_sleep_timer); 
} 
// Configure Callback and enable Interrupt 
static void configure_aon_sleep_timer_callback(void) 
{ 
    aon_sleep_timer_register_callback(aon_sleep_timer_callback); 
    NVIC_EnableIRQ(AON_SLEEP_TIMER0_IRQn); 
} 

int main(void) 
{ 
    // Setup Clock 
    system_clock_config(CLOCK_RESOURCE_XO_26_MHZ, CLOCK_FREQ_26_MHZ); 

    plf_drv_status plf_status; 
    if((plf_status = platform_driver_init()) == STATUS_SUCCESS) { 

     // Setup LED and Timer 
     configure_gpio_pins(); 
     configure_aon_sleep_timer(); 
     configure_aon_sleep_timer_callback(); 

     // wait for timer to be active 
     while(!aon_sleep_timer_sleep_timer_active()); 

     // Go to sleep 
     release_sleep_lock(); 
     while(true) { 
      // Replace platform_event_wait with at_ble_event_get if you would like to read the received event. 
      plf_status = platform_event_wait(0); 
     } 
    } 
} 

关于WFI,下面的示例示出了如何关闭大多数中断,并使用WFI到方框main()。每次接收到中断时,LED都会切换。我不建议使用这个,因为我不确定为什么最初启用这些中断。这只是为了显示WFI如何在SAMB11上阻塞。

#include <asf.h> 
#include "platform.h" 

// Configure LED 
static void configure_gpio_pins(void) 
{ 
    struct gpio_config config_gpio_pin; 
    gpio_get_config_defaults(&config_gpio_pin); 
    config_gpio_pin.direction = GPIO_PIN_DIR_OUTPUT; 
    gpio_pin_set_config(LED_0_PIN, &config_gpio_pin); 
    gpio_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE); 
} 

// Callback Func to toggle LED 
static bool led_is_on = false; 
static void toggle_led(void) 
{ 
    configure_gpio_pins(); 
    if(led_is_on) { 
     gpio_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE); 
     led_is_on = false; 
    } else { 
     gpio_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE); 
     led_is_on = true; 
    } 
} 

int main(void) 
{ 
    // Setup Clock 
    system_clock_config(CLOCK_RESOURCE_XO_26_MHZ, CLOCK_FREQ_26_MHZ); 

    // Clear all interrupts. 
    NVIC->ICER[0] = 0xFFFFFFFF; 

    // During testing, interrupts were received about once per second; stopped receiving interrupts (LED stopped flashing) after about 2 minutes. 
    int loop_count = 0; 
    while(true) { 
     __WFI(); 
     toggle_led(); 
    } 
} 
0

只是要添加到由Prestige Worldwide的答案。

确保AO_GPIO0/1/2为低电平(建议下拉),并且没有发生AON睡眠定时器中断,因为它们会将SAMB11从ULP中唤醒。

另请注意,在SWD上运行调试会话时,ULP模式似乎无法按预期工作。

当运行调试和睡眠/唤醒时,我有各种奇怪的行为,但在没有调试时运行相同的代码时根本没有问题。请注意,这是使用Atmel ICE。 Xplored板包含EDBG,这个调试器似乎可以与ULP一起工作。

简历回调从未为我解雇过,也许是ASF中的一个bug。但我不需要它,因为我可以在平台等待后安装所有GPIO /设备。

+0

这不提供问题的答案。一旦你有足够的[声誉](http://stackoverflow.com/help/whats-reputation),你将能够[评论任何职位](http://stackoverflow.com/help/privileges/comment);相反,[提供不需要提问者澄清的答案](http://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-c​​an- I-DO-代替)。 - [来自评论](/ review/low-quality-posts/13200186) – Inian

+0

我已经提供了3个原因,为什么'Cortex M0不能进入睡眠模式'会出现,作者需要检查它是否能够解决问题。这不是一个答案? –