|
Тахометр на 16меге, не могу разобраться |
|
|
|
May 25 2007, 04:17
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 25-09-05
Из: Москва
Пользователь №: 8 922

|
Господа разработчики, подскажите пожалуйста, что я не так делаю? Задача следующая необходимо построить тахометр. На вход МК подается последовательность импульсов с частотой до 100 Гц. Нужно подсчитать количество импульсов за секунду и вывести на индикатор. Я использую 6мегу , кварц 8.0МГц. Завожу сигнал на вход T0 счетчика и снимаю с него параметры каждую секунду. Проблема в том что полученные результаты не постоянны. Т.е. значение на индикаторе скачет в пределах +-4 единицы. Думал, что не стабильно получаю секунду, так проверил на осциллографе… вроде нормально.. Всю голову сломал… У кого какие будут мысли? (пишу в AVR Studio) Прилагаю код … Код #define QZ 8000000L #define TIME_OCR1A ((QZ / 1024)-1)
int Speed_p; void Timer1_init(void) {
OCR1A = TIME_OCR1A; /* прерывание раз в секунду */ TCCR1A = 0x00; TCCR1B = (1 << 3) | 0x05; TIMSK |= 1 << 4; /* разрешить прерывание OCIE1A */ }
SIGNAL (TIMER1_COMPA_vect) { Speed_p=TCNT0; TCNT0=0; }
int main() { unsigned int g=0; char str[10];
Timer1_init();
// Таймер0 считает входные импульсы // Timer/Counter 0 initialization TCCR0=0x07; TCNT0=0x00; OCR0=0x00;
// Port B initialization // Func7=Out Func6=Out Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In // State7=0 State6=0 State5=T State4=T State3=0 State2=T State1=T State0=T PORTB=0x00; DDRB=0xC8;
sei(); while(1) { ..........
.// Формируем строку для вывода g=(float)(Speed_p)*(float)1.66; str_out[8]=g%10;g/=10; str_out[7]=g%10;g/=10; str_out[6]=g%10; // выводим строку reload();// динамическая индикация
}
|
|
|
|
|
 |
Ответов
|
May 28 2007, 07:18
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
Если хватит диапазона то сделать так: Код g = Speed_p * 166; , а при индикации тупо ставить запятую где надо. Если диапазона int не хватит , то объявить переменную как long int g. Т.е. если у вас и входная и выходная переменные целочисленные, то не к чему делать вычисления с плавающей точкой - все равно потеряете точность и как следствие получите дополнительную погрешность при преобразовании типов.
--------------------
|
|
|
|
|
May 28 2007, 07:22
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 25-09-05
Из: Москва
Пользователь №: 8 922

|
Цитата(GDI @ May 28 2007, 11:18)  Если хватит диапазона то сделать так: Код g = Speed_p * 166; , а при индикации тупо ставить запятую где надо. Если диапазона int не хватит , то объявить переменную как long int g. Т.е. если у вас и входная и выходная переменные целочисленные, то не к чему делать вычисления с плавающей точкой - все равно потеряете точность и как следствие получите дополнительную погрешность при преобразовании типов. Я вывожу на индикатор целое число. И потом даже при увеличении погрешности если переменная Speed_p не изменяется, то и после умножения на константу любого типа выражение не должно прыгать.... По моему так.. Вообще у меня подозрения что как раз в момент когда выполняется Код Speed_p=TCNT0; ... и тут приходит импульс на вход тактирования таймера TCNT0=0; а я его обнуляю.... возможно здесья теряю единицу.... Может это можно какнибудь отловить....
Сообщение отредактировал DAndy_boy - May 28 2007, 07:27
|
|
|
|
|
May 28 2007, 07:50
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(DAndy_boy @ May 28 2007, 10:22)  Вообще у меня подозрения что как раз в момент когда выполняется Код Speed_p=TCNT0; ... и тут приходит импульс на вход тактирования таймера TCNT0=0; а я его обнуляю.... возможно здесья теряю единицу.... Может это можно какнибудь отловить.... Да, тут запросто можно потерять. Причём как не старайся - свести вероятность потери к нулю при таком подходе (с обнулением) не выйдет. Нужно дать счётчику бежать свободно и брать разницу двух последовательных показаний за интервал. При этом всё равно в соседние секундные интервалы будут разные значения - при "нецелом" числе импульсов в секунду (скажем, не 100Гц, а 99.5) гарантированно будет, что соседние секундные интервалы содержат разное число импульсов - то 99, то 100. Для 99.9Гц в девяти секундных интервалах будет 100 импульсов, а в одном - 99. Но при свободно бегущем счётчике и взятии разности показаний ни один импульс не будет потерян вообще - он добавится к следующему результату и после фильтрации будет правильная и "твёрдо стоящая" величина. p.s. При таких низких частотах я тоже рекомендую измерение периода и пересчёт. INPUT CAPTURE поможет хватать содержимое счётчика. Чтобы не заморачиваться с ловлей количества переполнений таймера между двумя захватами - выберите предделитель так, чтобы на самой низкой частоте период переполнения таймера был заведомо больше, чем период входного сигнала. Тогда можно брать просто разность двух захватов в ICR и всё.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
Сообщений в этой теме
DAndy_boy Тахометр на 16меге May 25 2007, 04:17 muravei Цитата(DAndy_boy @ May 25 2007, 08:17) Ду... May 25 2007, 07:32 DAndy_boy ну как что? добавил в прерывание таймера SIGNAL (T... May 25 2007, 08:43 aesok В reoload() запрещаются прерывания? Есть другие об... May 25 2007, 08:57  DAndy_boy Цитата(aesok @ May 25 2007, 12:57) В reol... May 25 2007, 10:18   aesok Входной сигнал стабильный? Может дрожит частота си... May 25 2007, 10:48 muravei Цитата(DAndy_boy @ May 25 2007, 12:43) см... May 25 2007, 10:09 DAndy_boy Сигнал стабильный ТТЛ... может попробывать считать... May 25 2007, 11:00 GDI Для подсчета частоты импульсов есть специальный ре... May 25 2007, 12:35 DAndy_boy Действительно.... с этими преобразованиями и дробн... May 25 2007, 15:52 defunct Цитата(DAndy_boy @ May 25 2007, 18:52) пр... May 26 2007, 19:19  DAndy_boy Цитата(defunct @ May 26 2007, 23:19) 1* 2... May 27 2007, 10:09   defunct Цитата(DAndy_boy @ May 27 2007, 13:09) Та... May 27 2007, 19:01    muravei А может лучше мерять период вх сигнала , а не част... May 28 2007, 07:02     DAndy_boy Цитата(muravei @ May 28 2007, 11:02) А мо... May 28 2007, 07:13      muravei Цитата(DAndy_boy @ May 28 2007, 11:13) Т.... May 28 2007, 17:11     Диm Цитата(muravei @ May 28 2007, 13:02) А мо... May 29 2007, 06:33 GDI При умножении константы на константу, конечно резу... May 28 2007, 07:31 DAndy_boy Цитата(GDI @ May 28 2007, 11:31) ...Это у... May 28 2007, 07:50 DAndy_boy Я все понял... вечером буду пробовать.... о резуль... May 29 2007, 04:40 DAndy_boy Начал разбираться с режимом захвата.... и все ника... May 29 2007, 10:26 aesok Есть такое волшебное слово: volatile. avr-libc-use... May 29 2007, 10:33  DAndy_boy Цитата(aesok @ May 29 2007, 14:33) Есть т... May 29 2007, 10:52   aesok Цитата(DAndy_boy @ May 29 2007, 14:52) Я ... May 29 2007, 11:12    DAndy_boy Цитата(aesok @ May 29 2007, 15:12) а поче... May 29 2007, 11:21    muravei Цитата(aesok @ May 29 2007, 15:12) В хелп... May 29 2007, 13:24 DAndy_boy Господа, опять прошу помощи…. Почитав описание ко... Jun 1 2007, 04:43 VDV значения могут прыгать из-за прескалера еще.
его б... Jun 19 2007, 17:09 GDI Цитатапоскольку входной сигнал имеет форму пилы (о... Jun 20 2007, 07:04
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|