Вопрос по прерываниям

cdriver
Offline
Зарегистрирован: 14.01.2016

Не могу разобраться в чем проблема. Необходимо обрабатывать прерывания по сравнеию с регистром OCR

Почему то когда я начинаю настраивать регистры по 5 таймеру (к примеру) на меге то происходит полная фигня, к примеру delay() аозращает всегда 0, а вот пример кода должен светодиод по нажатию кнопки загортся, если делать код без прерывания все четко работате, если делаю так как в коде светодиод живет своей непонятно жизнью... вообще не понимаю что происходит, помогите разобраться, голову сломал.

#include <ButtonMode.h>

#define B_OPEN_PIN 3      //кнопка открыть
#define B_MODE true       //есть инвертация кнопки (т.е. нажатат это сигнал переходит в LOW
#define B_STOP_PIN 5      //кнопка стоп
#define B_STOP_MODE true 

int mode=0;           //режим работы по кнопкам: 0стоп,  1открыть, 2закрыть, 3

ButtonMode butOpen(B_OPEN_PIN, 2, B_MODE);         // создание объекта для кнопки открыть, 15 время усреднения (счетчик)
ButtonMode butStop(B_STOP_PIN, 2, B_STOP_MODE);    // создание объекта для кнопки стоп

/*---------------------------------------------------------------------------------------------------------------*/
void setup() {
  pinMode(33, OUTPUT);
  pinMode(29, OUTPUT);
  Serial.begin(9600);

  TCCR5A =0;
  TCCR5B |= (1<<WGM31);      // Режим работы таймера CTC со сбросом счетчика + предделитель
  TIMSK5 |= ((1<<OCIE5A)|(1<<OCIE5B));  // Разрешение прерывания по сравнению с OCR3A и OCR3B без В почему то не работает
  OCR5A = 25500;             // Частота прерываний будет = Fclk/(N*(1+OCR1A)) где N - коэф. предделителя (1, 8, 64, 256 или 1024)

}
/*---------------------------------------------------------------------------------------------------------------*/
void loop() {
  if (butOpen.flagClick == true)  {  mode = 1; butOpen.flagClick = false; }     //нажатия кнопок управления открыть
  if (butStop.flagClick == true)  {  mode = 0; butStop.flagClick = false; }     //нажатия кнопок управления стоп

  switch (mode) {
    case 0: 
     digitalWrite(33, LOW);
    break;
    case 1: 
     digitalWrite(33, HIGH);
    break;
  }  
}

ISR (TIMER5_COMPA_vect) {
  digitalWrite(29, !digitalRead(29));
  butOpen.filterAvarage();     // вызов метода фильтрации по среднему
  butStop.filterAvarage();   // вызов метода фильтрации по среднему
  Serial.println(butOpen.flagClick);
}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

cdriver, проблема в том, что вы не понимаете как работают таймеры и не умеете их настраивать. У вас ошибки в каждой строчке конфигурации.

19 -ну ладно, тут ок.

20 строчка -3 ошибки сразу. (1) Нельзя давать команду |= если вы до этого не обнуляли регистр. Ибо нам неизвестно, что там было. В этом случае просто =   (2) Вы вставляете бит от 3-го таймера. Режим СТС это бит WGM52  (3) вы не запустили таймер битами CS5x Итого правильно будет: TCCR5B = (1<<WGM52) | (1<<CS50) ;

21 строчка  2 ошибки. Опять нельзя делать |=, и нельзя указывать прерывание, которые в не обрабатываете. Итого правильно будет TIMSK5=1<<OCIE5A;

cdriver
Offline
Зарегистрирован: 14.01.2016

Ок спасибо... про 3 таймер все праильно. Как таймеры работают я понимаю, изначально написал код под 3 таймер 16 битный... но у меня не получилось... далее уже были эксперементы с дургими таймерами... вот и получилась ошибка что от 3 таймера..... я так пологаю, что моя ошибка в |= я не понимаю как это работает, я думал что это выставляет определнный бит в регистре в 1... покажите тогда как правильно выставить несколько битов в 1 и в 0... и что все таки делает операция в моем примере? можетет разжевать или ссылку указать где почитать.

Спасибо.