Watchdog и прерывания

gzp13
Offline
Зарегистрирован: 06.04.2015
Здравствуйте. Суть такая, три положения на передатчике. Attiny 13спит.Ставлю тумблер в положение 1-приемник принимает сигнал PWM(длительность 1500мс) . Пытаюсь сделать так, чтобы она спала, а как только пришел этот сигнал она просыпалась, выполняла какое то действие и снова засыпала. Аналогично и далее, тумблер в положение 2( длительность сигнала 2000мс)-опять проснулась и сделала что то и снова в спячку.Код написал но не работает(((
//Установить частоту платы 9.6МГц
#include <avr/io.h> // принято подключать
#include <avr/wdt.h> // здесь организована работа с ватчдогом
#include <avr/sleep.h> // здесь описаны режимы сна
#include <avr/interrupt.h> // работа с прерываниями
#define F_CPU 9600000UL // 9.6 MHz
#define PPM_pin 1
int PPM;
unsigned long time;
unsigned long previoustime=0;
int count=0;

ISR (WDT_vect) { // данна функция вызывается по прерыванию при срабатывании wdt
                 // если wdt не сбросить, то будет резет
  wdt_reset();         // сбрасываем wdt сторож
  WDTCR |= _BV(WDTIE); // разрешение прерываний от сторожевого таймера 
  count++; 
}
ISR(PCINT0_vect)
{
  watch();  
}

void setup()
{ 
  DDRB &= ~(1<<1);
  DDRB |= (1<<0);
  DDRB |= (1<<2);
  DDRB |= (1<<4);
  GIMSK |= (1<<PCIE); // Разрешаем внешние прерывания PCINT0.
  PCMSK |= (1<<1); // Разрешаем по маске прерывания на ногак кнопок (PCINT3, PCINT4)
  sei(); // Разрешаем прерывания глобально: SREG |= (1<<SREG_I)
  
  wdt_enable(WDTO_8S); // разрешаем ватчдог каждые 8сек.
  WDTCR |= _BV(WDTIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.
  sei();               // разрешаем прерывания
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
  wdt_reset(); // сбрасываем    
}

void loop()
 {
  PPM_read();
   watch();

    wdt_reset();    // перед сном сбрасываем, чтобы спать все отведенное время
      sleep_enable(); // разрешаем сон
      sleep_cpu();    // спать! 
}



//=============================================================================
//                           Считывание сигнала PPM
//=============================================================================
void PPM_read(){
  while (!(PINB & (1<<PINB1)));    //когда на пине РВ1 0
   time = micros();
  while (PINB & (1<<PINB1));      //когда на пине РВ1 1   
  time = micros()-time;
  if (time>980 && time<3000) PPM = time;
}
//========================================================
//если произощло прерывание на PB1////////////////////////////
//==================================================
void watch()          // должна проснуться если пришел сигнал на PB1
{
   if (PPM <1200 ) 
       {     
   PORTB &= ~(1<<0);
   PORTB &= ~(1<<2);
   PORTB &= ~(1<<4);
}

 if (PPM < 1550 && PPM> 1200) 
 {
    unsigned long time1=micros();
if ( time1-previoustime>25000)
{  
  previoustime=time1;
   PORTB ^= (1 << PB0);
PORTB ^= (1 << PB2);
PORTB ^= (1 << PB4);    
 }
 }
    if (PPM > 2020) {
     PORTB |= (1<<0); 
     PORTB |= (1<<2); 
     PORTB |= (1<<4); //digitalWrite (0, HIGH);
    
    }
if(count>=20)  спим 160 сек.
{
count=0;
}
}

 

gzp13
Offline
Зарегистрирован: 06.04.2015

Здравствуйте. Суть такая, три положения на передатчике. Attiny 13спит.Ставлю тумблер в положение 1-приемник принимает сигнал PWM(длительность 1500мс) . Пытаюсь сделать так, чтобы она спала, а как только пришел этот сигнал она просыпалась, выполняла какое то действие и снова засыпала. Аналогично и далее, тумблер в положение 2( длительность сигнала 2000мс)-опять проснулась и сделала что то и снова в спячку.Код написал но не работает(((


//Установить частоту платы 9.6МГц
#include <avr/io.h> // принято подключать
#include <avr/wdt.h> // здесь организована работа с ватчдогом
#include <avr/sleep.h> // здесь описаны режимы сна
#include <avr/interrupt.h> // работа с прерываниями
#define F_CPU 9600000UL // 9.6 MHz
#define PPM_pin 1
int PPM;
unsigned long time;
unsigned long previoustime=0;
int count=0;

ISR (WDT_vect) { // данна функция вызывается по прерыванию при срабатывании wdt
                 // если wdt не сбросить, то будет резет
  wdt_reset();         // сбрасываем wdt сторож
  WDTCR |= _BV(WDTIE); // разрешение прерываний от сторожевого таймера 
  count++; 
}
ISR(PCINT0_vect)
{
  watch();  
}

void setup()
{ 
  DDRB &= ~(1<<1);
  DDRB |= (1<<0);
  DDRB |= (1<<2);
  DDRB |= (1<<4);
  GIMSK |= (1<<PCIE); // Разрешаем внешние прерывания PCINT0.
  PCMSK |= (1<<1); // Разрешаем по маске прерывания на ногак кнопок (PCINT1)
  sei(); // Разрешаем прерывания глобально: SREG |= (1<<SREG_I)
  
  wdt_enable(WDTO_8S); // разрешаем ватчдог каждые 8сек.
  WDTCR |= _BV(WDTIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.
  sei();               // разрешаем прерывания
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
  wdt_reset(); // сбрасываем    
}

void loop()
 {
  PPM_read();
   watch();

    wdt_reset();    // перед сном сбрасываем, чтобы спать все отведенное время
      sleep_enable(); // разрешаем сон
      sleep_cpu();    // спать! 
}



//=============================================================================
//                           Считывание сигнала PPM
//=============================================================================
void PPM_read(){
  while (!(PINB & (1<<PINB1)));    //когда на пине РВ1 0
   time = micros();
  while (PINB & (1<<PINB1));      //когда на пине РВ1 1   
  time = micros()-time;
  if (time>980 && time<3000) PPM = time;
}
//========================================================
//если произощло прерывание на PB1////////////////////////////
//==================================================
void watch()          // должна проснуться если пришел сигнал на PB1
{
   if (PPM <1200 ) 
       {     
   PORTB &= ~(1<<0);
   PORTB &= ~(1<<2);
   PORTB &= ~(1<<4);
}

 if (PPM < 1550 && PPM> 1200) 
 {
    unsigned long time1=micros();
if ( time1-previoustime>25000)
{  
  previoustime=time1;
   PORTB ^= (1 << PB0);
PORTB ^= (1 << PB2);
PORTB ^= (1 << PB4);    
 }
 }
    if (PPM > 2020) {
     PORTB |= (1<<0); 
     PORTB |= (1<<2); 
     PORTB |= (1<<4); //digitalWrite (0, HIGH);
    
    }
if(count>=20)  спим 160 сек.
{
count=0;
}
}

 

Bruzzer
Offline
Зарегистрирован: 17.03.2020

Что значит "Сигнал PWM длительность 1500 мс"?. Какая частота PWM, какая скважность? Или это одиночный импульс?

gzp13
Offline
Зарегистрирован: 06.04.2015

 Надо чтобы был режим POWER DOWN и контроллер выходил из этого режима по сигналу на PB0(PCINT0). А работает либо спящий режим если закомментировать строку        GIMSK |= (1<<PCIE); или PCCMSK |= (1<<0);    или если раскомментировать эти строки , то работает прерывание на PB0 но не работает режим POWER DOWN. Подсобите светом что не так, люди добрые)


//Установить частоту платы 9.6МГц
#include <avr/io.h> // принято подключать
#include <avr/wdt.h> // здесь организована работа с ватчдогом
#include <avr/sleep.h> // здесь описаны режимы сна
#include <avr/interrupt.h> // работа с прерываниями
#define F_CPU 9600000UL // 9.6 MHz
#define PPM_pin 1
int PPM;
unsigned long time;
unsigned long previoustime=0;
int count=0;

ISR (WDT_vect) { // данна функция вызывается по прерыванию при срабатывании wdt
                 // если wdt не сбросить, то будет резет
  wdt_reset();         // сбрасываем wdt сторож
  WDTCR |= _BV(WDTIE); // разрешение прерываний от сторожевого таймера 
   PORTB ^= (1 << 3);  //это для проверки WATCHDOG
}

ISR(PCINT0_vect)
{
   watch();  
  }
void setup()
{ 
  DDRB &= ~(1<<0);
  DDRB |= (1<<1);
  DDRB |= (1<<2);
  DDRB |= (1<<4);
  DDRB |= (1<<3);
   
  MCUCR |= (0 << ISC01) | (0 << ISC00);
MCUCR |= (1<<SM1); // power-down mode
 MCUCR &= ~(1<<SM0); // power-down mode
 GIMSK |= (1<<PCIE); // Разрешаем внешние прерывания PCINT0.
  PORTB |= (1<<3);
  //PCMSK |= (1<<0); // Разрешаем по маске прерывания на ногак кнопок (PCINT0)
  PRR = (1<<PRADC); // shut down ADC
  sei(); // Разрешаем прерывания глобально: SREG |= (1<<SREG_I)
  ADCSRA &= ~(1 << ADEN);
  wdt_reset(); // сбрасываем    
  wdt_enable(WDTO_4S); // разрешаем ватчдог каждые 8сек.
  WDTCR |= _BV(WDTIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.
  
 sei();               // разрешаем прерывания
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
 }
void loop()
 {
  PPM_read();
    wdt_reset();    // перед сном сбрасываем, чтобы спать все отведенное время
      sleep_enable(); // разрешаем сон
      sleep_cpu();    // спать! 
}



//=============================================================================
//                           Считывание сигнала PPM
//=============================================================================
void PPM_read(){
  
  while (!(PINB & (1<<0)));    //когда на пине РВ1 0
   time = micros();
  while (PINB & (1<<0));      //когда на пине РВ1 1   
  time = micros()-time;
  if (time>980 && time<3000) PPM = time;
}
//========================================================
//если произощло прерывание на PB1////////////////////////////
//==================================================
void watch()          // должна проснуться если пришел сигнал на PB0
{
   if (PPM <1200 ) 
       {     
   PORTB &= ~(1<<1);
   PORTB &= ~(1<<2);
   PORTB &= ~(1<<4);
}

 if (PPM < 1550 && PPM> 1200) 
 {
    unsigned long time1=micros();
if ( time1-previoustime>25000)
{  
  previoustime=time1;
   PORTB ^= (1 << 1);
PORTB ^= (1 << 2);
PORTB ^= (1 << 4);    
 }
 }
    if (PPM > 2000) {
     PORTB |= (1<<1); 
     PORTB |= (1<<2); 
     PORTB |= (1<<4); //digitalWrite (0, HIGH);
    }

}

 

gzp13
Offline
Зарегистрирован: 06.04.2015

Или я туплю и режим POWER DOWN работает.

Меряю тестером,ток без sleep enable 4.4мА, добавляю эти строки ток составляет 0.27мА, т.е как я понимаю спящий режим работает? Но вот в скетче BLINK ток в спящем режиме составляет 7мкА, сам измерял. Почему же в моем скетче ток потребления выше?

b707
Онлайн
Зарегистрирован: 26.05.2017

gzp13 пишет:

Или я туплю и режим POWER DOWN работает.

Меряю тестером,ток без sleep enable 4.4мА, добавляю эти строки ток составляет 0.27мА, т.е как я понимаю спящий режим работает? Но вот в скетче BLINK ток в спящем режиме составляет 7мкА, сам измерял. Почему же в моем скетче ток потребления выше?

послушайте, а нафига две одинаковых ветки?

админы. предлагаю эту ветку снести. у нее есть полная копия в другом разделе