Контроль предельной скорости вращения двиrателя Таймер TMRl работает в режиме захвата на входе. На вход ССРl (например, вывод 2 порта С) подается сиrнал от тахометра, измеряющеrо скорость вращения двиrателя. Если период следования импульсов становится меньше 1 мс, то это [o ворит О слишком высокой скорости вращения двиrателя, а включается светодиод, подключенный к выводу О порта О. При измерении периода следования импульсов от тахометра следует учиты вать возможность возникновения переполнения счетчика, поэтому в проrрамме реализуем подсчет переполнений, а фактическое количество тактовых импульсов таймера будем вычислять по формуле: N == N ovel.tlo\VS . Ох 1 0000 N stш1 + N епd, )'де Noverflo\vs количество переполнений; Nstart количество тактовых импульсов, принятых на начало периода; N el1d количество тактовых импульсов, принятых на конец периода. При рабочей частоте микроконтроллера] О мrц и коэффициенте деления ] за одну секунду счетчик подсчитывает 10000 импульсов, поэтому будем сопостав лять полученную величину периода именно с этим значением. Реализация этоrо алrоритма представлена в листинrе 5.7. Файлы для этоrо при мера SpeedCtr. с и SpeedCtr. pj t находятся на прилаrаемом к кни re компакт диске в папке Projects\PIC\SpeedCtr. #include <16F877.h> #use delay(clock==10000000) #fuses HS, NOWDT int N overflows; unsigned long int N start, N end; long int N; #int timerl //Обработка прерывания при переполнении TMR1 timer1_isr () { ++N overflows; //Увеличиваем счетчик переполнений } #int ССРl //Обработка прерывания при захвате на входе ССР1_isr () { N_end = CCP_1; //Количество тактовых импульсов, подсчитанных //с момента поступления предыдущеrо импульса на входе ССРl //Вычисляем период между двумя последовательнь и импульсами ССР1 N == (N_overflows * Ох10000)-N_start + N_end; if (N < 10000) //Если период меньше 10000 импульсов, то... output_low(PIN_DO); //заrорается сиrнальная лаМПОчка else output_high(PIN_DO); //Иначе лампочка racHeT N_start == N_end; //3апоминаем позицию текущеrо замера N_overflows == о; //Сбрасываем счетчик переполнений } void main () { setup_ccpl(CCP_CAPTURE_RE); //3ахват по нарастающему фронту //Инициализируем TMR1: тактируется от BHYTpeHHero осциллятора, //без предварительноrо деления частоты setup_timer_1(T1_INTERNAL | T1_DIV_BY 1); //Разрешаем прерывание при переполнении TMRl enable_interrupts(INT_TIМER1) ; //Разрешаем прерывание при захвате на входе enable_interrupts(INT_CCP1) ; enable_interrupts(global); //Общее разрешение прерываний while(true); //Бесконечный цикл в ожидании сиrнала на входе ССРl }