Всем привет.
Уже несколько недель потею над данной задачей и
Имеется двигатель, от завода установлен датчик с ранним положением примерно 40 градусов т.е искра происходит раньше чем поршень дойдет до ВМТ.
Задача на холостых оборотах 600-800 сделать задержку скажем на 4мс(выставлять вручную) и в дальнейшем в зависимости от оборотов эта задержка должна уменьшаться т.е к примеру на 6000 оборотов задержка будет равна 0.
Датчик используется индукционный на входе мк стоит сопротивление диод и стабилитрон, т.е на выходе датчика происходит один импульс. Следовательно что бы измерить оборот двигателя нужно ждать 2 импульса датчика, поэтому мне нужно изначально сделать задержку на определенное время а в дальнейшем ее уменьшать.
обороты двигателя. -- минимальные от 600-800 оборотов, максимальные от 6000-10000 оборотов
период - время одного оборота. От 1/600 до 1/10000. Опять же в 16,66 раз разница.
максимальный угол ОЗ 40 градусов, значит рабочий диапазон = 40/360 = 1/9 или примерно 40% от времени полного оборота.
Пишу в CVAVR, использую тини2313, вход датчика PORTD.2, выход импульса PORTB.4.
с таймерами практически не работал, читаю книгу Белова микроконтроллеры АВР, но практики практически нет.
не совсем понимаю как работают прерывания т.е по переполнению и сравнению счетчика но как это происходит на практике (interrupt), также не могу понять как правильно выбрать делитель для моей задачи и как правильно сделать начальную задержку
8-ми битный таймер использовать для выходного импульса а 16-ти битный для подсчета оборотов двигателя.
flash char tablica[104]= {100.....10000}
в tablica[i] находятся значения задержек от 100 оборотов до 10000
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
TCCR1B=0x00; //останавливаем счётчик 1Мгц
TCNT1L=TCNT1H=0xff; //заносим макс. значение
};
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
PORTB.4=1; //включаем КЗ
//TCCR1B=0x00;
//PORTB.4=0;
#asm("nop")
};
interrupt [TIM1_COMPB] void timer1_compb_isr(void)
{
TCCR1B=0x00; //останавливаем счётчик 1Мгц
PORTB.4=0; //выключаем КЗ
//PORTB.4=1;
};
void main(void)
{
DDRA=DDRB=DDRD=0xff;
DDRD.2=0; //вход под датчик
PORTB.2=0;
OCR1AL=OCR1AH=0xff;
OCR1BL=OCR1BH=0xff;
TIMSK=0xE0;
OCR0A=0xff;
OCR0B=0xff;
TIMSK=0xE0;
PORTB.4=0;
while(1)
{
while(PIND.2==0); //делаем один опрос датчика
//#asm("nop")
#asm("cli")
PORTB.4=0; //выключаем КЗ
PORTB.3=1; //вкл. светодиод
TCNT0=0x00; //сбрасываем счётчик
TCCR0A=0x02;
//запускаем счётчик 1Мгц для 0-го 8-ми битного таймера делитель 8
TCNT1L=TCNT1H=0x00; //сбрасываем счётчик
TCCR1B=0x02; //
запускаем счётчик 1Мгц для 0-го 16-ти битного таймера делитель 8, наверное мало как это правильно рассчитать
// delay_us(500); //убираем дребезг
PORTB.3=0;
PIND.2=0;
#asm("sei")
while(PIND.2==0); ////делаем второй опрос датчика и измеряем скорость вращения
TCCR1B=0x00; //останавливаем счётчик 1Мгц
counter_rpm=(TCNT1L|((int)TCNT1H‹‹8 )); //частота вращения
//Таким образом частота вращения вала двигателя будет равна
// F=(1/N)*60*1000000 оборотов в минуту.
i=(1/counter_rpm)*60*1000000;
bufer=tablica[i];
OCR1BH=(char)(bufer››8 ); //заносим задержку
OCR1BL=(char)bufer; //в счётчик
bufer=bufer+1000; //длительность импульса 1мс
OCR1AH=(char)(bufer››8 );
OCR1AL=(char)bufer;
TIFR=0xff; //сбрасываем флаги
//TCNT1L=TCNT1H=0x00; //сбрасываем счётчик
//TCCR1B=0x02; //запускаем счётчик 1Мгц
PIND.2=0;
#asm("sei")
//
};
};
Возможно есть какие то недочеты с моей стороны, не судите строго.
Всем заранее спасибо