#include <90s4433.h> volatile unsigned int period ; // Переменные. volatile unsigned int azz ; volatile unsigned int pi = 360 ; volatile unsigned int result ; // Timer 1 input capture interrupt service routine // Прерывание от PORTB.1 interrupt [TIM1_CAPT] void timer1_capt_isr(void) { ; azz = ICR1 ; // Перемещаем содержимое регистра захвата в переменную "azz" ICR1 = 0 ; // Очищаем регистр захвата TIMSK= 0b00000000 ; // Запрещаем прерывания } ; // Declare your global variables here void main(void) { ; // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped TCCR0=0x00; TCNT0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1 output: Discon. // Noise Canceler: On // Input Capture on Rising Edge // Timer 1 Overflow Interrupt: On // Input Capture Interrupt: On // Compare Match Interrupt: On TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; OCR1H=0x00; OCR1L=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off GIMSK=0x00; MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; UBRRHI=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; // Global enable interrupts #asm("sei") //____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ //Надо измерить фазу сигнала относительно опорного. Опорный сигнал - на PORTB.0 , ИЗМЕРЯЕМЫЙ на PORTB.1 //(Вызывает прерывание по положительному перепаду на PORTB.1 ) //Смысл - получить величину периода основного сигнала;;; и получить величину задержки перепада в - //измеряемого сигнала относительно перепада в - основного сигнала. Величину перепада разделить на период и //умножить на 360 ===== результат - смещение в градусах относительно основного сигнала! //Поместить результат в переменную "result" // Примечание: PORTB.0 -вход опорного сигнала ( меандр частотой 50-100 гц) // PORTB.1 -вход измеряемого сигнала ( тоже самое только сдвинутое по фазе) // ( порты выбраны наобум, подразумеваеться что PORTB.1 -это вход захвата для таймера1 // вызывающий прерывания.) //____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ while (1) { // Основной цикл................. TCCR1B = 0b10000000 ; TIMSK = 0b00000000 ; ; while ( PINB.0<<1 ) { ; // если на PORTB.0 нулевой уровень - ждать положительного и ничего не делать } ; // измеряем период опорного сигнала ; while ( PINB.0>>0 ) { TCCR1B = TCCR1B | 0x85 ; // запускаем таймер если пошёл положительный полупериод 1/1024 и сидим тут } while ( PINB.0<<1 ) { ; // Отрицательный ? Ждать и ничего не делать ( чтоб не выскочить из цикла при отрицательном полупериоде) } TCCR1B = TCCR1B & 0x80 ; // останавливаем таймер если начался следующий положительный полупериод period = TCNT1 ; // запишем в переменную " период " значение счётчика TCNT1 = 0 ; // обнулим счётчик // Очевидно здесь на этот момент на опорном входе относительно которого измеряем будет присутствовать положительный уровень; -поэтому чтобы не усложнять программу воспользуемся изменением по отрицательному перепаду и основного сигнала и измеряемого......... while ( PINB.0>>0) { ; // если на PORTB.0 положительный уровеь - ждать появления отрицательного и ничего не делать } ; // Фиксируем начало отрицательного перепада измеряемого сигнала относительно начала отрицательного перепада основного сигнала. if (PINB.0<<1 ) ; // если уровень стал 0 ( нулевй уровень на входе измерения периода) { TCCR1B = TCCR1B | 0b10000101 ; // запустить таймер1 с коэф деления 1\1024 и разрешитть внешние прерывания , условиe генераци внешнего прерывания - по спадающему фронту TIMSK = TIMSK | 0b00100000 ; // должно последовать прерывание от вывода PB.1 } ; azz /= period ; //расчитаем фазу. поделим период на время прошедьшшее с начала периода по спадающему перепаду до возникновения отрицатльного перепада измеряемого сигнала и умножим на 360 pi *= azz ; result = pi ; // Это результат TCCR1B = 0b10000000 ; // Остановим таймер TCNT1 = 0 ; // Обнулим таймер } ; } ;