Страница 1 из 1
RPM-метр для компьютерного куллера
Добавлено: Вс дек 14, 2008 19:43:51
Andergrin
Написал на WinAVR программу для ATMega8 для измерения частоты вращения двух компьютерных куллеров. Реализовано измерение оборотов кратное 60 об/мин, но хотелось бы измерить частоту вращения, кратную 10 об/мин, а как это сделать - не пойму. В своей программе использую прерывание по входу INT0 и INT1 для подсчета количества импульсов, пришедших от таходатчика куллера. Период подсчета импульсов - 1 секунда, устанавливаю при помощи таймера TCCR0, таймер TCCR1 выполняет функции двух ШИМ.
Добавлено: Вс дек 14, 2008 21:40:42
Aheir
Лучше проводить анализ данных по прерываниям поочередно, т.е. секунду мониторим ИНТ0, ИНТ1 отключен в это время, потом наоборот. Несколько непонятно, как у Вас реализовано измерение частоты, откуда берется такая кратность? Стандартные подходы: либо считаем кол-во импульсов за единицу времени, либо время, за которое приходит N импульсов. На Форуме есть примеры реализации и того, и другого, поищите. Можно без проблем измерять обороты с точностью до 1.
Добавлено: Вс дек 14, 2008 22:21:03
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;
}
}
Добавлено: Вс дек 14, 2008 23:24:20
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 секунд.
Как мне кажется для низкой частоты такой алгоритм неоптимален, лучше измерять период следования импульсов а затем вычислять частоту или число оборото в минуту.
Добавлено: Вт дек 16, 2008 22:33:08
Andergrin
Пробую разные варианты, и что-то меня сейчас смущает, так это таймер TCCR0, а точнее его регистр TCNT0. Я установил тактирование от внутреннего генератора 8 МГц без предделителя, и записываю в TCNT0 число 255, как я понимаю после одного такта генератора он переполняется. По появлению 1 в регистре TIFR, записываю 1 или 0 в порт, на виртуальном осциллографе получаю прерывание периодом 5,22 мск, хотя по идее должно быть 0,125 мск. Так и должно быть, или я что-то делаю не так?
Добавлено: Вт дек 16, 2008 23:20:07
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 есть предделитель как он сконфигурирован? может быть в этом причина такого периода?
Добавлено: Ср дек 17, 2008 14:38:46
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.01
5 об/мин
S2'=7654.32
4 об/мин
Подчеркнутые цифры- погрешность метода.
Добавлено: Чт дек 18, 2008 21:23:08
Andergrin
Наконец то соорудил таки алгоритм измерения частоты оборотов с шагом 1 об/мин. Пока что сделал только один канал, на таймере TCCR2, но без труда можно реализовать второй канал на таймере TCCR0. Частота тактового генератора 8 МГц, установлен предделитель на 8, тоесть период одного такта таймера составляет 1 мкс. По переполнению таймера содержимое переменной i увеличивается на единицу и одержанное значение умножается на 256 (количество тактов переполнения таймера, которое отвечает 256 мкс). После поступления тахосигнала от куллера переходим в оброботчик прерываний по INT0, присваиваем переменной n текущее значение счетчика TCNT2, и проводим вычисление периода импульса по формуле T(мкс)=i*256мкс+TCNT2. Остается только вычислить количество оборотов по формуле N=60000000(мкс)/T(мкс)
Исходники и пример работы в Протеусе прилагаются.
Добавлено: Чт дек 18, 2008 23:22:43
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 вычислял бы в основном цикле, после того как флаг проходил бы проверку на истинность. Цель данных преобразований - сделать обработчики прерываний как можно короче. Возможно в данном проекте это и не актуально, но все-же.
Добавлено: Чт дек 18, 2008 23:54:27
Andergrin
Выставлял TIFR |=0x40, а вот если count_1 перенести из обработчика прерываний в главную функцию то в результате отображается "хаотично" изменяющиеся данные, а когда переменная count_1 в обработчике прерываний - все нормально. А точность тут достаточная, десятые я все равно не отображаю.
Добавлено: Пт дек 19, 2008 14:18:03
smac
Andergrin писал(а):Выставлял TIFR |=0x40, а вот если count_1 перенести из обработчика прерываний в главную функцию то в результате отображается "хаотично" изменяющиеся данные, а когда переменная count_1 в обработчике прерываний - все нормально. А точность тут достаточная, десятые я все равно не отображаю.
Нет вы не поняли, TIFR это регистр флагов прерываний от таймеров, его трогать не надо, тем более, что записью единицы в нужный бит вы не выставляете, а наоборот сбрасываете соответствующий флаг.(загляните в даташит). Я имел ввиду, что нужно организовать программный флаг, который выставлять и сбрасывать самому. Данные пересчитывать значения только после установки флага, после пересчета значений флаг сбрасывать.
Добавлено: Пт дек 19, 2008 15:06:06
Andergrin
smac писал(а):Нет вы не поняли, TIFR это регистр флагов прерываний от таймеров, его трогать не надо, тем более, что записью единицы в нужный бит вы не выставляете, а наоборот сбрасываете соответствующий флаг.(загляните в даташит)
Собственно, я это и хотел сделать, чтоб после появления внешнего прерывания сразу начинался счет сначала, чтоб к следующему прерыванию получить новые корректные данные
Добавлено: Пт дек 19, 2008 23:47:44
smac
Andergrin писал(а):
Собственно, я это и хотел сделать, чтоб после появления внешнего прерывания сразу начинался счет сначала, чтоб к следующему прерыванию получить новые корректные данные
Флаг прерывания от таймера или регистра стравнения автоматически сбрасываетя при обслуживании запроса прерывания, т. е. при входе в обработчик прерывания.
Добавлено: Пн дек 22, 2008 18:33:47
Andergrin
Вариант прошивки для измерения частоты оборотов от двух источников