Помогите, пожалуйста, начинающему чайнику. Задача - сделать измеритель/индикатор скорости вращения двигателя постоянного тока (до 12 тысяч оборотов в минуту).
Для начала написал программу, которая анализирует наличие сигнала на ножке захвата ICP1 (PD4 контроллера ATMega 64L) и при его поступлении выводит на вывод PE2 импульс, который можно наблюдать на осциллографе симулятора VMLAB (это для изучения и отладки), инкрементирует текущее (произвольное) число и выводит это число на LCD cимулятора.
Что же получилось? После запуска программы около 2 секунд инициируется LCD (это нормально), на его экран выводится число 25. Затем в симуляторе подаётся импульс на PD4. По идее подпрограмма прерывания по захвату должна выработать импульс "отрицательной" полярности длительностью 5 мс, инкрементировать число 25 и вывести на экран LCD число 26. Однако происходит следующее:
после первой подачи импульса захвата на выводе PE2 генерируется импульс с задержкой около 2 сек, число 26 тоже появляется с такой же задержкой;
начиная со второго импульса захвата число 26 уже не инкрементируется, а выходные импульсы на PE2 продолжают генерироваться с такой же задержкой.
Вопросы: откуда такая задержка при подаче импульсов захвата? Почему число инкрементируется только один раз?
#include <mega64.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x1B ;PORTA
#endasm
#include <lcd.h>
#include<stdio.h>
#include<delay.h>
// LCD display buffer
char lcd_buffer[33];
unsigned int x = 0x00;
void __vivod_LCD(void) { //Функция вывода на ЖКИ
sprintf(lcd_buffer,"%i",x); //Запись в буфер ЖКИ
lcd_clear(); //Очистка экрана ЖКИ
lcd_puts(lcd_buffer); //Вывод на ЖКИ
}
// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
PORTE.2=0;
delay_ms(5);
PORTE.2=1;
x++;
__vivod_LCD ();
}
void main(void)
{
// Input/Output Ports initialization
PORTA=0x00;
DDRA=0x00;
PORTD=0xFF;
DDRD=0x00;
PORTE=0xFF;
DDRE=0x0FF;
// Timer/Counter 1 initialization
// Clock source: T1 pin Falling Edge
TCCR1A=0x00;
TCCR1B=0x81;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x24;
ETIMSK=0x00;
// LCD module initialization
lcd_init(16);
x=25;
__vivod_LCD ();
#asm("sei")
while (1)
{
}
}