c - avr sleep 模式和唤醒

标签 c avr

我正在尝试让我的 AtTiny 13 进入休眠状态并通过中断唤醒它。它确实进入休眠状态,但永远不会醒来。整个代码:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <avr/sleep.h>

#define RED (1<<PB4)
#define RED_HIGH PORTB |=RED
#define RED_LOW PORTB &= ~RED
#define RED_TOG PORTB ^= RED

#define BUTTON 1<<PB1

volatile static bool is_sleeping;

ISR(INT0_vect)
{
    RED_TOG;
    is_sleeping = true;
}

int main(void){

    GIMSK |= 1<<INT0;
    MCUCR |= 0<<ISC00 | 1<<ISC01;
    sei();

    DDRB |= RED;
    DDRB &= ~BUTTON;
    PORTB |= BUTTON;

    RED_HIGH;
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

    while(1){
        if(is_sleeping){
            sleep_enable();
            sei();
            sleep_cpu();
            sleep_disable();
        }
    }
}

根据 sleep.h 数据,它应该可以工作。有什么想法吗?

更新:从IDLE模式唤醒没有问题;

最佳答案

假设没有硬件接线问题,您的代码将按如下方式工作:启动后,您的 LED 亮起,并且 while 循环自 is_sleeping 起空闲。最初设置为零。第一个 INT0 中断切换 LED(将其关闭)并设置 is_sleeping标志,以便 while 循环在下一轮进入 protected 代码。该代码使 MCU 进入休眠状态 sleep_mcu()线。一旦 INT0 中断等待 MCU,它就会从最后一个位置继续,即它会返回 sleep 状态,因为 is_sleeping仍然设置! (并且在您的代码中永远不会变回 false)。这意味着 MCU 唤醒后几乎立即进入休眠状态,并关闭直到下一个 INT0 中断。

所以回答你的问题它永远不会醒来我会说:它确实会醒来,但时间很短。如果您测量电流(例如使用示波器和分流电阻器),您会在电流唤醒和立即休眠时观察到尖峰。

无论你的主要问题是什么,都要注意代码质量。嵌入式编程绝不是宽容的,您可能会因为一些微不足道的错误而陷入数小时的困境。例如,始终对宏定义保持防御态度。您定义了BUTTON1<<PB1没有括号。不同之处在于,稍后您会受到运算符优先级的影响。例如使用 DDRB &= ~BUTTON你没有得到你所期望的。你的右侧表情展开为 11111100 (因为 ~1<<111111110 << 1 )而你想要 11111101 (因为 ~(1<<1)~ 00000010 )。如果您将 PB0 用于其他用途,您可能会遇到不需要的行为。

此外,在复制示例代码时,请确保您了解它的含义。 sleep.h中的样本依赖于同时使用 seicli补充。在您的代码中,您只坚持在循环中重新启用中断,这在这里毫无意义。

编辑:由于您声称唤醒工作在“空闲”模式下,那么您的下一个问题是您希望系统通过设置对(ISC00,ISC01)在下降沿唤醒。至(0,1)MCUCR 。请参阅数据表第 9.2 章“请注意,识别 INT0 上的下降沿或上升沿中断需要存在 I/O 时钟”,而第 7.1 章中的表则指出“Clk_I/0 不存在” 在掉电模式下。您唯一的选择是通过设置对 (ISC00,ISC01) 使 INT0 外部中断在低电平触发。至(0,0)MCUCR .

关于c - avr sleep 模式和唤醒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47504614/

相关文章:

c - 将文本写入多个c文件中的单个文本文件

c - AVR 如何执行浮点运算

c - 停止字符串数组

eclipse - Xcode 4 的 AVR?

avr - 在atmel studio7中更改起始地址.hex

C:使用单个#define 传递两个逗号分隔的值

c++ - 指针间接问题

c - 使用结构体的函数会导致段错误

c - 试图修复有关 ‘const’ 限定符的警告

python - 如何使用正则表达式检测无效的 C 转义字符串?