Перейти к содержанию

Тахометр на Atmega8


Рекомендуемые сообщения

Здравствуйте уважаемые, стоит задача: сделать бесконтактный тахометр на Atmega8,  вывод данных на дисплей.

Идея какая: мерить время каждого оборота - Т, с помощью прерывания на ножке PD3 и запускать таймер на отчет времени, и когда прерывание срабатывает повторно останавливать таймер и записать в переменную timer значение TCNT1 и отключить таймер до следующего прерывания. Чтоб узнать период одного оборота измерительного колеса, нужно знать время одного тика таймера, что составляет 1 / (частота МК / предделитель) и значение регистра TCNT1 за один оборот измерительного колеса которое записано в переменную timer. Произведение данных величин можно записать так: T = (timer * tодного тика). Чтобы узнать частоту измерительного колеса в секунду, нужно 1/T. Частота - это произведение количества оборотов на время. Чтобы преобразовать в об/мин, нужно подставить 60. Результат: f = RPM/60,   f = 1/T,  RPM/60 = 1/T.  в итоге: RPM = 60/T

Конечная формула: RPM = 60/(timer * tодного тика)

Проблема с кодом, уважаемые, скажите, что здесь не так:

char buff [0];
volatile unsigned int change = 0;
volatile unsigned int timer = 0;
float T = 0;
unsigned int RPM = 0; 
unsigned int Frec = 0;


ISR(INT0_vect)
{

	if(change == 0)
	{
		TCNT1 = 0;
		asm("nop");
		TIMSK = (1<<OCIE1A);
		timer = 0;
	    
	} 
	if(change == 1)
	{
	   timer = TCNT1; 	
	   asm("nop");
	   TIMSK = (0<<OCIE1A);
	}
  


   if(change == 0) change = 1;
     else change = 0;

}


int main(void)
{
   //записываем это значение в верхнюю часть регистра  (8 бит из 11)
   UBRRH = (unsigned char) (51 >> 8);
   
   // записываем оставшуюся часть регистра
   UBRRL = (unsigned char) 51;
   
   // задействуем передатчик и приемник
   UCSRB = (1 << RXEN) | (1 << TXEN);
   
   //устанавливаем 2 стоповых бита и 8-битную длину передаваемого символа
   UCSRC = (1 << USBS) | (3 << UCSZ0);
   
   
   GICR|=(1<<INT0); //разрешаем прерывание по INT0
   MCUCR |= (0<<ISC00)|(0<<ISC01); //прерывание по фронту сигнала на INT0
   TCCR1B = (1<<CS12)|(1<<WGM12); // /256, 8*10^6 / 256 = 31250 KHz // 1/31250 = 0,000032 sec
   OCR1A = 32768;
   sei();
   
	
	while (1) 
    {
    
	T = timer * 0,000032; // perod 1 RPM, 0,000032 время одного тика 
//     Frec = 1/T;
//     RPM = Frec*60;
	RPM = 60 / T;
	
	
	sprintf(buff, "%5d", RPM);
	
	while (! (UCSRA & (1 << UDRE)) );
	{
		UDR = buff;//когда передатчик готов посылаем 8 бит данных
	}
  
    }
}

 

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Только что, Yuriy.pv сказал:

Для этого есть нога ICP

Я знаю, я просто хочу разобраться в алгоритме, и решил сделать все более, для себя, наглядней

Изменено пользователем Kostyanskiy
Ссылка на комментарий
Поделиться на другие сайты

Организация питания на основе надежных литиевых аккумуляторов EVE и микросхем азиатского производства

Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

29 минут назад, Kostyanskiy сказал:

что здесь не так:

сам алгоритм вычисления периода.
обычно запускается 16-и битный таймер, в прерывании по переполнению таймера инкриминируется переменная тайм 32бит
в прерывании от ногадрыга читается таймер и складывается с тайм , полученная сумма вычитается из предыдущего значения суммы и получается значение периода в тактах таймера.
далее полученные значения пропускаются через цифровой фильтр скользящего среднего и переводятся в частоту.

ЗЫ и использовать тип флоат в 8-ми битниках кагбе моветон.

Ссылка на комментарий
Поделиться на другие сайты

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

ISR(TIMER1_COMPA_vect)
{
	timer++;
}
//=============================================================================================================
ISR(INT0_vect)
{
   SumNew = (TCNT1 + timer) - SumLast;
   T = SumNew;
   SumLast = SumNew; 
   TCNT1 = 0;
   
}
int main(void)
{  
  //инициализация переферии 
	
	while (1) 
    {
    
	RPM = 60/T;
    }
}

То есть, вот так?

Изменено пользователем Kostyanskiy
Ссылка на комментарий
Поделиться на другие сайты

Литиевые аккумуляторы EVE Energy и решения для управления перезаряжаемыми источниками тока (материалы вебинара)

Опубликованы материалы вебинара Компэл, посвященного литиевым аккумуляторам EVE Energy и решениям для управления перезаряжаемыми источниками тока.

На вебинаре мы представили информацию не только по линейкам аккумуляторной продукции EVE, но и по решениям для управления ею, что поможет рассмотреть эти ХИТ в качестве дополнительной альтернативы для уже выпускающихся изделий. Также рассмотрели нюансы работы с производителем и сервисы, предоставляемые Компэл по данной продукции. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

тогда volatile uint32_t timer = 0;

ISR(TIMER1_COMPA_vect)
{
    (timer << 16)++;
}

Или как?

59 минут назад, IMXO сказал:

обычно запускается 16-и битный таймер, в прерывании по переполнению таймера инкриминируется переменная тайм 32бит
в прерывании от ногадрыга читается таймер и складывается с тайм , полученная сумма вычитается из предыдущего значения суммы и получается значение периода в тактах таймера.

Можете пожалуйста поподробней рассказать почему так? Или дайте источники где про это можно почитать

Ссылка на комментарий
Поделиться на другие сайты

@Kostyanskiy  Если один тик равен 1/31250, то получается RPM = 60/(timer * 1/31250) = 60*31250 / timer = 1875000 / timer . Таким образом очень медленное и трудоёмкое умножение на 0.000032 и деление 60/Т с плавающей запятой заменяем на быстрое и лёгкое целочисленное деление, всего одна операция. Долой флоат!

Изменено пользователем Yurkin2015
Ссылка на комментарий
Поделиться на другие сайты

3 минуты назад, Yurkin2015 сказал:

плавающей запятой заменяем на быстрое и лёгкое целочисленное деление, всего одна операция

Я понял, но при чем здесь

13 минут назад, Kostyanskiy сказал:

16-и битный таймер, в прерывании по переполнению таймера инкриминируется переменная тайм 32бит

И какая зависимость скорости колеса измерения, предделителя таймера и переменной которая инкрементируется в прерывании по переполнению таймера?

Ссылка на комментарий
Поделиться на другие сайты

timer+=(1<<16)

могу, предположим вы настроили таймер на приращение 1мкс.
пусть таймер переполнился 10 раз, 
и когда прошло прерывание от ногадрыга таймер досчитал до пусть будет 34566,

то в сумме вы получите SumNew = 10*2^16+34566 = 689926

при первом проходе SumLast=0
то T = SumNew - SumLast = 689926 - 0 = 689926мкс

F=60/(T*10^-6)=60000000/T = 86 обр/мин
если нужно точнее
F=600/(T*10^-6)=600000000/T = 86,9 обр/мин (естественно получим 869 , а запятую ставим сами в нужном месте)

 

Ссылка на комментарий
Поделиться на другие сайты

19 минут назад, IMXO сказал:

10*2^16

небольшое уточнение, почему 2 в степени 16 и умноженное на 10?

32 минуты назад, IMXO сказал:

T = SumNew - SumLast

Я понял почему здесь так, из-за нелинейности движения измер. колеса разное время движения точки измерения, но почему мы тогда просто не ограничемся счетчиком TCNT1 зачем нам еще и переполнение по прерыванию таймера и как оно играет на конечный результат?

 

 

 

Ссылка на комментарий
Поделиться на другие сайты

14 minutes ago, Kostyanskiy said:

зачем нам еще и переполнение

Вот, частота тиков 31250. Значит за 2 с небольшим секунды 16-битный счётчик переполнится и начнёт считать снова с нуля. Мы же не знаем, какие обороты будут измеряться. Может, минимально 10 об/мин нужно измерять, тогда счётчик много раз переполнится между прерываниями от оборотов. На этот случай и делается учёт переполнений.

Изменено пользователем Yurkin2015
Ссылка на комментарий
Поделиться на другие сайты

20 минут назад, Yurkin2015 сказал:

тогда счётчик много раз переполнится между прерываниями от оборотов. На этот случай и делается учёт переполнений.

А что нам мешает каждый раз в прерывании от ножки сбрасывать счетчик в 0?

Ссылка на комментарий
Поделиться на другие сайты

42 минуты назад, Kostyanskiy сказал:

зачем нам еще

затем, что включив предделитель на таймере, вы его загрубили
возьмем средний тахометр 12000обр/мин это  200Гц или 5000мкс
инкремент таймера у вас 32мкс те всего 156 тактов

формула расчета
F=1875000/N
F=1875000/156=12019обр/мин
F=1875000/157=11942
F=1875000/158=11867
те единица отсчета на придельной частоте дает ошибку в +/-75..77 обр/мин

те чем меньше время приращения таймера тем точнее измерение на приделе тахометра,
и тем больше нужна разрядность счетчика на нижнем приделе тахометра.
 

3 минуты назад, Kostyanskiy сказал:

А что нам мешает

все тоже самое... пока МК зашел в прерывание пока выполнил нужные вычисление таймер тикает, обнулил = создал ошибку
сделал вычитание = нивелировал ошибку

Ссылка на комментарий
Поделиться на другие сайты

24 minutes ago, Kostyanskiy said:

в прерывании от ножки

Ну, сбросили в ноль, а  следующее прерывание от ножки пришло через 5 секунд, например, обороты ну очень маленькие, таймер успеет переполнится пару раз.

Ссылка на комментарий
Поделиться на другие сайты

9 часов назад, Yurkin2015 сказал:

Ну, сбросили в ноль, а  следующее прерывание от ножки пришло через 5 секунд, например, обороты ну очень маленькие, таймер успеет переполнится пару раз.

Наконец-то дошло как это работает, но зачем тогда первые 16 бит инкрементировать, почему не просто timer++?

11 часов назад, Kostyanskiy сказал:
11 часов назад, IMXO сказал:

T = SumNew - SumLast

 

И если посмотреть с другой стороны, то это не совсем период, это разность времени между 2 оборотами, зачем нам эта разность если это не период ?

Ссылка на комментарий
Поделиться на другие сайты

@Kostyanskiy  Всё смешалось в одну кучу.

Обычно таймер не зануляют, пусть себе крутится ровно без всяких вмешательств. При каждом внешнем прерывании от ножки просто считываем текущее показание счётчика. Колесо вращается быстро, по ходу пьесы получаем от счётчика числа, например:

2410, 3620, 4830, 6040 ....

Поэтому для вычисления длительности одного оборота надо вычесть предыдущее показание из величины, которую только что прочитали. Находим в прерываниях разность:

3620 - 2410 = 1210,

4830 - 3620 = 1210,

6040 - 4830 = 1210

и так далее ...

То есть период вращения равен 1210 тиков. Без всяких занулений и лишних телодвижений.

Изменено пользователем Yurkin2015
Ссылка на комментарий
Поделиться на другие сайты

2 часа назад, Kostyanskiy сказал:

Наконец-то дошло как это работает, но зачем тогда первые 16 бит инкрементировать, почему не просто timer++?

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

SumNew = timer + TCNT1

можно и просто инкрементировать timer описавши его как  unsigned int , но тогда  при нахождении суммы нужно принудительно компилятору указывать размерность переменной при сложении

SumNew = ((unsigned long int)timer)<<16 + TCNT1

Ссылка на комментарий
Поделиться на другие сайты

@IMXO помогите с кодом пожалуйста, а то у меня немного руки кривые :unsure:

volatile uint32_t timer = 0;
volatile unsigned int T = 0;
volatile unsigned int SumNew = 0;
volatile unsigned int SumLast = 0;
volatile unsigned int RPM = 0;


ISR(TIMER1_COMPA_vect)
{
	timer+=(1<<16);
}

ISR(INT0_vect)
{
	SumNew = (TCNT1 + timer);
	T = SumNew - SumLast;
	SumLast = SumNew;
}



int main(void)
{
	ST7789_Init(3);
	LCD_Fill(BLACK);
	GICR|=(1<<INT0); //разрешаем прерывание по INT0
	MCUCR |= (0<<ISC00)|(0<<ISC01); //прерывание по фронту сигнала на INT0
	TCCR1B = (1<<CS12)|(1<<WGM12); // /256, 8*10^6 / 256 = 31250 KHz // 1/31250 = 0,000032 sec
	TIMSK = (1<<OCIE1A);
	OCR1A = 65535; // на переполнении 
	sei();
  
  while(1)
	{  
	   RPM = 60/T;
	   TFTDrawValue(0, 16, WHITE, BLACK, RPM);
	  
	}
	
}

 

Изменено пользователем Kostyanskiy
Ссылка на комментарий
Поделиться на другие сайты

:) вот интересно вы какой ожидаете результат в попытке 32бита впихнуть в  16битную переменную?

ну и тему перечитайте формула частоты и как она получается выше написано.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...