Помогите, пожалуйста, начинающему чайнику. Задача - сделать измеритель/индикатор скорости вращения двигателя постоянного тока (до 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) { } }
|