Помогите с тахометром на atmega!
|
|
igorunm | Дата: Пятница, 08.02.2013, 16:07 | Сообщение # 1 |
Рядовой
Группа: Пользователи
Сообщений: 8
Статус: 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
Статус: Offline
| В этом примере считается количество тиков в секунду. Тебе же надо считать время между импульсами. Используй пин ICP и 1й таймер.
|
|
| |
igorunm | Дата: Пятница, 08.02.2013, 17:34 | Сообщение # 3 |
Рядовой
Группа: Пользователи
Сообщений: 8
Статус: Offline
| а подскажите, как это будет в коде выглядеть? и как выставить интервал времени измерения
|
|
| |
HiSER | Дата: Пятница, 08.02.2013, 18:15 | Сообщение # 4 |
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Статус: Offline
| А почитать даташит, не? Вот пример: http://my-avr.at.ua/load/icp/1-1-0-40
|
|
| |
igorunm | Дата: Пятница, 08.02.2013, 18:37 | Сообщение # 5 |
Рядовой
Группа: Пользователи
Сообщений: 8
Статус: 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
Статус: Offline
| это определение типа, должно быть в начале
|
|
| |
igorunm | Дата: Пятница, 08.02.2013, 19:09 | Сообщение # 7 |
Рядовой
Группа: Пользователи
Сообщений: 8
Статус: Offline
| Не могу найти даже описание что такое "typedef union " и как с ним работать. Прошу помочь, как Вы уже поняли, знания не глубоки, максимум наверное смогу дисплей подключить, вывести на него данные...
|
|
| |
HiSER | Дата: Пятница, 08.02.2013, 19:17 | Сообщение # 8 |
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Статус: Offline
| Покажи код и скажи версию компилятора.
|
|
| |
igorunm | Дата: Пятница, 08.02.2013, 19:28 | Сообщение # 9 |
Рядовой
Группа: Пользователи
Сообщений: 8
Статус: 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
Статус: Offline
| Компилятор свежее скачай, версии 2.xx.x
|
|
| |
igorunm | Дата: Пятница, 08.02.2013, 19:33 | Сообщение # 11 |
Рядовой
Группа: Пользователи
Сообщений: 8
Статус: Offline
| свежее почему-то не понимает даже lcd_init()
|
|
| |
HiSER | Дата: Пятница, 08.02.2013, 19:41 | Сообщение # 12 |
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Статус: 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
Статус: Offline
| Благодарю Вас, всё скомпилировалось! Остался один вопросик, как часто происхоит обновление оборотов? И я буду снимать сигнал с катушки зажигания, их 4, тоесть при 8000 об.мин частота на входе будет 66.6 Гц, я так понимаю в последнюю формулу мне надо внести изменения... Теперь еще и эмуляция в протеусе не запускается... пишет инвалид опкод
Сообщение отредактировал igorunm - Пятница, 08.02.2013, 19:56 |
|
| |
HiSER | Дата: Пятница, 08.02.2013, 19:57 | Сообщение # 14 |
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Статус: 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
Статус: Offline
| Разобрался, спасибо!
Сообщение отредактировал igorunm - Пятница, 08.02.2013, 20:08 |
|
| |