Понедельник, 21.09.2020, 19:58
Микроконтроллерная техника AVR
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Микроконтроллеры » Вопросы по МК » Помогите с тахометром на atmega! (Прошивка)
Помогите с тахометром на atmega!
igorunmДата: Пятница, 08.02.2013, 16:07 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 8
Репутация: 0
Статус: Offline
Добрый день. Все же пришлось обратиться к Вам... Задача: сделать автомобильный тахометр на атмеге и лсд 16*2 , обновление показаний (пересчет) должен производился как можно чаще, минимум раз в 0,5 сек. Тахометр необходим для оперативного контроля за оборотами двигателя, т.к. будет контролировать подачу в ДВС закиси азота на строго определенном интервале оборотов. Работаю в CVAVR, за основу взял пример частотомера из раздела "СТАТЬИ" Вот что получилось у меня на данном этапе, но загвостка в том, что измерения обновляются каждую секунду, что очень долго...  

#include "mega16.h"
#asm
.equ __lcd_port=0x18
#endasm
#include "lcd.h"
#include "delay.h"

typedef unsigned char byte;
typedef unsigned long ulong;

flash byte txt[]="freq:";

byte ovf;
byte i;
byte buff[17];
ulong freq;

interrupt [TIM1_OVF] void tmr1_ovf() {
ovf++;
}

void main(){
TCCR1A=0;
TCCR1B=0;
TIMSK=4;
ACSR=0x80;
lcd_init(16);
#asm("sei")
buff[16]=0;
while (1) {
ovf=0;
TCNT1=0;
TCCR1B=7;

//Ожидание около 1 сек

delay_ms(999);
delay_us(243);

TCCR1B=0; 
freq=(((ulong)ovf*65536+TCNT1)*121.212)*0.001;
i=4;
do {
i--;
buff[i]=freq%10+0x30;
freq/=10;

} while(i!=0);
lcd_clear();
lcd_puts(buff);
}
}


Сообщение отредактировал igorunm - Пятница, 08.02.2013, 16:08
 
HiSERДата: Пятница, 08.02.2013, 17:24 | Сообщение # 2
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
В этом примере считается количество тиков в секунду. Тебе же надо считать время между импульсами.
Используй пин ICP и 1й таймер.
 
igorunmДата: Пятница, 08.02.2013, 17:34 | Сообщение # 3
Рядовой
Группа: Пользователи
Сообщений: 8
Репутация: 0
Статус: Offline
а подскажите, как это будет в коде выглядеть? и как выставить интервал времени измерения
 
HiSERДата: Пятница, 08.02.2013, 18:15 | Сообщение # 4
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
А почитать даташит, не?
Вот пример: http://my-avr.at.ua/load/icp/1-1-0-40
 
igorunmДата: Пятница, 08.02.2013, 18:37 | Сообщение # 5
Рядовой
Группа: Пользователи
Сообщений: 8
Репутация: 0
Статус: Offline
посмотрел, постарался вникнуть, попытался воткнуть дисплей, cvavr сразу отказался компилировать...

typedef union {
struct {
byte l;
byte h;
}b;  --->  the strukture type '?2' must be defined outside this declaration
word w;
}wb;  ------> sintax error

отсутствует функция main

Нельзя ли немного раскоментировать код?
 
HiSERДата: Пятница, 08.02.2013, 18:50 | Сообщение # 6
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
это определение типа, должно быть в начале
 
igorunmДата: Пятница, 08.02.2013, 19:09 | Сообщение # 7
Рядовой
Группа: Пользователи
Сообщений: 8
Репутация: 0
Статус: Offline
Не могу найти даже описание что такое "typedef union " и как с ним работать. Прошу помочь, как Вы уже поняли, знания не глубоки, максимум наверное смогу дисплей подключить, вывести на него данные...
 
HiSERДата: Пятница, 08.02.2013, 19:17 | Сообщение # 8
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
Покажи код и скажи версию компилятора.
 
igorunmДата: Пятница, 08.02.2013, 19:28 | Сообщение # 9
Рядовой
Группа: Пользователи
Сообщений: 8
Репутация: 0
Статус: Offline
cvavr ver. 1.25.8 standart

/*HiSER ©2013*/

#include <mega8.h>
#include <lcd.h>
 #asm
   .equ __lcd_port=0x12; PORTD    /* ÆÊÈ äèñïëåé ïîäêëþ÷èëè ê ïîðòó I/O D */
 #endasm    
 byte buff[17]; 
typedef unsigned char byte;
typedef unsigned int word;
typedef union {
struct {
byte l;
byte h;
}b;
word w;
}wb;
main (void)
wb tmr_cnt;
byte pulse_freq;
bit sync;

interrupt [TIM1_CAPT] void tmr1_capt() {
sync=1;
TCNT1H=0;
TCNT1L=0;
}

void main() {
ACSR=0x80;

TCCR1A=0;
TCCR1B=0;
TCNT1H=0;
TCNT1L=0;
TIMSK=0x20;

#asm("sei")

TCCR1B=1;

//sync first pulse
sync=0;
while (sync==0);

while (1) {
sync=0;
while (sync==0);
tmr_cnt.b.l=ICR1L;
tmr_cnt.b.h=ICR1H;

tmr_cnt.w++;
pulse_freq=1000000/tmr_cnt.w;
//pulse_freq - here frequency
buff[i]=pulse_freq%10;
}
lcd_init( 16 );               /* èíèöèàëèçàöèÿ íà 16 ñèìâîëîâ */
    lcd_clear( ); 
    lcd_puts(buff);
}


Сообщение отредактировал igorunm - Пятница, 08.02.2013, 19:30
 
HiSERДата: Пятница, 08.02.2013, 19:31 | Сообщение # 10
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
Компилятор свежее скачай, версии 2.xx.x
 
igorunmДата: Пятница, 08.02.2013, 19:33 | Сообщение # 11
Рядовой
Группа: Пользователи
Сообщений: 8
Репутация: 0
Статус: Offline
свежее почему-то не понимает даже lcd_init()
 
HiSERДата: Пятница, 08.02.2013, 19:41 | Сообщение # 12
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
Код
/*HiSER ©2013*/

#include <mega8.h>
#include <lcd.h>
#asm
.equ __lcd_port=0x12; PORTD
#endasm

typedef unsigned char byte;
typedef unsigned int word;
typedef union {
struct {
byte l;
byte h;
}b;
word w;
}wb;

wb tmr_cnt;
byte pulse_freq;
bit sync;
byte buff[17];

interrupt [TIM1_CAPT] void tmr1_capt() {
sync=1;
TCNT1H=0;
TCNT1L=0;
}

void main() {
ACSR=0x80;

TCCR1A=0;
TCCR1B=0;
TCNT1H=0;
TCNT1L=0;
TIMSK=0x20;

lcd_init(16);
lcd_clear();

#asm("sei")

TCCR1B=1;

//sync first pulse
sync=0;
while (sync==0);

while (1) {
//sync pulse
sync=0;
while (sync==0);
//read timer capture
tmr_cnt.b.l=ICR1L;
tmr_cnt.b.h=ICR1H;

//calc freq
tmr_cnt.w++;
pulse_freq=1000000/tmr_cnt.w;

//convert bin to BCD
buff[3]=0;
buff[2]=pulse_freq%10+48;
pulse_freq/=10;
buff[1]=pulse_freq%10+48;
pulse_freq/=10;
buff[0]=pulse_freq%10+48;

//preview
lcd_goto(0,0);
lcd_puts(buff);

}

}

Добавлено (08.02.2013, 19:41)
---------------------------------------------

Цитата (igorunm)
свежее почему-то не понимает даже lcd_init()
если evalution версия может работать с ограничениями.
 
igorunmДата: Пятница, 08.02.2013, 19:41 | Сообщение # 13
Рядовой
Группа: Пользователи
Сообщений: 8
Репутация: 0
Статус: Offline
Благодарю Вас, всё скомпилировалось!  Остался один вопросик, как часто происхоит обновление оборотов? И я буду снимать сигнал с катушки зажигания, их 4, тоесть при 8000 об.мин частота на входе будет 66.6 Гц, я так понимаю в последнюю формулу мне надо внести изменения...
Теперь еще и эмуляция в протеусе не запускается... 
пишет инвалид опкод


Сообщение отредактировал igorunm - Пятница, 08.02.2013, 19:56
 
HiSERДата: Пятница, 08.02.2013, 19:57 | Сообщение # 14
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
Обновление зависит он частоты импульсов.
TCCR1B=1; надо изменить на TCCR1B=2;

формула:
pulse_freq=125000/tmr_cnt.w;

800-8000rpm в pulse_freq 6-66

можно сделать точность до десятых
тип pulse_freq изменить на word
Формула:
pulse_freq=12500/tmr_cnt.w;

800-8000rpm в pulse_freq 66-666
 
igorunmДата: Пятница, 08.02.2013, 20:01 | Сообщение # 15
Рядовой
Группа: Пользователи
Сообщений: 8
Репутация: 0
Статус: Offline
Разобрался, спасибо!

Сообщение отредактировал igorunm - Пятница, 08.02.2013, 20:08
 
Форум » Микроконтроллеры » Вопросы по МК » Помогите с тахометром на atmega! (Прошивка)
  • Страница 1 из 1
  • 1
Поиск:

Хостинг от uCoz