[an error occurred while processing this directive]
Я когда-то (на асме всё) формировал из одного 16р таймера 8 программных 16р таймеров (+)
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено уни 27 апреля 2006 г. 14:41
В ответ на: OFF: Кто-нибудь может на пальцах объяснить, как в AVR при наличии ограниченного числа таймеров, формировать множество различных временных интервалов? Может есть какая простая методика? отправлено =NIK= 27 апреля 2006 г. 12:55

Это было для AT90S8535. У меня в нижних регистрах заводился специальный регистр флагов для таймеров. Сами счётчики я хранил в SRAM, выделяя для этого 8*2 байта (16разр) = 16 байт ОЗУ. Инициализирую счётчик в ОЗУ, выставляю флаг. В прерывании от таймера инкрементировал, проверял и снимал по переполнению или обнулению :) уже не помню. Вылизывал ISR специально, чтобы использовать по минимуму регистров. Может пригодится кому. Это main.asm файл, смотеть ниже инициализацию и сам обработчик. Работало :)

; CP-1251 (WIN)
; Таблица векторов прерываний
.cseg
.org 0000
rjmp Reset ; Reset Handler
reti ; IRQ0 Handler
reti ; IRQ1 Handler
reti ; Timer2 Compare Handler
reti ; Timer2 Overflow Handler
reti ; Timer1 Capture Handler
reti ; Timer1 CompareA Handler
reti ; Timer1 CompareB Handler
rjmp TIM1_OVF ; Timer1 Overflow Handler
mTaskMngr:
rjmp TIM0_OVF ; Timer0 Overflow Handler
reti ; SPI Transfer Complete Handler
reti ; UART RX Complete Handler
reti ; UDR Empty Handler
reti ; UART TX Complete Handler
reti ; ADC Conversion Complete Interrupt Handler
reti ; EEPROM Ready Handler
reti ; Analog Comparator Handler

.include "inc\8535def.inc"
.include "inc\def.inc"
.include "task0.asm"
.include "task1.asm"
.include "task2.asm"
.include "task3.asm"
.include "task4.asm"
.include "task5.asm"
.include "task6.asm"
.include "task7.asm"

; Действия при перезагрузке
Reset:
ldi _tmp, Low(RAMEND)
mov RAMEndLo, _tmp
out SPL, _tmp
ldi _tmp, High(RAMEND)
mov RAMEndHi, _tmp
out SPH, _tmp
; Очистка области памяти SRAM
rcall ClearMemory
; Начальные установки регистров направления и портов
rcall InitExtInts
rcall InitPorts
rcall InitTimers
; Инициализация задач
rcall InitTask0
rcall InitTask1
rcall InitTask2
rcall InitTask3
rcall InitTask4
rcall InitTask5
rcall InitTask6
rcall InitTask7

clr ZeroReg
clr tSPhi
clr tSPlo
clr DFlags
clr MsgFlags
clr jTskCnt

; Установка флагов по умолчанию
; SetFlag MsgFlags, KeyPressBit
; SetFlag MsgFlags, RedrawBit
; SetFlag MsgFlags, RTCBit
; SetFlag MsgFlags, LoadBit
; SetFlag MsgFlags, ClockEnBit
; ClrFlag MsgFlags, AutoEnBit
; SetFlag MsgFlags, Kl1StateBit ; по умолчанию закрыты
; SetFlag MsgFlags, Kl2StateBit
; Переход на нулевую задачу
clr _tmp
out SPH, _tmp
ldi _tmp, 0x8F
out SPL, _tmp
; Начальное значение PC для нулевой задачи
ldi _tmp, Low(Task0)
push _tmp
ldi _tmp, High(Task0)
push _tmp

; Обработчик прерывания от нулевого таймера
TIM0_OVF:
; в стеке находятся два байта PC
; необходимо ещё сохранить значение статус регистра
; и регистров общего назначения
; значение счётчика текущей задачи хранится в jTskCnt
in stmp, SReg
push stmp
push r16
push r17
push r18
push r19
push r20
push r21
push r22
push r23
push r24
push r25
push r26
push r27
push r28
push r29
push r30
push r31
; сохраняем указатель стека текущей задачи
mov TaskCnt, jTskCnt
ldi XL, 0x60
clr XH
andi TaskCnt, 0x07
mov CntxOfst, TaskCnt
clc
rol CntxOfst
add XL, CntxOfst
adc XH, ZeroReg
in _tmp, SPH
st X+, _tmp
in _tmp, SPL
st X, _tmp
inc TaskCnt
; теперь переключаемся на стек следующей задачи
ldi XL, 0x60
clr XH
andi TaskCnt, 0x07
mov CntxOfst, TaskCnt
clc
rol CntxOfst
add XL, CntxOfst
adc XH, ZeroReg
ld _tmp, X+
out SPH, _tmp
ld _tmp, X
out SPL, _tmp
mov jTskCnt, TaskCnt
; восстанавливаем все регистры
pop r31
pop r30
pop r29
pop r28
pop r27
pop r26
pop r25
pop r24
pop r23
pop r22
pop r21
pop r20
pop r19
pop r18
pop r17
pop r16
; начальное значение счётчика нулевого таймера
out TCNT0, ZeroReg
pop stmp
out SReg, stmp
reti; TIM0_OVF

; Очистка всей SRAM
ClearMemory:
clr XH
ldi XL, 0x60
; Первые 256 байт
ldi r16, 255
clr r17
mLoop0:
st X+, r17
dec r16
brne mLoop0
; Вторые 256 байт
ldi r16, 255
mLoop1:
st X+, r17
dec r16
brne mLoop1
ret; ClearMemory

InitExtInts:
; Настройка внешних прерываний
; ...
ret; InitExtInts

InitPorts:
; Настройка портов
; ...
ret; InitPorts

InitTimers:
ldi _tmp, ((1<<CS02)|(1<<CS00)) ; установка делителя таймера
out TCCR0, _tmp
ldi _tmp, ((1<<CS12)|(1<<CS10)) ; установка делителя таймера
out TCCR1B, _tmp
; начальное значение счётчика нулевого таймера
clr _tmp
out TCNT0, _tmp
; начальное значение счётчика первого таймера
ldi _tmp, 0xFF
out TCNT1H, _tmp
ldi _tmp, 0xFC
out TCNT1L, _tmp
; установка битов прерываний от таймеров
ldi _tmp, ((1<<TOIE0)|(1<<TOIE1))
out TIMSK, _tmp
; инициализация программных таймеров
ldi XH, 0x01
ldi XL, 0x70
; начальное значение счётчика 0
ser _tmp
st X+, _tmp
st X+, _tmp
clr _tmp
st X+, _tmp
st X+, _tmp
; начальное значение счётчика 1
ser _tmp
st X+, _tmp
st X+, _tmp
clr _tmp
st X+, _tmp
st X+, _tmp
; начальное значение счётчика 2
ser _tmp
st X+, _tmp
st X+, _tmp
clr _tmp
st X+, _tmp
st X+, _tmp
; начальное значение счётчика 3
ser _tmp
st X+, _tmp
st X+, _tmp
clr _tmp
st X+, _tmp
st X+, _tmp
; начальное значение счётчика 4
ser _tmp
st X+, _tmp
st X+, _tmp
clr _tmp
st X+, _tmp
st X+, _tmp
; начальное значение счётчика 5
ser _tmp
st X+, _tmp
st X+, _tmp
clr _tmp
st X+, _tmp
st X+, _tmp
; начальное значение счётчика 6
ser _tmp
st X+, _tmp
st X+, _tmp
clr _tmp
st X+, _tmp
st X+, _tmp
; начальное значение счётчика 7
ser _tmp
st X+, _tmp
st X+, _tmp
clr _tmp
st X+, _tmp
st X+, _tmp
ret; InitTimers

; Обработчик прерывания от первого таймера
TIM1_OVF:
; В текущем контексте сохраняем статус регистр
in StatReg, SREG
; Сохраняем текущий указатель стека
in tSPhi, SPH
in tSPlo, SPL
; Переходим на RAMEND
out SPL, RAMEndLo
out SPH, RAMEndHi
push r2
push r3
push r24
push r25
push XH
push XL
; Проверяем выставленные биты
ChckFlg0:
sbrs DFlags, DelBit0
rjmp ChckFlg1
ldi XH, 0x01
ldi XL, 0x71
ld r24, X
ld r25, -X
adiw r25:r24, 1
st X+, r25
st X+, r24
ld r3, X+
ld r2, X
cp r2, r24
cpc r3, r25
brne ChckFlg1
ClrFlag DFlags, DelBit0
ser _tmp
ldi XH, 0x01
ldi XL, 0x70
st X+, _tmp
st X, _tmp
ChckFlg1:
sbrs DFlags, DelBit1
rjmp ChckFlg2
ldi XH, 0x01
ldi XL, 0x75
ld r24, X
ld r25, -X
adiw r25:r24, 1
st X+, r25
st X+, r24
ld r3, X+
ld r2, X
cp r2, r24
cpc r3, r25
brne ChckFlg2
ClrFlag DFlags, DelBit1
ser _tmp
ldi XH, 0x01
ldi XL, 0x74
st X+, _tmp
st X, _tmp
ChckFlg2:
sbrs DFlags, DelBit2
rjmp ChckFlg3
ldi XH, 0x01
ldi XL, 0x79
ld r24, X
ld r25, -X
adiw r25:r24, 1
st X+, r25
st X+, r24
ld r3, X+
ld r2, X
cp r2, r24
cpc r3, r25
brne ChckFlg3
ClrFlag DFlags, DelBit2
ser _tmp
ldi XH, 0x01
ldi XL, 0x78
st X+, _tmp
st X, _tmp
ChckFlg3:
sbrs DFlags, DelBit3
rjmp ChckFlg4
ldi XH, 0x01
ldi XL, 0x7D
ld r24, X
ld r25, -X
adiw r25:r24, 1
st X+, r25
st X+, r24
ld r3, X+
ld r2, X
cp r2, r24
cpc r3, r25
brne ChckFlg4
ClrFlag DFlags, DelBit3
ser _tmp
ldi XH, 0x01
ldi XL, 0x7C
st X+, _tmp
st X, _tmp
ChckFlg4:
sbrs DFlags, DelBit4
rjmp ChckFlg5
ldi XH, 0x01
ldi XL, 0x81
ld r24, X
ld r25, -X
adiw r25:r24, 1
st X+, r25
st X+, r24
ld r3, X+
ld r2, X
cp r2, r24
cpc r3, r25
brne ChckFlg5
ClrFlag DFlags, DelBit4
ser _tmp
ldi XH, 0x01
ldi XL, 0x80
st X+, _tmp
st X, _tmp
ChckFlg5:
sbrs DFlags, DelBit5
rjmp ChckFlg6
ldi XH, 0x01
ldi XL, 0x85
ld r24, X
ld r25, -X
adiw r25:r24, 1
st X+, r25
st X+, r24
ld r3, X+
ld r2, X
cp r2, r24
cpc r3, r25
brne ChckFlg6
ClrFlag DFlags, DelBit5
ser _tmp
ldi XH, 0x01
ldi XL, 0x84
st X+, _tmp
st X, _tmp
ChckFlg6:
sbrs DFlags, DelBit6
rjmp ChckFlg7
ldi XH, 0x01
ldi XL, 0x89
ld r24, X
ld r25, -X
adiw r25:r24, 1
st X+, r25
st X+, r24
ld r3, X+
ld r2, X
cp r2, r24
cpc r3, r25
brne ChckFlg7
ClrFlag DFlags, DelBit6
ser _tmp
ldi XH, 0x01
ldi XL, 0x88
st X+, _tmp
st X, _tmp
ChckFlg7:
sbrs DFlags, DelBit7
rjmp EndChck
ldi XH, 0x01
ldi XL, 0x8D
ld r24, X
ld r25, -X
adiw r25:r24, 1
st X+, r25
st X+, r24
ld r3, X+
ld r2, X
cp r2, r24
cpc r3, r25
brne EndChck
ClrFlag DFlags, DelBit7
ser _tmp
ldi XH, 0x01
ldi XL, 0x8C
st X+, _tmp
st X, _tmp
EndChck:
; инициализируем счётчик
ldi r25, 0xFF
out TCNT1H, r25
ldi r24, 0xFC
out TCNT1L, r24
pop XL
pop XH
pop r25
pop r24
pop r3
pop r2
; возврат
out SPH, tSPhi
out SPL, tSPlo
; Восстанавливаем статус регистр из текущего контекста
out SREG, StatReg
reti; TIM1_OVF



Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 
NoIX ключ Запомнить

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Rambler's Top100 Рейтинг@Mail.ru
Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание

E-mail: info@telesys.ru