Обсуждаем контроллеры компании Atmel.
Ответить

16 битный счетчик или как посчитать до 65535 на 8 битном мк

Пт фев 21, 2020 10:09:39

Всем Привет ! понадобилось мне как то посчитать прерывания от таймера больше чем 256 раз. В интернете не нашел готовых алгоритмов. Искал не долго минут 30.
Вообщем решил написать свой - прошу оценить насколько это правильно я сделал. Может кому то пригодится.
Код на ассемблере avr
;*****************************************
; 16 битный счетчик - использовать только 1 рон


;*******************************************
.include "tn13def.inc"
;****** РЕГИСТРЫ
.def tmp0=r16 ; используется везде в качестве переменной для обмена данными
.def count_timer=r18 ; 1 байт нашего счетчика

;*******************************************
rjmp start ;Reset Handle
reti ;Внешнее настраиваемое прерывание External Interrupt Request 0 INT0
reti ;Внешнее прерывание по изменению состояния вывода Pin Change Interrupt Request 0 PCINT0
reti ;Прерывание по переполнению таймера/счетчика 0
reti ;EE_READY_vect EEPROM готова
reti ;ANALOG_COMP_vect Аналоговый компаратор переключился
reti ;TIMER0_COMPA_vect Прерывание по сравнению, канал A таймера/счетчика 0
reti ;TIMER0_COMPB_vect Прерывание по сравнению, канал B таймера/счетчика 0
reti ;WDT_vect Сторожевой таймер (если используется в качестве источника прерывания)
reti ;ADC_vect Преобразование АЦП завершено

.dseg
counter2: .byte 1 ; Выделяем 1 ячеку в озу для хранения второго байта счетчика
.cseg ; область команд

reset:
ldi tmp0, low(RAMEND) ; Стандартная инициализация стека
out SPL,tmp0
ldi count_timer,0 ; Обнуляем первый байт счетчика, величина второго байта не принципиальна при сбросе мк

start: inc count_timer ; Добавляем единичку
BRBS SREG_Z,overfl ; Для проверки достижения макс знач - переполн. Используем проверку флага Z регистор флагов
rjmp start
overfl:
ldi count_timer,0 ; Обнуляем первый байт счетчика
lds tmp0,counter2 ; Читаем из оперативы выделенный байт counter2
inc tmp0 ; Так как команда inc не может напрямую работать с ячейкой озу - используем переходн. перем TMP0
sts counter2,tmp0 ; Сохраняем в озу новое значение counter2 увеличенное на 1. (инкрементируем)
BRBS SREG_Z,overfl1 ; Для проверки достижения макс знач - переполн. Используем проверку флага Z регистор флагов
rjmp start ; Если нужно досчитать до другого значения используем другую комаду ветвления их в мк много.
overfl1: nop
Вложения
16bit_counter.asm
(2.25 KiB) Скачиваний: 156
algoritm 16bit.jpg
(32.21 KiB) Скачиваний: 156

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 10:23:25

алгоритм-то у вас нарисован не правильный... не по достижению 255 ветвление, а по переполнению, т.е. по достижению 256.
кроме того, если надо "досчитать" до какого-то значения, логичнее считать вычитанием из этого значения до нуля.

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 10:37:37

neitrino777 Начинать счёт лучше с 0.
Код:
;rjmp start ;Reset Handle
rjmp RESET ;Reset Handle
reti ;Внешнее настраиваемое прерывание External Interrupt Request 0 INT0
reti ;Внешнее прерывание по изменению состояния вывода Pin Change Interrupt Request 0 PCINT0
reti ;Прерывание по переполнению таймера/счетчика 0
reti ;EE_READY_vect EEPROM готова
reti ;ANALOG_COMP_vect Аналоговый компаратор переключился
reti ;TIMER0_COMPA_vect Прерывание по сравнению, канал A таймера/счетчика 0
reti ;TIMER0_COMPB_vect Прерывание по сравнению, канал B таймера/счетчика 0
reti ;WDT_vect Сторожевой таймер (если используется в качестве источника прерывания)
reti ;ADC_vect Преобразование АЦП завершено

.dseg
counter2: .byte 1 ; Выделяем 1 ячеку в озу для хранения второго байта счетчика
.cseg ; область команд

reset:
ldi tmp0, low(RAMEND) ; Стандартная инициализация стека
out SPL,tmp0
ldi count_timer,-1 ; предустановка в -1
;ldi count_timer,0 ; Обнуляем первый байт счетчика, величина второго байта не принципиальна при сбросе мк

start: inc count_timer ; Добавляем единичку
Последний раз редактировалось akl Пт фев 21, 2020 12:18:32, всего редактировалось 2 раз(а).

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 10:46:34

чем лучше-то? как по мне, так вычитанием проще. у топикстартера счет до 65535, если модифицировать его алгоритм для счета ДО ЛЮБОГО 16-битного числа - что выйдет? при вычитании те же 7 команд.

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 12:33:46

ADIW/SBIW забыли...
8)

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 15:10:30

не забыли. при счете на вычитание проверить равенство нулю двухбайтового числа можно одой командой OR, а при счете на увеличение сравнить два двухбайтных числа (счетчик и заданное) одной командой никак не выйдет.

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 15:54:23

А то, что ОБЕ эти команды (ADIW/SBIW) ставят Z=1 при результате = 0х0000
НЕ ПОДХОДИТ?
:wink:

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 16:21:01

BOB51 писал(а):НЕ ПОДХОДИТ?
как по мне, так без разницы, я ассемблером перегорел давно. все не упомнишь - если ставят Z, то и чудесно

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 16:29:32

Да и я не так часто самоделки верчу...
Старые "шпоры" и конспект выручают!
шпора AVR.pdf
(60.25 KiB) Скачиваний: 121

(Тем более прыгать ассемблеру между трех семейств... :wink: )
:beer:

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 16:55:54

Чем люди только не занимаются, лишь бы C не изучать ;P

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 19:50:53

Си/С++ я лучше с ардуинкой скушаю.
(https://radiokot.ru/forum/viewtopic.php?f=62&t=156720)
Оно друг дружке никак не мешает - только польза от взаимодополнений.
8)

Поставил топикстартеру плюсик за активность - маловато сейчас народу начинающего,
пусть не стесняются свои замечания/пробы публиковать - мы также не сразу "вумными котанами" стали!
:beer:

Re: 16 битный счетчик или как посчитать до 65535 на 8 битно

Пт фев 21, 2020 20:53:53

Спасибо всем. Значит в правильном направление двигаюсь. С нуля считать да - наверное удобней. Хочу хорошо знать ассемблер - что бы выжимать из железок по максиму. Понятно, что крупные проекты это си или модули побольше. Мне важно понимать как это работает внутри на случай если что-то не работает уметь это чинить -оптимизировать.
Ответить