|
Тахометр на 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();// динамическая индикация
}
|
|
|
|
|
 |
Ответов
|
Jun 1 2007, 04:43
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 25-09-05
Из: Москва
Пользователь №: 8 922

|
Господа, опять прошу помощи…. Почитав описание компаратора и режим захвата таймера я пришел к выводу, что при использовании внутреннего опорного напряжения захват будет идти только по срезу входного сигнала… Что не очень удобно, по крайне мере в моем случае. По этому пришлось использовать внешнее опорное напряжение и поменять местами входы компаратора, т.е. на не инвертирующий вход подавать измеряемый сигнал, а на другой - внешнее опорное напряжение? поскольку входной сигнал имеет форму пилы (от 0 до 100 Гц). И все-таки в процессе работы появились подозрения, что бывают моменты, когда захват происходит как по срезу, так и по фронту. И в результате никак не могу получить стабильные результаты, значения прыгают на 1,2 герца. Или тут не обойтись без усреднения за несколько интервалов? Прилагаю код, может кто увидит косяк… Код #define QZ 7372800L #define TIME_OCR1A ((QZ / 1024)) volatile long Zahvat1=0;// захват первого фронта volatile long Zahvat2=0;// захват первого фронта volatile long TOVER=0;// то количество импульсов которое насчитали до //сброса таймера на секунде и до прихода фронта измеряемого сигнала long Zah_end;// количество тактов Таймера между фронтами volatile int k=0; // указывает на каком этапе находимся
SIGNAL (TIMER1_CAPT_vect) { // здесь происходит захват значения таймера if(k==0) {// захватываем первый фронт Zahvat1=ICR1+TOVER; TOVER=0; k=1; } else if(k==1) {// захватываем второй фронт Zahvat2=ICR1+TOVER; TOVER=0; //данные готовы для преобразования и вывода k=5; } }
SIGNAL (TIMER1_COMPA_vect) { // прерывание каждую секунду // поскольку значение таймера сбрасывается, то сохраняем количество импульсов которые насчитали if(k!=5 && TOVER!=0){Zahvat1=Zahvat2=0;k=0;} if(k==0) {TOVER+=TIME_OCR1A-Zahvat1;Zahvat1=0;} else if(k==1) { TOVER+=TIME_OCR1A-Zahvat2;Zahvat2=0;} else if(k==5)TOVER=0; }
/**************************************************************************** Timer1_init() Функция инициализации Timer1. ****************************************************************************/ void Timer1_init(void) { OCR1A = TIME_OCR1A; /* прерывание раз в секунду */ TCCR1A = 0x00; TCCR1B = (1 << 3) | 0x05; TIMSK |= 1 << 4; /* разрешить прерывание OCIE1A */ TIMSK |=1<<5; // режим захвата }
int main() { int g; Timer1_init();
PORTC=0x00; DDRC=0xFF;
// Input/Output Ports initialization // Port A initialization // Func7=Out Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=0 State6=0 State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00; DDRA=0xC0;
DDRA|=(1<<4);
// 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=0x00;
// Port D initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=T State2=T State1=0 State0=0 PORTD=0x0C; DDRD=0xF3;
// Analog Comparator initialization // Analog Comparator: On // Analog Comparator Input Capture by Timer/Counter 1: On ACSR=0x04; SFIOR=0x00;
sei(); do { if(k==5) {// значения готовы if(Zahvat2>Zahvat1) { // значения верны str_out[0]=0; // выводим флаг ошибки (все удачно) Zah_end=(Zahvat2-Zahvat1); g=(TIME_OCR1A)/Zah_end; // вычисляем период TOVER=0; str_out[5]=g%10;g/=10; str_out[4]=g%10;g/=10; str_out[3]=g%10;g/=10; str_out[2]=g%10;g/=10; } else // значения не верны след. не учитываем их str_out[0]=1; // выводим флаг ошибки k=0; }
reload(); // динамическая индикация }while(1);
}
|
|
|
|
|
Jun 19 2007, 17:09
|
Частый гость
 
Группа: Участник
Сообщений: 152
Регистрация: 18-03-06
Пользователь №: 15 366

|
значения могут прыгать из-за прескалера еще. его бы тоже обнулять надо. делал как-то сам тахометр-спидометр на tyni2313 с выводом на жк экран, все работало. считал скорость, обороты, километраж. в аттаче код асмовский с комментариями. посмотрите, мож, поможет.
|
|
|
|
Сообщений в этой теме
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 Если хватит диапазона то сделать так:
Кодg = Speed... May 28 2007, 07:18 DAndy_boy Цитата(GDI @ May 28 2007, 11:18) Если хва... May 28 2007, 07:22  ReAl Цитата(DAndy_boy @ May 28 2007, 10:22) Во... May 28 2007, 07:50 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 GDI Цитатапоскольку входной сигнал имеет форму пилы (о... Jun 20 2007, 07:04
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|