Здравствуйте.
Это разработка тахометра, который должен считать импульсы от датчика Холла.
Вместо датчика Холла (временно) подключена кнопка к пину 2.
Дребезг контактов не имеет значения. Это - разработка. ТЕОРИЯ
По импульсу от датчика Холла переменная stobor увеличивается на единицу.
Каждую секунду по прерыванию от таймера содержимое stobor присваивеатся stobor2.
Затем в loop()stobor2 передается в порт ПРАКТИКА
Ни фига не работает как надо.
После нажатия на кнопку в порт выводится какое-то число. Например, 81.
Проблема в том, что это число выводится не один раз, как ожидалось, а 4 - 5 раза.
В чем может быть дело?
Спасибо.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
volatile int stobor; // счетчик оборотов
volatile int stobor2; // счетчик оборотов
unsigned long int t1;
unsigned long int t2;
unsigned long int period = 1000;
void setup()
{
t1 = millis();
t2 = millis();
pinMode(2, INPUT_PULLUP);
Serial.begin(9600);
stobor = 0;
stobor2 = 0;
wdt_enable (WDTO_8S);
attachInterrupt(digitalPinToInterrupt(2), holl, RISING); // прерывание на пине 2
// Настройка таймера
cli();
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
TCCR1B |= (1 << CS12) | (1 << CS10);
OCR1A = 15624;
TIMSK1 |= (1 << OCIE1A);
sei();
}
void loop()
{
// обработка счетчика оборотов stobor2
t2 = millis();
if (t2 - t1 >= period)
{
t1 = t2;
Serial.println(stobor2);
}
wdt_reset();
}
void holl() // Прерывание по датчику Холла
{
stobor++;
}
ISR(TIMER1_COMPA_vect) // Прерывание по таймеру
{
stobor2 = stobor;
stobor = 0;
}
В прерывании кнопки поднимаете флаг, что кнопка сработала.
Если он поднят - печать, а затем сброс флага.
P.S. Чушь написал. Кнопка - это ведь датчик Холла.))
Но принцип всё равно тот же. Если не нужна многократная печать - поднимаем флаг в нужном месте, и, сразу, после печати сбр.
Один таймер на счет, другой скажем на 100мс, тут все от параметров системы зависит, второй забирает значение первого, обнуляет его, пересчитывает попугаи в нужные единицы и кладет в переменную, все, забирайте и печатайте когда хотите.
Такое возможно, если @Upper прав, хотя я с ходу не вижу, где косяк, может дело в 16-битных регистрах. Я сейчас должен уходить, если что позже посмотрю.
Может @Upper разъяснит, где косяк в настройках таймера
Здесь проблема не в том, какой период срабатывания прерывания по таймеру, а в том, что состояние в stobor2 сохраняется на 4-5 секунд. В строке 58 stobor2=stobor; Взял количество “попугаев”. В строке 59 stobor обнулил. Значит, если не нажимать кнопку, то при следующем срабатывании прерывания по таймеру в stobor2 должен прийти ноль. А ноль приходит с задержкой в 4-5 секунд.
Может быть. Но сначала stobor2 надо правильно получить и обработать. Возможно, что на время обработки понадобится какой-то флаг, чтобы запретить смену stobor2.