chenxp99 发表于 2014-4-8 14:08:22

给《会说话的单片机》增加时序控制,遇障碍求指点

本帖最后由 chenxp99 于 2014-4-8 18:01 编辑

目标:循环播放 XX s后休眠XXX,再唤醒再次循环
实际运行始终处于播放状态。。。

#include <mega88.h>
#include <sleep.h>

#define wav_size 5080
flash unsigned char wav = {
    0x80,0x80,0x80,0x80,0x81,0x80,0x81,0x81,0x80,080,0x80,0x80,0x80,0x80,0x80,0x80,
。。。。。。。。。
   
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f,
0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80
}; //采样频率8K,分辨率8 位的 Wav 数据

#define true 1
#define false !true

volatile unsigned char State =0;                        //播放间隔
volatile unsigned char sleep = false;


volatile unsigned int wav_index=0;
volatile unsigned char wdt_counter=0;               //看门狗延时

const unsigned char delay_sleep = 4;                   // 休眠期8s*4=32s
const unsigned char delay_play = 6;                     // 播放期8s*6=48s
                                                                      //期望 32s 休眠后唤醒 48s,

void Ports_Init(void)
void Timers_Peripherals_Init(void)
{
    TCCR0A=0x83;
    TCCR0B=0x01;   
    TCNT0=0x00;
    OCR0A=0x00;
    OCR0B=0x00;

    ASSR=0x00;
    TCCR2A=0x02;
    TCCR2B=0x02;
    TCNT2=0x00;
    OCR2A=0x7C;
    OCR2B=0x00;

    TIMSK2=0x02;
//
    PRR=(1<<PRTWI)|(0<<PRTIM2)|(0<<PRTIM0)|(1<<PRTIM1)|(1<<PRSPI)|(1<<PRUSART0)|(1<<PRADC);
    PRR1=(0<<PRWDT)|(0<<PREFL)|(1<<PRPCI);
//
}
interrupt void timer2_compa_isr(void)
{
    #asm("cli");
    if (State == 0) OCR0A = wav;
    else OCR0A = 0x7f;
    if (++wav_index > wav_size)
    {
      wav_index = 0;
      State ^= 0x01;
    }
    #asm("sei");
}
interrupt void wdt_timeout_isr(void)             //看门狗中断只负责按时序确定状态
{
    #asm("cli");
    MCUSR = ~(1<<WDRF);
    switch (sleep)
    {
      case false:
            if (++wdt_counter > delay_play)
            {
                sleep = true;
                wdt_counter = 0;
            }
            break;
      case true:
            if (++wdt_counter > delay_sleep)
            {
                sleep = false;
                wdt_counter = 0;
            }
            break;
    }
    #asm("sei");
}
void main(void)
{
    CLKPR=0x80;
    CLKPR=0x02;
//
    MCUSR = (0<<WDRF);
    #asm("wdr");
    WDTCSR = (1<<WDCE)|(1<<WDE);
    WDTCSR = (1<<WDIE)|(1<<WDP3)|(0<<WDCE)|(0<<WDE)|(0<<WDP2)|(0<<WDP1)|(1<<WDP0); //8s 中断模式
//
    Ports_Init();
    Timers_Peripherals_Init();

    #asm("cli");
    wdt_counter = 0;
    sleep = false;
    #asm("wdr");
    #asm("sei");

    while (1)
    {
      switch (sleep)
      {
            case false:
                break;
            case true:
            {
                // #asm("cli");
                powerdown();
                break;
            }
      }
    }
}

chenxp99 发表于 2014-4-8 18:44:26

本帖最后由 chenxp99 于 2014-4-8 18:56 编辑

AVR132 Using the Enhanced Watchdog Timer
1. Initialization; 2 .Disable WDT System Reset Mode; 3. Enable WDT Interrupt Mode;4. Set WDT timeout period; 5. SetSleep Mode; 6. Return

2、3、4 步骤没看明白,难道WDCE和WDE置位后,一并设置不可以吗,中断模式的WDE位为零,不是已经disable WDE了吗 ?


1. Enable sleep mode; 2. Enable intrrrupts; 3.Set WDT timeout period; 4. Enable WDT interrupt Mode

WDT timeout wakeup: Disable WDT interrupt mode          为什么呢
页: [1]
查看完整版本: 给《会说话的单片机》增加时序控制,遇障碍求指点