Инструменты пользователя

Инструменты сайта


mk8:project_tmr

Работа с таймером в МК 1886ВЕ61У

В данной статье рассматривается работа с блоком таймера на примере МК 1886ВЕ61У в составе отладочной платы.

Общие сведения

Таймеры предназначены для формирования временных интервалов, позволяя микропроцессорной системе работать в режиме реального времени. Таймеры представляют собой цифровые счётчики, которые подсчитывают импульсы либо от высокостабильного генератора частоты, либо от внешнего источника сигнала, в этом случае таймер называют счетчиком внешних событий. В микроконтроллере 1886ВЕ61У есть три таймера. Таймер 0, 1,2. Все 3 три таймера имеют флаги запроса прерываний по переполнению, но с разными приоритетами. Таймеры 1 и 2 имеют самый низкий приоритет и маскируются битом периферийных прерываний PEIF. Эти оба таймера помимо того, что представляют собой 16 разрядные счётчики, имеют функции реализации ШИМ (широтно-импульсной модуляции) и регистрации событий (функция захвата). Мы же будем работать с таймером 0, который не имеет реализации функции ШИМ/Захвата, однако вектор запроса данного прерывания имеет гораздо больший приоритет. Он не маскируется битом разрешения периферийных прерываний и имеет отдельный флаг запроса по переполнению таймера 0, в регистре состояния прерываний INSTA.

Таймер 0

Таймер 0 также (как и Таймер 1 и 2) состоит из 16-разрядного таймер/счетчика и представлен двумя регистрами TMR0L –младший байт TMR0H-старший. Управление блоком осуществляется с помощью регистра T0STA. Здесь важным аспектом является выбор предделитедя для таймера, который задается битами TOPS[3:0]. Чтобы сделать секундомер, необходимо чтобы таймер переполнялся (достигал максимального значения FFFFh) каждую секунду. Сначала обратимся к схеме таймера, по который видно, что блок можно затактировать двумя способами в зависимости от бита TOCS. Если бит T0CS установлен в «1», инкрементирование счетчика «таймера 0» происходит от тактовых импульсов внутреннего генератора, который является источником синхронизации для всего микроконтроллера. Если бит T0CS сброшен в «0», то инкрементирование счетчика происходит от тактовых импульсов с входа PA1/T0CLK (внешний источник тактовых импульсов). Мы будем использовать внутренний тактовый генератор, но здесь надо обязательно следует обратить внимание на то, что частота, приходящая с него, инкрементирующая таймер равна Fc/4.

Наш микроконтроллер тактируется внешним кварцевым резонатором на 16 МГц, который установлен на плате. Следовательно на таймер приходит частота в 4 МГц. Значение предделителя зададим равное 64. Получается таймер работает на частоте 62,5 кГц. Период таймера равен 1/62500=0,000016 с. Поскольку максимальное значение таймера равно 65536 (FFFFh), переполнение его будет происходить приблизительно через одну секунду: 65536*000016 =1,05 с. Как раз то, что нам и нужно.

Секундомер на ассемблере

Пример демонстрирует работу таймера с использованием прерываний по переполнению. Каждый раз, когда таймер достигает максимального значения (раз в 1 секунду) происходит увеличение числа, отображаемого на семисегментном индикаторе до значения 99. Запуск секундомера выполняется с помощью кнопки.

INCLUDE <1886VE6M.INC>
; объявляем требуемые регистры
DATAREG EQU 0x2C
TIME EQU 0x1A
TIME2 EQU 0x1B
TIME3 EQU 0x1C
;********************************************************
ORG 0x0 ; задаем начальный адрес расположения программы
BSF GLINTD 
MOVLB 6
CLRF ADCON0
SETF ADCON1
MOVLB 1
CLRF PORTC
CLRF PORTD
SETF DDRC
SETF DDRD
GOTO POLL ; переходим к области опроса прерываний.
;********************************************************
; область обработки прерываний
ORG 0x10
INTERRUPT:
          MOVLW 0x0A ; 
          CPFSEQ TIME
         INCF TIME,1
         CPFSLT TIME
         CALL SOS
         BCF T0IF
         CLRF TMR0L ; 
         CLRF TMR0H ; 
         RETFIE ; 
;********************************************************
; область опроса прерываний
ORG 0x30
POLL:
     MOVLW 0x0 ; задаем начальное значение регистра,
     ; значение которого будет на табло.
     MOVWF TIME
      MOVWF TIME2
     CLRF TMR0L ; задаем младший регистр таймера.
     CLRF TMR0H ; задаем старший регистр таймера.
     BSF T0CS ; выбираем внутреннюю частоту генерации
     ; циклов
     BSF T0IE ; разрешаем запрос прерываний.
     CALL BTN
;********************************************************
; проверка на необходимость прерывания
DIVIDER:
        BCF T0PS0 ; устанавливаем предделитель частоты 1:64.
        BSF T0PS1
        BSF T0PS2
        BCF T0PS3
        BTFSC T0IF ; проверяем бит запроса прерываний.
BCF GLINTD
CALL START
;********************************************************
; область индикации
ORG 0x70
START:
      ;MOVLB 1
      SETF PORTD ; FF в регистр порта D
      CLRF PORTC ; очистка порта С
      MOVLW 0x0 
      MOVWF DDRD
      MOVWF DDRC
      MOVFP TIME,WREG
      CALL SYMGEN
      MOVWF DATAREG
      CALL TRANSFER
      MOVLW 0xDF
      MOVWF PORTD
      
      MOVFP TIME2,WREG
      CALL SYMGEN
      MOVWF DATAREG
      CALL TRANSFER
      MOVLW 0xEF
      MOVWF PORTD
GOTO DIVIDER
;********************************************************
; область опроса кнопки
ORG 0x90
BTN:
BCF T0IF
BCF PORTD,0 ; 
BTFSS PORTC,7 ; 
CALL DIVIDER ; 
; 
SETF PORTD ; 
MOVLW 0x0
MOVWF DDRD
CLRF PORTC ; 
MOVWF DDRC
CALL SYMGEN
MOVWF DATAREG
CALL TRANSFER
MOVLW 0xDF
MOVWF PORTD ;
MOVLW 0x00
MOVWF DATAREG
CALL TRANSFER

GOTO BTN

SOS:
MOVLW 0x00
MOVWF TIME
INCF TIME2,1
MOVLW 0x0A
CPFSLT TIME2
GOTO POLL
RETURN
;********************************************************
;передача данных в сдвиговый регистр
TRANSFER:
         BCF DDRC,7
         SETF PORTD,F
         BSF PORTC,7
         BTFSS DATAREG,7
         BCF PORTC,7
         BSF PORTC,6
         BCF PORTC,6
         BSF PORTC,7
         BTFSS DATAREG,6
         BCF PORTC,7
         BSF PORTC,6
         BCF PORTC,6
         BSF PORTC,7
         BTFSS DATAREG,5
         BCF PORTC,7
         BSF PORTC,6
         BCF PORTC,6
         BSF PORTC,7
         BTFSS DATAREG,4
         BCF PORTC,7
         BSF PORTC,6
         BCF PORTC,6
         BSF PORTC,7
         BTFSS DATAREG,3
         BCF PORTC,7
         BSF PORTC,6
         BCF PORTC,6
         BSF PORTC,7
         BTFSS DATAREG,2
         BCF PORTC,7
         BSF PORTC,6
         BCF PORTC,6
         BSF PORTC,7
         BTFSS DATAREG,1
         BCF PORTC,7
         BSF PORTC,6
         BCF PORTC,6
         BSF PORTC,7
         BTFSS DATAREG,0
         BCF PORTC,7
         BSF PORTC,6
         BCF PORTC,6
         BSF DDRC,7
RETURN
;********************************************************
; область преобразования значений для индикации
SYMGEN:
       ADDWF PCL,1
       RETLW 0x3F ; "0"
       RETLW 0x06 ; "1"
       RETLW 0x5B ; "2"
       RETLW 0x4F ; "3"
       RETLW 0x66 ; "4"
       RETLW 0x6D ; "5"
       RETLW 0x7D ; "6"
       RETLW 0x07 ; "7"
       RETLW 0x7F ; "8"
       RETLW 0x6F ; "9"
       RETURN
;********************************************************
END
mk8/project_tmr.txt · Последние изменения: 2018/09/21 16:54 — katya