RPM-метр для компьютерного куллера

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Родился
Сообщения: 9
Зарегистрирован: Пт дек 12, 2008 23:28:02
Откуда: Україна

Сообщение Andergrin »

Написал на WinAVR программу для ATMega8 для измерения частоты вращения двух компьютерных куллеров. Реализовано измерение оборотов кратное 60 об/мин, но хотелось бы измерить частоту вращения, кратную 10 об/мин, а как это сделать - не пойму. В своей программе использую прерывание по входу INT0 и INT1 для подсчета количества импульсов, пришедших от таходатчика куллера. Период подсчета импульсов - 1 секунда, устанавливаю при помощи таймера TCCR0, таймер TCCR1 выполняет функции двух ШИМ.
Реклама
Модератор
Аватара пользователя
Сообщения: 4517
Зарегистрирован: Пн апр 03, 2006 11:43:25
Откуда: Санкт - Петербург

Сообщение Aheir »

Лучше проводить анализ данных по прерываниям поочередно, т.е. секунду мониторим ИНТ0, ИНТ1 отключен в это время, потом наоборот. Несколько непонятно, как у Вас реализовано измерение частоты, откуда берется такая кратность? Стандартные подходы: либо считаем кол-во импульсов за единицу времени, либо время, за которое приходит N импульсов. На Форуме есть примеры реализации и того, и другого, поищите. Можно без проблем измерять обороты с точностью до 1.
Оптимизм х (Опыт + Знания) = const
Контактная информация:
Реклама
Родился
Сообщения: 9
Зарегистрирован: Пт дек 12, 2008 23:28:02
Откуда: Україна

Сообщение Andergrin »

То, что я видел, было реализовано для одного куллера и используя вход ICP1, или так же как и в моем случае - с дискретностью 60 об/мин.
Я считаю 31250 прерываний, частота микроконтроллера 8 МГц без предделителя. Кусок кода (для одного куллера):

Код: Выделить всё

SIGNAL (SIG_INTERRUPT0)
{
  count_pulses_1++;	
}

//When overflow occurs
SIGNAL (SIG_OVERFLOW0)
{
	//TCNT0=0xFD;
	i++;
	if (i==31250)
	{
		//PORTD ^=0x01;
		rpm_1=60*(unsigned int)count_pulses_1; 
		i=0;
		count_pulses_1=0;
	}  
}
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Andergrin писал(а):То, что я видел, было реализовано для одного куллера и используя вход ICP1, или так же как и в моем случае - с дискретностью 60 об/мин.
Я считаю 31250 прерываний, частота микроконтроллера 8 МГц без предделителя. Кусок кода (для одного куллера):

Код: Выделить всё

SIGNAL (SIG_INTERRUPT0)
{
  count_pulses_1++;	
}

//When overflow occurs
SIGNAL (SIG_OVERFLOW0)
{
	//TCNT0=0xFD;
	i++;
	if (i==31250)
	{
		//PORTD ^=0x01;
		rpm_1=60*(unsigned int)count_pulses_1; 
		i=0;
		count_pulses_1=0;
	}  
}
У вас алгоритм подсчета импульсов за определенное время, в этом случае чтобы добиться дискретности показаний 10 об/мин, нужно увеличить время счета в 6 раз (умножить константу для i во втором прерывании на 6), а в формуле для rpm_1 уже использовать 10, соответственно показания будут обновляться раз в 6 секунд.
Как мне кажется для низкой частоты такой алгоритм неоптимален, лучше измерять период следования импульсов а затем вычислять частоту или число оборото в минуту.
Реклама
Эиком - электронные компоненты и радиодетали
Родился
Сообщения: 9
Зарегистрирован: Пт дек 12, 2008 23:28:02
Откуда: Україна

Сообщение Andergrin »

Пробую разные варианты, и что-то меня сейчас смущает, так это таймер TCCR0, а точнее его регистр TCNT0. Я установил тактирование от внутреннего генератора 8 МГц без предделителя, и записываю в TCNT0 число 255, как я понимаю после одного такта генератора он переполняется. По появлению 1 в регистре TIFR, записываю 1 или 0 в порт, на виртуальном осциллографе получаю прерывание периодом 5,22 мск, хотя по идее должно быть 0,125 мск. Так и должно быть, или я что-то делаю не так?
Реклама
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Andergrin писал(а):Пробую разные варианты, и что-то меня сейчас смущает, так это таймер TCCR0, а точнее его регистр TCNT0. Я установил тактирование от внутреннего генератора 8 МГц без предделителя, и записываю в TCNT0 число 255, как я понимаю после одного такта генератора он переполняется. По появлению 1 в регистре TIFR, записываю 1 или 0 в порт, на виртуальном осциллографе получаю прерывание периодом 5,22 мск, хотя по идее должно быть 0,125 мск. Так и должно быть, или я что-то делаю не так?
Лучше бы код выложили, ибо не понятно как вы записываете в таймер число: в прерывании или нет? останавливаете при этом таймер или нет? и т. п. Для генерирования временных отсчетов не кратных 256 (ну или 65356 для 2х байтного таймера) лучше использовать режим СТС (Clear Timer on Compare) и регистр сравнения. Как говорит даташит в таймере 0 нет такой возможности, поэтому предлагаю рассмотреть возможность использования таймера1 или таймера2, если он будет работать на измерения.
З. Ы. У таймера0 есть предделитель как он сконфигурирован? может быть в этом причина такого периода?
Реклама
akl
Друг Кота
Сообщения: 4468
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Andergrin писал(а):То, что я видел, было реализовано для одного куллера и используя вход ICP1, или так же как и в моем случае - с дискретностью 60 об/мин.
Здравствуйте.
Позвольте не согласиться с Вами. С помощью ICP можно очень точно и быстро измерить скорость вращения.
Посмотрите веточку http://www.radiokot.ru/forum/viewtopic.php?t=12082
Допустим, что необходимо измерить скорость вращения двух источников; для этого есть следующие возможности
- задействовать INT0 и INT1 примерно так как в схеме
- время измерения скорости вращения 0.25 сек
и ограничения
- таймер Т1 используется для формирования ШИМ в пределах 0...10'000 импульсов Fclk=8МГц

Далее, назначаем регистры-счетчики
-счетчик числа переполнений таймера Т1 250'000:10000*0.125=200, свидетельствующий об окончании времени измерения
- счетчик числа периодов (Nx1) измеряемой скорости вращения 1
- счетчик числа периодов (Nx2) измеряемой скорости вращения 2

- регистр А1 памяти начального состояния Т1 в момент начала измерения скорости 1
- регистр А2 памяти начального состояния Т1 в момент начала измерения скорости 2

- регистр А11 памяти конечного состояния Т1 в момент окончания измерения скорости 1
- регистр А22 памяти конечного состояния Т1 в момент окончания измерения скорости 2

Далее разрешаем прерывания INT0, INT1, ICP, по прерываниям заносим значения А1,А2 и запрещаем прерывание ICP до окончания времени измерения. После окончания времени измерения вновь разрешаем прерывание ICP для получения значений А11, А22. Прерывания INT0, INT1 наращивают значения Nx1,Nx2 соответственно.
Далее, пользуясь алгоритмом приведенным в веточке получаем результаты.

Пример:
S1=6789.012 об/мин А1=357
S2=7654.321 об/мин А2=7531

после измерения должно получиться
S1'=6789.015 об/мин
S2'=7654.324 об/мин
Подчеркнутые цифры- погрешность метода.
Родился
Сообщения: 9
Зарегистрирован: Пт дек 12, 2008 23:28:02
Откуда: Україна

Сообщение Andergrin »

Наконец то соорудил таки алгоритм измерения частоты оборотов с шагом 1 об/мин. Пока что сделал только один канал, на таймере TCCR2, но без труда можно реализовать второй канал на таймере TCCR0. Частота тактового генератора 8 МГц, установлен предделитель на 8, тоесть период одного такта таймера составляет 1 мкс. По переполнению таймера содержимое переменной i увеличивается на единицу и одержанное значение умножается на 256 (количество тактов переполнения таймера, которое отвечает 256 мкс). После поступления тахосигнала от куллера переходим в оброботчик прерываний по INT0, присваиваем переменной n текущее значение счетчика TCNT2, и проводим вычисление периода импульса по формуле T(мкс)=i*256мкс+TCNT2. Остается только вычислить количество оборотов по формуле N=60000000(мкс)/T(мкс)
Исходники и пример работы в Протеусе прилагаются.
Вложения
rpm.rar
(67 КБ) 224 скачивания
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Andergrin писал(а):Наконец то соорудил таки алгоритм измерения частоты оборотов с шагом 1 об/мин. Пока что сделал только один канал, на таймере TCCR2, но без труда можно реализовать второй канал на таймере TCCR0. Частота тактового генератора 8 МГц, установлен предделитель на 8, тоесть период одного такта таймера составляет 1 мкс. По переполнению таймера содержимое переменной i увеличивается на единицу и одержанное значение умножается на 256 (количество тактов переполнения таймера, которое отвечает 256 мкс). После поступления тахосигнала от куллера переходим в оброботчик прерываний по INT0, присваиваем переменной n текущее значение счетчика TCNT2, и проводим вычисление периода импульса по формуле T(мкс)=i*256мкс+TCNT2. Остается только вычислить количество оборотов по формуле N=60000000(мкс)/T(мкс)
Исходники и пример работы в Протеусе прилагаются.
Я бы еще для полного счастья в обработчике внешнего прерывания 0 ставил бы флаг что данные обновились, а переменную count_1 и переменную b вычислял бы в основном цикле, после того как флаг проходил бы проверку на истинность. Цель данных преобразований - сделать обработчики прерываний как можно короче. Возможно в данном проекте это и не актуально, но все-же.
Родился
Сообщения: 9
Зарегистрирован: Пт дек 12, 2008 23:28:02
Откуда: Україна

Сообщение Andergrin »

Выставлял TIFR |=0x40, а вот если count_1 перенести из обработчика прерываний в главную функцию то в результате отображается "хаотично" изменяющиеся данные, а когда переменная count_1 в обработчике прерываний - все нормально. А точность тут достаточная, десятые я все равно не отображаю.
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Andergrin писал(а):Выставлял TIFR |=0x40, а вот если count_1 перенести из обработчика прерываний в главную функцию то в результате отображается "хаотично" изменяющиеся данные, а когда переменная count_1 в обработчике прерываний - все нормально. А точность тут достаточная, десятые я все равно не отображаю.
Нет вы не поняли, TIFR это регистр флагов прерываний от таймеров, его трогать не надо, тем более, что записью единицы в нужный бит вы не выставляете, а наоборот сбрасываете соответствующий флаг.(загляните в даташит). Я имел ввиду, что нужно организовать программный флаг, который выставлять и сбрасывать самому. Данные пересчитывать значения только после установки флага, после пересчета значений флаг сбрасывать.
Родился
Сообщения: 9
Зарегистрирован: Пт дек 12, 2008 23:28:02
Откуда: Україна

Сообщение Andergrin »

smac писал(а):Нет вы не поняли, TIFR это регистр флагов прерываний от таймеров, его трогать не надо, тем более, что записью единицы в нужный бит вы не выставляете, а наоборот сбрасываете соответствующий флаг.(загляните в даташит)
Собственно, я это и хотел сделать, чтоб после появления внешнего прерывания сразу начинался счет сначала, чтоб к следующему прерыванию получить новые корректные данные
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Andergrin писал(а): Собственно, я это и хотел сделать, чтоб после появления внешнего прерывания сразу начинался счет сначала, чтоб к следующему прерыванию получить новые корректные данные
Флаг прерывания от таймера или регистра стравнения автоматически сбрасываетя при обслуживании запроса прерывания, т. е. при входе в обработчик прерывания.
Родился
Сообщения: 9
Зарегистрирован: Пт дек 12, 2008 23:28:02
Откуда: Україна

Сообщение Andergrin »

Вариант прошивки для измерения частоты оборотов от двух источников
Вложения
rpm.rar
(61.87 КБ) 246 скачиваний
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»