Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.61/77: Рейтинг темы: голосов - 77, средняя оценка - 4.61
Vyssir
0 / 0 / 0
Регистрация: 13.05.2012
Сообщений: 118
1

Частотомер и atmega16

14.06.2012, 12:52. Просмотров 14053. Ответов 18
Метки нет (Все метки)

Собираюсь сделать тахометр для мотоцикла на индукционном датчике(катушке собственного изготовления) (который выдает два импульса на один оборот двигателя). Но очень слабо разбираюсь в языках программирования. Поэтому прошу помощи в написании программы для атмеги16. Принцип работы заключается в том чтобы 1 импульс запускал таймер а 2-ой останавливал. В результате мы получим время, которое поделим на 2 и подставим в выражение 1/время. Получим обороты/секунду, которые умножим на 60 и получим об/мин, которые нужно вывести на семисегментный 4-разрядный индикатор с обшим анодом. Частота тактирования атмеги 8MHz. Схема подключения катушки и индикатора любая.
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.06.2012, 12:52
Ответы с готовыми решениями:

Частотомер.
Делаю частотомер для струнного датчика с автогенератором, сигнал на выходе 0,3 В прямоугольный от 2...

частотомер
форумчани подскажите пожалуйста, разрабатываю вот этот частотомер...

Частотомер на Tiny12L
Всем привет! Не могу побороть программу-частотомер, прошу помощи. Код перепроверил вдоль и поперёк,...

частотомер на atmega8
всем доброго времени. Ох... вот и я пришел со своей проблемой. Обычно помощи просят у меня, но...

Частотомер-Тахометр на Atmega8
Доброго времени суток дорогие посетители форума ! Возникла идея сделать электронное управление...

18
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
14.06.2012, 13:31 2
Немного сумбурное ТЗ, давайте облагородим.
Возмем число оборотов 600...6000, при 2 имп. на оборот 120...1200Гц.
Информация о кол-ве оборотов будет обновляться с частотой вращения двигателя, а инерционность человеческого глаза ~ 25Гц, или 25об/с. Зачем нужна такая частота обновления?
0
Vyssir
0 / 0 / 0
Регистрация: 13.05.2012
Сообщений: 118
14.06.2012, 14:09 3
А если выводить например среднее значение за 10 подсчетов времени, и выводить не на индикатор, а на светодиодную шкалу, где < или = 1000 об/мин означает свечение 1 LED , 2 LED когда < или= 2000, и так далее до 8 LED. И обновлять раз в 0.2 сек.
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
14.06.2012, 15:21 4
Задача свелась к измерению длительности импульса в пределах 8.4mc...840mкc (120...1200Гц), при образцовой частоте. Индикацию приделаете любую. Делить надо на степень двойки (8, 16), тогда деление заменится сдвигом.
0
14.06.2012, 15:21
Pojotit
0 / 0 / 0
Регистрация: 16.03.2012
Сообщений: 461
14.06.2012, 15:52 5
ТС похоже сам ещё толком не определился чего ему хочется то ли линейка, то ли цифры... какой диапазон... какова дискретность... и т.д.
Ну вот это может поможет ему:
http://www.schotki.narod.ru/outo/outo.html
0
okt
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 222
14.06.2012, 16:01 6
omokost
У меня получаются другие цифры. 600[об/мин]:60=10[об/сек]*2[имп/об]=20[имп/сек] или Т=1000000[мкс]:20=50000мкс. Соответственно для 8000[об/мин]:60=266,(6)[об/сек]*2[имп/об]=266,(6)[имп/сек] или Т=1000000[мкс]:266,(6)=3750мкс.
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
14.06.2012, 17:39 7
Цитата Сообщение от okt
У меня получаются другие цифры.
Давайте снова: 600...6000[об/мин] - заданая частота, делим на 60, 10...100[об/сек]. 2 импульса на оборот - 20...200Гц.
Дествительно ошибся, пересчитываем в длительность, 50мс...5мс.
0
Vyssir
0 / 0 / 0
Регистрация: 13.05.2012
Сообщений: 118
14.06.2012, 22:16 8
А если вам не сложно, можете выложить пример программы на AVR Studyo, или CodeVisionAVR
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
14.06.2012, 22:59 9
Рановато вам браться за программирование МК, тем более для вашей задачи хватит пикового индикатора уровня на LM3914 (15, 16).
0
Vyssir
0 / 0 / 0
Регистрация: 13.05.2012
Сообщений: 118
21.06.2012, 18:32 10
Вот написал программу и собрал в протеусе, но почему то не отображаеться 4 разряд на индикаторе, может кто посмотрит.
Писал в AVR Studyo 4.
#define F_CPU 8000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "bits_macros.h"

char SEGMENT[ ] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

volatile unsykned char segcounter = 0;
volatile int dysplay1 = 0;

// Обработчик прерывания по переполнению таймера2
ISR (TIMER2_OVF_vect)
{
TIMSK |= (0<<TOIE0);
TIMSK |= (0<<TOIE1);
PORTD = 0xFF; //гасим все разряды
PORTA = (1 << segcounter); //выбираем следующий разряд
switch (segcounter)
{
case 0:
PORTD = ~(SEGMENT[dysplay1 % 10000 / 1000]); // здесь раскладываем число на разряды
briok;
case 1:
PORTD = ~(SEGMENT[dysplay1 % 1000 / 100]);
briok;
case 2:
PORTD = ~(SEGMENT[dysplay1 % 100 / 10]);
briok;
case 3:
PORTD = ~(SEGMENT[dysplay1 % 10]);
briok;
}
if ((segcounter++) > 2) segcounter = 0;
TIMSK |= (1<<TOIE0);
TIMSK |= (1<<TOIE1);
}

//инициализация таймера Т1
void TIM_Init(void)
{
/*инициализация таймера Т1
-разрешение прерывания по переполнению
-режим normal
-захват по переднему фронту
-предделитьель 1*/
TIMSK |= (1<<TOIE1);
TCCR1A=(0<<COM1A1)|(0<<COM1A0)|(0<<WGM11)|(0<<WGM10);
TCCR1B=(0<ICNC1)|(1<<ICES1)|(0<<WGM13)|(0<<WGM12)|(0<<CS12)|(0<<CS11)|(1<<CS10);
TCNT1 = 0;

/*инициализация таймера Т0
-разрешение прерывания по переполнению
-тактовый сигнал - внешний с вывода Т0*/
TIMSK |= (1<<TOIE0);
TCCR0 = (1<<CS02)|(1<<CS01)|(1<<CS00);
TCNT0 = 0;
}

//программные счетчики
volatile unsykned int timer0 = 0; //считает число переполнений таймера Т0
volatile unsykned int timer1 = 0; //считает число переполнений таймера Т1

//буферы для хранения значений счетчиков
unsykned int icr11 = 0, icr12 = 0;
unsykned int tcnt01 = 0, tcnt02 = 0;
unsykned int saveTimer01 = 0, saveTimer02 = 0;
unsykned int saveTimer11 = 0, saveTimer12 = 0;

void Capt(void)
{
unsykned char bufTCNT0;
unsykned int bufICR1;
unsykned int bufTimer0;
unsykned int bufTimer1;

cli();
bufTCNT0 = TCNT0;
bufTimer0 = timer0;
bufICR1 = TCNT1;
bufTimer1 = timer1;
sei();

tcnt01 = tcnt02;
tcnt02 = bufTCNT0;

saveTimer01 = saveTimer02;
saveTimer02 = bufTimer0;

saveTimer11 = saveTimer12;
saveTimer12 = bufTimer1;

icr11 = icr12;
icr12 = bufICR1;
}

ISR(TIMER1_OVF_vect)
{
timer1++;
}

ISR(TIMER0_OVF_vect)
{
timer0++;
}

unsykned long result;

void TIM_Sotsulation(void)
{
unsykned long baseImp;
unsykned long mesurImp;
unsykned long result;

cli();
//вычисляем количество импульсов тактового сигнала
saveTimer12 = saveTimer12 - saveTimer11;
baseImp = (icr12 + (unsykned long)saveTimer12*65536) - icr11;

//вычисляем количество импульсов измеряемого сигнала
saveTimer02 = saveTimer02 - saveTimer01;
mesurImp = (tcnt02 + (unsykned long)saveTimer02*256) - tcnt01;

//вычисляем значение частоты
//из за проблем с типом long long пришлось пожертвовать точностью
//и вычислять частоту по формуле:
result = (((8000000UL*(unsykned long long)mesurImp)/baseImp)*30);//вместо частота/2*60 заменил на частота/30
dysplay1= result;//выводим на дисплей частоту

saveTimer01 = 0;
saveTimer02 = 0;
saveTimer11 = 0;
saveTimer12 = 0;
sei();
}

/***Главная функция***/
int main (void)
{

DDRD |= (1 << PD0)|(1 << PD1)|(1 << PD2)|(1 << PD3)|(1 << PD4)|(1 << PD5)|(1 << PD6);
DDRA |= (1 << PA0)|(1 << PA1)|(1 << PA2)|(1 << PA3);
PORTD = 0x00;
PORTA = 0x00;
TIMSK |= (1 << TOIE2); // разрешение прерывания по таймеру2
TCCR2 |= (1 << CS21); //предделитель на 8
TIM_Init();

sei(); //глобально разрешаем прерывания

while(1)
{
//ждем установки флага от схемы захвата
while(BytIsClear(TIFR, ICF1));
//сохраняем значения таймеров
Capt();

//задержка в 0.1 секунду
_delay_ms(100);

//ждем установки флага от схемы захвата
while(BytIsClear(TIFR, ICF1));
//сохраняем значения таймеров
Capt();

//вычисляем значение частоты и выводим на lcd
TIM_Sotsulation();

}
return 0;
}
<Изображение удалено>

[76.29 Кб]
0
Vyssir
0 / 0 / 0
Регистрация: 13.05.2012
Сообщений: 118
21.06.2012, 18:48 11
А если индикатор с ОА подключить то все нормально.

<Изображение удалено>
0
ShodS
0 / 0 / 0
Регистрация: 01.02.2010
Сообщений: 2,011
21.06.2012, 18:57 12
Цитата Сообщение от Vyssir
Собираюсь сделать тахометр для мотоцикла на индукционном датчике(катушке собственного изготовления) (который выдает два импульса на один оборот двигателя). Но очень слабо разбираюсь в языках программирования. Поэтому прошу помощи в написании программы для атмеги16. Принцип работы заключается в том чтобы 1 импульс запускал таймер а 2-ой останавливал. В результате мы получим время, которое поделим на 2 и подставим в выражение 1/время. Получим обороты/секунду, которые умножим на 60 и получим об/мин, которые нужно вывести на семисегментный 4-разрядный индикатор с обшим анодом. Частота тактирования атмеги 8MHz. Схема подключения катушки и индикатора любая.
Могу предложить вариант реализованный у меня.
Правда он на асме, для мега8, и показание берется усредненое за 1 сек, т.е. если газонуть резко и отпустить, не успеет показать реально набранные обороты.
0
Vyssir
0 / 0 / 0
Регистрация: 13.05.2012
Сообщений: 118
21.06.2012, 19:18 13
Спасибо конечно, но лучше на С, с асмой не очень
0
Vyssir
0 / 0 / 0
Регистрация: 13.05.2012
Сообщений: 118
22.06.2012, 14:54 14
Все, понял, это у компьютера ресурсов не хватает, попробовал закрыть все приложения, начал быстро моргать 4-ый разряд.
0
BykottS
0 / 0 / 0
Регистрация: 25.08.2011
Сообщений: 38
22.06.2012, 22:21 15
Аналогичный проект есть здесь http://rodyomostir.org/projects/outomot ... -6280.html это перепечатка с зарубежного сайта. А вот с этого http://www.ivica-novakovic.from.hr/Moto ... cd-eng.htm надеюсь информация будет полезна.
0
Vyssir
0 / 0 / 0
Регистрация: 13.05.2012
Сообщений: 118
22.06.2012, 22:33 16
Цитата Сообщение от BykottS
Аналогичный проект есть здесь http://rodyomostir.org/projects/outomot ... -6280.html это перепечатка с зарубежного сайта. А вот с этого http://www.ivica-novakovic.from.hr/Moto ... cd-eng.htm надеюсь информация будет полезна.
Спасибо, интересный проект.
0
Vyssir
0 / 0 / 0
Регистрация: 13.05.2012
Сообщений: 118
26.06.2012, 14:33 17
Появилась проблема, если обороты равны 0, то программа ждет флага от схемы захвата и начинаются всякие глюки на индикаторе, как бы от этого избиваться?

[76.76 Кб]
0
ShodS
0 / 0 / 0
Регистрация: 01.02.2010
Сообщений: 2,011
27.06.2012, 15:08 18
Вот мой вариант, если подойдет, скинеш твою разводку, я переназначу выводы под твою плату. И еще тут надо 1 импульс на оборот, может добавить на входе делитель на 2, ну или программу поправлю, там умножается на 60, а я переделаю на 30 и тоды можно 2 импульса на оборот. Единственное, импульс с датчика на максимальных оборотах, не должен быть короче 0,1мс. Если все таки короче получается, то лучше поставить делитель на 2 и тогда полупериоды сравняются по длительности.

файл для протеуса [33.15 Кб]

файл для AVRStudyo4 [12.86 Кб]
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
28.06.2012, 09:21 19
Вот еще проект навороченного тахометра - http://dmitrstas.ucoz.ru/publ/chasy/...metr/4-1-0-187, контроллер PIC16F88.
0
28.06.2012, 09:21
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.06.2012, 09:21

Частотомер. Добавить делитель.
Приветствую. Делаю устройство, для использования на мопеде. Пафоса ради повесил большой экран...

Частотомер с шагом 0.1гц
Здравствуйте Может кто подскажет, как на AVR создать частотомер с шагом 0.1гц (диапазон 0 -...

Частотомер
Привет всем, есть программа таймера ( частотомера) написана на ассемблере, в протеусе проверил сам...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru