11.05.2022г. ВНИМАНИЕ! Если у вас не отображаются иллюстрации к статьям, для просмотра сайта используйте TOR браузер

ATmega8: счетчик оборотов компьютерного вентилятора, через внешнее прерывание

разделы: AVR , дата: 10 ноября 2015г.


за один оборот, датчик Холла
срабатывает дважды

Обычно внешние прерывания разбирают на кнопках, но у меня есть более интересный пример: счетчик оборотов компьютерного кулера.

Напомню, что подсчет оборотов ведется через датчик Холла, который является неотъемлемой частью компьютерного вентилятора. В данном случае пойдет речь о трех-пиновым вентиляторе. схема подключения взята из одного из предыдущих постов, когда счетчик писался для Arduino. В качестве шаблона кода взят пример, из прерыдущего поста про фоторезистор. Из примера, были уделены три строчки относящиеся к АЦП.

В официальном руководстве на ATmega8, внешние прерывания(External Interrupts) описаны на странице 66. Они имеют более высокий приоритет перед другими прерываниями. Управляются регистром MCUCR:

Младшие четыре бита указывают на режимы срабатывания прерывания. Для INT0 это будет:

Для INT1:

    где в описании по порядку перечислены варианты:
  1. при низком уровне;
  2. при любом изменении уровня;
  3. при спадющем фронте;
  4. при нарастающем фронте.

Включаются прерывания через контрольный(управляющий) регистр GICR:

Кроме того, имеется флаговый регистр GIFR:

Еще раз напомню схему подключения:

Текст программы:

#include <util/delay.h>
#include <uart.h>
#include <avr/io.h>
#include <avr/interrupt.h>

static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);

volatile uint16_t data_fan;
ISR(INT0_vect)
{
	data_fan++;
};

int main(void)
{
	//---- init
	init_uart();
        DDRB |= (1<<PB5); // led indicator

	// External Interrupt
	MCUCR = (1<<ISC01); // falling edge
	GICR  = (1<<INT0); // enable INT0

	//---- ready indication
        blink13(3); //ready indication
	stdout = &mystdout;
	printf("Ok, I'm ready!\n");

	data_fan=0;
	sei();
	//---- main body
	for (;;)
	{
		_delay_ms(1000);
		cli();
		data_fan*=30;
		printf("Fan speed: %d RPM\n",data_fan);
		data_fan=0;
		sei();
	};

        return 0;
}

Здесь используется внешнее прерывание INT0, счетчик срабатывает по падающему фронту. Замер осуществляется в течении одной секунды. За один оборот, датчик Холла срабатывает дважды( у магнита два полюса). Умножив результат на 30 получаем количество оборотов в минуту.

Лог работы программы:

Верхний ряд цифр, это показания с 12-cm вентилятора, а нижний ряд - с 8cm.

Скачать архив с полными исходниками можно здесь: скачать zip