Проблема распознавания уровня сигнала на входе PCINT0. Надо определить время (по таймеру1) нахождения сигнала на высоком уровне, и выводить значения по USART через определенное время (таймер2). Почему при прерывании число задних и передних франтов сильно отличается? Это приводит к неверным результатам. Микроконтроллер ATmega644P Код программы:
#include <avr/io.h> #include <avr/interrupt.h>
#define check_num_pin0 (1<<PINA0) #define check_pinA PINA
unsigned long counterA; unsigned long T1_0,T2_0;
void USART_Init() // Initializing USART { UBRR0 = 0x33; /* Enable receiver and transmitter */ UCSR0B = (1<<RXEN0)|(1<<TXEN0); /* Set frame format: 8data, 1stop bit */ UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); } void USART_Transmit( char data ) { /* Wait for empty transmit buffer */ while ( !(UCSR0A & (1<<UDRE0)) ); /* Put data into buffer, sends the data */ UDR0 = data; } void TIMER2_Init() // Initializing TIMER2 { ASSR=(1<<AS2); OCR2A=0x20; TCCR2B=(1<<CS22)|(1<<CS21)|(1<<CS20); TIMSK2=(1<<OCIE2A); } void TIMER1_Init() { TCNT1=0; TCCR1B=(1<<CS12); } void Interrupt_Extern() { PCICR=(1<<PCIE0); PCMSK0=(1<<PCINT0); } int main() { PORTA=(1<<PORTA0); counterA=0; T1_0=0; T2_0=0; USART_Init(); TIMER2_Init(); Interrupt_Extern();
sei(); while(1);
}
ISR(TIMER2_COMPA_vect) { cli();
if (check_num_pin0 & check_pinA) { T2_0=TCNT1; counterA+=(T2_0-T1_0); }
TCCR2B=(0<<CS22)|(0<<CS21)|(0<<CS20); // выключение таймера2 TCCR1B=0; // выключение таймера1 TCNT1=0; USART_Transmit(counterA>>16); // вывод данных USART_Transmit(counterA>>8); USART_Transmit(counterA);
counterA=0; T1_0=0; T2_0=0; TCNT2=0; TCCR2B=(1<<CS22)|(1<<CS21)|(1<<CS20); // Включение таймера2 TIMER1_Init(); // Включение таймера1 PCIFR=0; // Обнуление флагов прерывания PCINT sei();
}
ISR(PCINT0_vect) { cli(); if (check_num_pin0 & check_pinA) // Высокий уровень { T1_0=TCNT1; } else // Низкий уровень { T2_0=TCNT1; counterA+=(T2_0-T1_0); } PCIFR=0; sei(); }
|