Цитата(AHTOXA @ Mar 30 2011, 16:40)

Для измерения длительности сигналов есть специально предназначенные модули захвата (input capture).
Нашёл пример, перевел его с AVRStudio на mikroc. Работать отказывается. Весь вечер просидел с ним.
Думаю, может ошибся когда переводил, взял оригинальный код и собрал в AVRStudio.
Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
// Input: Square wave on ICP PIN
// This program determines the pulse width of a square wave and represents that pulse width
//in a certain form in port D
double overflow_counter, rising_edge, falling_edge, pulse_width;
double TOP = 65535;
//This interrupt service routine calculates the pulse width of a square wave on the ICP pin
//and displays that in a certain form on PORT D
ISR(TIMER1_CAPT_vect){
if (PORTA == 0xAA) PORTA = 0x55;
else PORTA == 0xAA;
// If ICP pin is set, there was a rising edge else if its low there must have been a falling edge /
if (bit_is_set(PINB,1)){
rising_edge = ICR1;
TCCR1B &= ~(1<<ICES1); //Capture now on falling edge
overflow_counter = 0;
}
else{
falling_edge = ICR1;
TCCR1B |= (1<<ICES1);//Capture now on rising edge
pulse_width =falling_edge - rising_edge + TOP*overflow_counter;
//Test to see if correct pulse width being calculated
//if pulse width is greater than 35 than PD2 goes high otherwise PD3 IS HIGH
if (pulse_width>35){
PORTD |= (1<<PD2);
PORTD &= ~(1<<PD3);
}
else{
PORTD |= (1<<PD3);
PORTD &= ~(1<<PD2);
}
}
}
ISR(TIMER1_OVF_vect){
overflow_counter++; //increment counter when overflow occurs
}
int main(void){
DDRB = 0;// ICP pin as input which is pin 0 on port B/
DDRD = 0XFF; // ALL PINS on port D are set as output.
DDRA = 0xFF;
PORTA = 0xAA;
sei();//enable global interrupt
//setting up Timer control register 1
//TOP VALUE IS 0XFFFF; (NORMAL MODE)
TCCR1A = 0;
TCCR1B = 0;
//SETS PRESCALER ON 1
TCCR1B |= (1<<CS10);
TCCR1B &= ~(1<<CS11) & ~(1<<CS12);
// Enable Input noise canceller and capture time on rising edge
TCCR1B |= (1<<ICES1) | (1<<ICNC1);
TIMSK = 0;
TIMSK |= (1<<TICIE1); //Enable Input Capture Interrupt
TIMSK |= (1<<TOIE1); //Enable timer overflow interrupt
while(1){}
}
Проект настроен на 8 МГц, Атмега16. В оригинале примера сигнал читался с PB0, хотя для Timer1 должен быть вход PB1. PB0 это для Timer0. Пробовал и так и так. В конечном счёте тупо взял и запараллелил оба входа, чтобы не гадать.
Счётчик работает, прерывание TIMER1_OVF_vect срабатывает исправно, а прерывание TIMER1_CAPT_vect срабатывает только один раз, когда запускается main. И больше не вызывается. Независимо от состояния порта В.
В чём прикол - не могу понять