AVR Assembler Source Blog

Ремонт частотных преобразователей AVR Assembler Source Blog: Timer_led_switch

Thursday, October 3, 2013

Timer_led_switch


                              ;Цель: реализовать таймер, отображающий с помощью светодиодов в 8-разрядном двоичном коде время замкнутого состояния контактов кнопки включения с дискретностью 0,5 с, предусмотреть возможность сброса таймера в исходное состояние и индикацию переполнения таймера
                              ;Для управления таймером необходим отсчет времени интервалами по 0,5 с. от момента замыкания кнопки включения (Кн1) до ее размыкания, а также кнопка Кн2-сброс, светодиоды подключены через токоограничительные резисторы к порту B
                              ;Контроль кнопок наиболее просто реализуется с использованием внешних прерываний Int0(PD2) и Int1(PD3). т.к. приоритет сброса выше, подключим Кн2 между PD2 и общим проводом, а Кн1 между PD3 и общим проводом. 
                              ;Светодиод для индикации переполнения таймера подключим к PD1
                              ;При тактовой частоте 8 МГц интервалы 0,5 с. можно получить в канале сравнения А таймера-счетчика 1 с коэффициентом деления тактовой частоты - 1024, кодом канала сравнения А - 3906 ($0f42) и сбросом таймера 1 по сигналу сравнения канала А. Для инициализации этого режима в регистре TCCR1A все биты очищаются, а в регистр TCCR1B записывается константа 0b00001000. Запуск таймера производится установкой трех младших битов TCCR1B, останов их очисткой. Для сброса таймера необходимо очистить биты регистров TCNT1H, TCNT1L.
                              ;Используемые векторы прерываний Int0 ($001), Int1 ($002), Tim1_CompA($006)


.NOLIST                       ;не включать последующие команды в листинг
.INCLUDE "m32def.inc"         ;включить в код файл описаний команд и регистров конкретного контроллера
.LIST                         ;включить последующие команды в листинг
.DEF temp=r16                 ;определить переменную temp как регистр r16
.CSEG                         ;указываем, что далее будем работать с памятью программ FLASH
.ORG $000                     ;установка положения в начальный $000 адрес памяти
 rjmp init                    ;прерывание по reset 
 rjmp restim                  ;прерывание по сбросу таймера (Int0)
 rjmp timon                   ;прерывание по включению таймера (Int1)
.ORG $006                     ;установка положения в $006 адрес памяти
 rjmp half                    ;прерывание для формирования интервала в полсекунды
.ORG $011                     ;установка положения в $011 адрес памяти



init:                         ;инициализация используемых аппаратных средств, назначение портов на вход и выход

       ldi temp, LOW(RAMEND)  ;значение переменной RAMEND указано во включаемом файле .inc, различное значение для каждого контроллера
       out SPL, temp 
       ldi temp, HIGH(RAMEND) 
       out SPH, temp

       ser temp               ;установить регистр temp
       out DDRB, temp         ;установить порт B на вывод
       out PORTD, temp        ;высокий уровень по умолчанию в порт D
       clr temp               ;очистить регистр temp
       out PORTB, temp        ;очистить биты порта B (сброс)
       out DDRD, temp         ;порт D на ввод
       sbi DDRD, PD1          ;установить бит PD1(индикатор переполнения)
       out MCUCR, temp        ;внешние прерывания по низкому уровню
       ldi temp, $08          ;загрузить $08 в temp
       out TCCR1B, temp       ;разрешения сброса таймера 1 по каналу сравнения А
       ldi r18, $42
       ldi r19, $0f
       out OCR1AH, r19
       out OCR1AL, r18        ;запись кода сравнения (3906) канала А
       ldi temp, $10
       out TIMSK, temp        ;разрешение прерывания канала А
       ldi temp, $c0
       out GIMSK, temp        ;разрешение внешних прерываний
       sei                    ;общее разрешение прерываний

main:                         ;бессодержательный бесконечный цикл, может быть заменен любой программой

       nop                    ;пустая инструкция
       rjmp main

restim:

       clr r20                ;очистить регистр r20
       out PORTB, r20         ;очистить биты порта B(сброс)
       cbi PORTD, PD1         ;очистить индикацию переполнения
       out TCNT1H, r20
       out TCNT1L, r20        ;сброс таймера 1

stop: 

       in temp, TCCR1B        ;чтение регистра TCCR1B
       cbr temp, $07          ;очистить 3 младших бита 
       out TCCR1B, temp       ;остановить таймер 1
       reti                   ;завершить прерывание

timon:

       in temp, TCCR1B        ;чтение регистра TCCR1B
       sbr temp, $07          ;установить 3 младших бита
       out TCCR1B, temp       ;запустить таймер 1
       reti                   ;завершить прерывание

half:                         ;формирование интервала 0,5 с при нажатой кнопке и индикация

       sbic PORTD, PD3        ;пропустить следующую инструкцию, если Кн1 нажата
       rjmp stop              ;перейти к остановке таймера, если Кн1 не нажата
       inc r20
       out PORTB, r20         ;инкремент индикатора кода таймера
       breq carry             ;если равно перейти к формированию переполнения
       reti                   ;завершить прерывание

carry:

       sbi PORTD, PD1         ;установить бит индикации переполнения
       rjmp stop              ;перейти к остановке таймера 1

No comments:

Post a Comment