Как устроить многочасовую задержку в Ассемблере для МК???:((
- Сообщения: 13
- Зарегистрирован: Вт авг 02, 2011 14:23:31
Знаком с МК только в объеме данной "обучалки", но мне не нужно пускать светодиодики так или эдак... Пожалуйста... как устроить многочасовую задержку или цикл - нужно рвать и тут же восстанавливать некоторую цепь релюшкой с интервалом 5 - 10 часов (зарядка "сименса")... Какой регистр инкриминировать или декриминировать...? Словом, как устроить столь грандиозный "Loop". Уверен, что не сложно и не надо многого, может даже элементарно... Буду чудовищно благодарен за подробности... Да...чуть не забыл, крайне желательно для ATtiny13A... Хотя бы "наводку"... 
- Реклама
Как вариант могу предложить тактировать МК часовым кварцем например, тогда и задержку можно большую делать..
[img]http://radiokot.ru/forum/download/file.php?id=93376[/img][i][color=#000080][size=85]Между людьми возникает напряжение, если у них разный потенциал...[/size][/color][/i]
- Сообщения: 13
- Зарегистрирован: Вт авг 02, 2011 14:23:31
Спасибо.. Мысль, наверное, вполне здравая...МитяРа писал(а):Как вариант могу предложить тактировать МК часовым кварцем например, тогда и задержку можно большую делать..
Будет и это делать, только медленнее и всё..Вечно начинающий писал(а):но что если он должен выполнять еще что-либо, например выдавать импульсы с двух разрядов порта В
Тогда нужно найти "золотую середину" между простым формированием часовых задержек и выполнением ещё чего-то..
Хотя можно ещё хитрее сделать: пусть МК работает на полной скорости, а для отслеживани я времени поставить RTC например DS1307..
Или без неё на ресурсах МК сделать внутренний RTC и пусть часики тикают..
[img]http://radiokot.ru/forum/download/file.php?id=93376[/img][i][color=#000080][size=85]Между людьми возникает напряжение, если у них разный потенциал...[/size][/color][/i]
- Сообщения: 13
- Зарегистрирован: Вт авг 02, 2011 14:23:31
Хотя можно ещё хитрее сделать: пусть МК работает на полной скорости, а для отслеживани я времени поставить RTC например DS1307..
Или без неё на ресурсах МК сделать внутренний RTC и пусть часики тикают..[/quote]
Дак вот в том-то и дело... как этот самый внутренний RTC (это надо полагать таймер?) организовать? То есть, я где-нибудь хочу увидеть участок кода соответствующий... Насколько я знаю, а знаю я мало.... очень...
- таймер или таймеры в МК - ну это максимум десятки секунд, не больше...
Или без неё на ресурсах МК сделать внутренний RTC и пусть часики тикают..[/quote]
Дак вот в том-то и дело... как этот самый внутренний RTC (это надо полагать таймер?) организовать? То есть, я где-нибудь хочу увидеть участок кода соответствующий... Насколько я знаю, а знаю я мало.... очень...
- Реклама
Вариантов несколько, вот например:Вечно начинающий писал(а): как этот самый внутренний RTC (это надо полагать таймер?) организовать?
а) настраиваешь один из таймеров для "тиканья" секунд по прерыванию, т.е. каждую секунду приходит от таймера прерывание..
б) выделяешь три регистра в МК секунды/минуты/часы..
в) в программе обработки прерывания от таймера обрабатываешь "тиканье" уже всех регистров, т.е. секунды и минуты считаются 0-59, а часы 0-23..
[img]http://radiokot.ru/forum/download/file.php?id=93376[/img][i][color=#000080][size=85]Между людьми возникает напряжение, если у них разный потенциал...[/size][/color][/i]
- Сообщения: 13
- Зарегистрирован: Вт авг 02, 2011 14:23:31
А вот это уже очень здравая мысль... Ну во всяком случае, мне так кажется... Спасибо огромное... Над этим уже можно поработать, если будут еще предложения с удовольствием почитаю... По большой неопытности мурыжиться долго очень придется... Но, в любом случае вроде установку дали верную, спасибо:)
- Сообщения: 13
- Зарегистрирован: Вт авг 02, 2011 14:23:31
Думаю, для начала надо найти пример создания секундомера на основе МК, поизучать листинги...
Щас посмотрел, у AVR есть МК со встроенным RTC, вот статья, мож пригодится: http://easyelectronics.ru/avr-uchebnyj- ... jmera.html
А если хочется на Тиньке13-й, то сделай, программный, как мя те описал..
Заодно можно попутно сделать несколько "будильников" и вставить в программу обработки часов проверку времени этих "будильников"..
А по ним уже и свои события обрабатывать, когда включать подзарядку, а когда выключать..
А если хочется на Тиньке13-й, то сделай, программный, как мя те описал..
Заодно можно попутно сделать несколько "будильников" и вставить в программу обработки часов проверку времени этих "будильников"..
А по ним уже и свои события обрабатывать, когда включать подзарядку, а когда выключать..
[img]http://radiokot.ru/forum/download/file.php?id=93376[/img][i][color=#000080][size=85]Между людьми возникает напряжение, если у них разный потенциал...[/size][/color][/i]
- Сообщения: 13
- Зарегистрирован: Вт авг 02, 2011 14:23:31
Спасибо, попробую разобраться... Но не все сразу... Просто хотелось сразу и наскоком, видно не получиться... это только два импульса с двух разрядов на кнопки телефона - это действительно просто, а с часами уже сложнее... увы... Пока прервусь, будет еще, что посоветовать пишите - благодарен...
самый тупой способ, самый дешевый и простой: программная задержка.этот код WinAVR создаст задержку примерно 278 часов.
узкое место: если зависнет, то каюк. поэтому лучше использовать WDT, настроив его на 1 секунду и считая сбросы аналогичным способом. attiny13 будет с головой достаточно, и никаких RTC и другой мороки (если не требуется идеальная точность выдержки времени)
Код: Выделить всё
for(uint32_t i=0; i< 1000000UL; i++){
_delay_ms(1000);
}узкое место: если зависнет, то каюк. поэтому лучше использовать WDT, настроив его на 1 секунду и считая сбросы аналогичным способом. attiny13 будет с головой достаточно, и никаких RTC и другой мороки (если не требуется идеальная точность выдержки времени)
битва с дураками проиграна, победители торжествуют. слава победителям!
На ассемблере, для самых начинающих, предлагали в одной книжке (The AVR microcontroller and embedded systems) сделать несколько вложенных циклов. Инструкцией BRNE. Один цикл может пройти максимум 255 раз, для вложенных надо перемножать. Пять вложенных циклов могут дать максимум порядка 300 часов задержки, при тактовой частоте 8 МГц. Будут использоваться 5 регистров (из 32-х). Более правильно таймерами... но можно и так. Если нужно меньше 300 часов, то загрузить в регистры меньшие значения.
LDI R20, 255
GGG0: LDI R21, 255
GGG1: LDI R22, 255
GGG2: LDI R23, 255
GGG3: LDI R24, 255
GGG4: NOP
NOP
NOP
DEC R24
BRNE GGG4
DEC R23
BRNE GGG3
DEC R22
BRNE GGG2
DEC R21
BRNE GGG1
DEC R20
BRNE GGG0
LDI R20, 255
GGG0: LDI R21, 255
GGG1: LDI R22, 255
GGG2: LDI R23, 255
GGG3: LDI R24, 255
GGG4: NOP
NOP
NOP
DEC R24
BRNE GGG4
DEC R23
BRNE GGG3
DEC R22
BRNE GGG2
DEC R21
BRNE GGG1
DEC R20
BRNE GGG0
самый бестолковый способ, ведь мк при этом не сможет больше ничего (кроме прерываний) выполнятьSmarTrunk писал(а):На ассемблере, для самых начинающих, предлагали в одной книжке (The AVR microcontroller and embedded systems) сделать несколько вложенных циклов. Инструкцией BRNE. Один цикл может пройти максимум 255 раз, для вложенных надо перемножать. Пять вложенных циклов могут дать максимум порядка 300 часов задержки, при тактовой частоте 8 МГц. Будут использоваться 5 регистров (из 32-х). Более правильно таймерами... но можно и так. Если нужно меньше 300 часов, то загрузить в регистры меньшие значения.
я обычно организую переменную из N-байт которую inc/dec в прерывании какого-нибудь таймера, и при переполнении/совпадении/обнулении (это как карты лягут) этой переменной произвожу манипуляции, вариаций море.
- Сообщения: 16
- Зарегистрирован: Ср янв 19, 2011 00:34:56
Использую ниже ассемблер для PIC, для других ассемблеров все деалется аналогично.
Организуйте длинные целые.
Пусть нужна задержка 100 часов. Пусть в вашей программе можно вызывать
некую подпрограмму раз в секунду. Считаем :
Зедержка = 100 * 60 * 60 = 360000 = 57E40h = секунд.
Задержка укладывается в три байта, значит будем использовать
трехбайтное целое.
TIME_HI EQU 20h ; Старший байт
TIME_ME EQU 21h ; Средний -//-
TIME_LO EQU 22h ; Младший -//-
Инициализация длинного целого счетчика задержки :
MOVLW 5
MOVWF TIME_HI
MOVLW 7Eh
MOVWF TIME_ME
MOVLW 40h-1 ; На один меньше, ибо будем считать до -1
MOVWF TIME_LO
Раз в секунду будет вызывать подпрограмму вычитания из длинного целого
счетчика задержки единицы и если досчитаем до -1, то выключим зарядку :
TICK_1s:
DECF TIME_LO, F
INCFSZ TIME_LO, W
RETURN
DECF TIME_ME, F
INCFSZ TIME_ME, W
RETURN
DECF TIME_HI, F
INCFSZ TIME_HI, W
RETURN
DONE: Задержка досчиталась до -1, выключаем зарядку !
RETURN
Аналогично алгоритм пересчитывается для любой длинной задержки и для
любой частоты вызова подпрограммы вычитания из длинного целого счетчика
единицы.
Организуйте длинные целые.
Пусть нужна задержка 100 часов. Пусть в вашей программе можно вызывать
некую подпрограмму раз в секунду. Считаем :
Зедержка = 100 * 60 * 60 = 360000 = 57E40h = секунд.
Задержка укладывается в три байта, значит будем использовать
трехбайтное целое.
TIME_HI EQU 20h ; Старший байт
TIME_ME EQU 21h ; Средний -//-
TIME_LO EQU 22h ; Младший -//-
Инициализация длинного целого счетчика задержки :
MOVLW 5
MOVWF TIME_HI
MOVLW 7Eh
MOVWF TIME_ME
MOVLW 40h-1 ; На один меньше, ибо будем считать до -1
MOVWF TIME_LO
Раз в секунду будет вызывать подпрограмму вычитания из длинного целого
счетчика задержки единицы и если досчитаем до -1, то выключим зарядку :
TICK_1s:
DECF TIME_LO, F
INCFSZ TIME_LO, W
RETURN
DECF TIME_ME, F
INCFSZ TIME_ME, W
RETURN
DECF TIME_HI, F
INCFSZ TIME_HI, W
RETURN
DONE: Задержка досчиталась до -1, выключаем зарядку !
RETURN
Аналогично алгоритм пересчитывается для любой длинной задержки и для
любой частоты вызова подпрограммы вычитания из длинного целого счетчика
единицы.
- Сообщения: 3385
- Зарегистрирован: Пн окт 11, 2010 19:00:08
Можно заюзать, например, эту прогу.
Правда, она для PIC.
Правда, она для PIC.
Я бы сделал так.
Настраиваем прерывание по таймеру, скажем, на 1 мс.
В обработчике прерывания по таймеру напишем :
SUBI REG_L,1
BRCC not_flag
SUBI REG_M,1
BRCC not_flag
SUBI REG_H,1
BRCC not_flag
LDI REG_F,1
not_flag: ........
Инициализируем в нужном месте программы задержку.
LDI REG_L,lowwalue
LDI REG_M,middlvalue
LDI REG_H,highvalue
LDI REG_F,0
Теперь выполняем какие хотим действия, периодически посматривая на флаг REG_F. Если он ненулевой, значит, задержка отработана.
А что будет, если за время выдержки вырубится питание - это отдельная песня.
REG_L,REG_M,REG_H,REG_F - это регистры, которые не будут использоваться другими процессами. Иначе придется под это дело заводить переменные.
Если прерывание через 1 мс, то хватит на 4.5 часа, если 10 мс - приблизительно на двое суток.
Настраиваем прерывание по таймеру, скажем, на 1 мс.
В обработчике прерывания по таймеру напишем :
SUBI REG_L,1
BRCC not_flag
SUBI REG_M,1
BRCC not_flag
SUBI REG_H,1
BRCC not_flag
LDI REG_F,1
not_flag: ........
Инициализируем в нужном месте программы задержку.
LDI REG_L,lowwalue
LDI REG_M,middlvalue
LDI REG_H,highvalue
LDI REG_F,0
Теперь выполняем какие хотим действия, периодически посматривая на флаг REG_F. Если он ненулевой, значит, задержка отработана.
А что будет, если за время выдержки вырубится питание - это отдельная песня.
REG_L,REG_M,REG_H,REG_F - это регистры, которые не будут использоваться другими процессами. Иначе придется под это дело заводить переменные.
Если прерывание через 1 мс, то хватит на 4.5 часа, если 10 мс - приблизительно на двое суток.



