AFON // радиотехник affonya@mail.ru
← Проекты на PIC

Проект 32. Измеритель длительности импульса

Модуль захвата фиксирует моменты фронта и спада по таймеру, а разность даёт длительность импульса с точностью до микросекунды. Так измеряют период, скважность и время задержки.

Задача

Измерить длительность входного импульса.

Микроконтроллер: PIC16F877A, кварц 4 МГц. Среда: MPLAB X + MPASM (или любой совместимый ассемблер). Как настроить среду и прошить контроллер — в статье программирование PIC.

Что понадобится

  • PIC16F877A
  • кварц 4 МГц + 2×22 пФ
  • источник измеряемых импульсов
  • 8 светодиодов для индикации

Схема подключения

ВыводПодключение
RC2 / CCP1вход измеряемого сигнала
RB0…RB7индикация результата
MCLRчерез 10 кОм на +5 В

Алгоритм

  1. Запустить TMR1 от внутреннего такта.
  2. Настроить CCP1 на захват по нарастающему фронту и дождаться события.
  3. Обнулить таймер и переключить захват на спад.
  4. После спада прочитать CCPR1H:CCPR1L — это длительность в тактах таймера.

Листинг на ассемблере

Код проверен ассемблером и собирается без ошибок. Скачать: p32.asm · p32.hex (готовая прошивка).

;=======================================================
; Проект 32. Измеритель длительности импульса (TMR1 + захват CCP)
; PIC16F877A, 4 МГц. Вход сигнала — RC2/CCP1
; Результат (старший байт длительности) — на RB0..RB7
;=======================================================
        LIST    p=16F877A
        #include <p16f877a.inc>
        __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF

        cblock  0x20
        t1l, t1h, res
        endc

        ORG     0x000
        goto    Start

Start
        bsf     STATUS,RP0
        clrf    TRISB           ; индикация
        bsf     TRISC,2         ; RC2/CCP1 — вход
        bcf     STATUS,RP0
        movlw   b'00000001'     ; TMR1 вкл, предделитель 1:1, внутр. такт
        movwf   T1CON

Main
        movlw   b'00000101'     ; захват по нарастающему фронту
        movwf   CCP1CON
        bcf     PIR1,CCP1IF
        clrf    TMR1L
        clrf    TMR1H
W1      btfss   PIR1,CCP1IF     ; ждём начала импульса
        goto    W1
        clrf    TMR1L           ; обнуляем счётчик
        clrf    TMR1H

        movlw   b'00000100'     ; захват по спаду
        movwf   CCP1CON
        bcf     PIR1,CCP1IF
W2      btfss   PIR1,CCP1IF     ; ждём конца импульса
        goto    W2

        movf    CCPR1L,w        ; младший байт результата
        movwf   t1l
        movf    CCPR1H,w        ; старший байт
        movwf   t1h
        movf    t1h,w           ; выводим старший байт
        movwf   PORTB
        goto    Main

        END

Пояснения

  • При кварце 4 МГц и предделителе 1:1 один отсчёт TMR1 равен 1 мкс, поэтому результат читается прямо в микросекундах.
  • Захват выполняется аппаратно в момент фронта, поэтому точность не зависит от того, насколько быстро программа успела отреагировать.
  • Для длинных импульсов включают предделитель TMR1 или считают переполнения таймера в прерывании.

Что дальше

Разобравшись с этим проектом, переходите к следующему в разделе проекты на PIC. Справочник по архитектуре и периферии контроллеров — на странице микроконтроллеры PIC.