Ассемблер (ASM) для AVR в вопросах и ответах
- Сообщения: 1487
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Сторожевой таймер работает от независимого внутреннего генератора мк. С кварцем и внешним тактовым входом никак не связан. Время срабатывания настраивается специальным регистром.
- Реклама
- Сообщения: 3342
- Зарегистрирован: Ср янв 02, 2013 08:37:35
[uquote="vit007",url="/forum/viewtopic.php?p=3423720#p3423720"]Все равно не понятно, как посчитать время до прерывание в авр. У меня 1 MHz[/uquote]
- Сообщения: 124
- Зарегистрирован: Пн мар 22, 2010 18:07:52
С мануалом сходится...
, но почему на симуляторе не видно. Только в железе можно увидеть?
Цитата из Help симулятора Студии 4.19
Похоже что так.Notes for ATtiny25/45/85
The Watchdog is not simulated.
- Сообщения: 19
- Зарегистрирован: Вс сен 09, 2018 06:42:27
Всем Привет ! учу ассемблер avr, выполняю очередное задание. Сложить два массива и создать на их основе третий. Всё было хорошо с двумя массивами данных. Но когда понадобилось
создать третий в озу и я воспользовался третьей регистровой парой x , atmel sudio 7 (attiny13) стала ругаться на плохой номер или операнд при чтение байта в регистр. Есть какие то ограничения на эту регистровую пару ? в даташите на тиньку ничего нет об этом
вот код
LDI XL,low(data*2) ; заносим младший байт адреса, в регистровую пару
LDI XH,high(data*2) ; заносим старший байт адреса, в регистровую пару
LPM R17,X
data: .db $10,$7
Добавлено after 35 minutes 55 seconds:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
СОРРИ, ЗА БЕСПОКОЙСТВО. Уже разобрался, команда lpm работает только с Z
создать третий в озу и я воспользовался третьей регистровой парой x , atmel sudio 7 (attiny13) стала ругаться на плохой номер или операнд при чтение байта в регистр. Есть какие то ограничения на эту регистровую пару ? в даташите на тиньку ничего нет об этом
вот код
LDI XL,low(data*2) ; заносим младший байт адреса, в регистровую пару
LDI XH,high(data*2) ; заносим старший байт адреса, в регистровую пару
LPM R17,X
data: .db $10,$7
Добавлено after 35 minutes 55 seconds:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
СОРРИ, ЗА БЕСПОКОЙСТВО. Уже разобрался, команда lpm работает только с Z
Работа - продажа электронных компонентов. А для души - есть Ассемблер, дочка и сын.
- Реклама
LPM работает НЕ С ОЗУ, А с ПЗУ!!!!!
Вы чего хотите - массивы в ОЗУ изменить или автоперепрошивкой МК заняться?

Если оба исходных массива в ПЗУ
то сначала читаем в буфер А одно значение, затем делаем быстрый обмен содержимого регистровой пары второго адреса (MOVW zl,r2 к примеру), заранее сохраненной в регистровом банке (r2-r15), затем читаем второе значение в буфер В, делаем над данными необходимую операцию и помещаем результат в ОЗУ.
Кроме прочего для однобайтовых данных у тини 13 имеется возможность применения LPM Rd,Z+ с постинкрементом указателя.

Вы чего хотите - массивы в ОЗУ изменить или автоперепрошивкой МК заняться?
Если оба исходных массива в ПЗУ
то сначала читаем в буфер А одно значение, затем делаем быстрый обмен содержимого регистровой пары второго адреса (MOVW zl,r2 к примеру), заранее сохраненной в регистровом банке (r2-r15), затем читаем второе значение в буфер В, делаем над данными необходимую операцию и помещаем результат в ОЗУ.
Кроме прочего для однобайтовых данных у тини 13 имеется возможность применения LPM Rd,Z+ с постинкрементом указателя.
Сейчас разбираюсь с динамическим опросом кнопок, сделал так для экономии портов - кнопки сканируются одновременно с анодами индикаторов (см. схему)
Сканирование сделал просто логическим сдвигом влево. Когда единичка вылезает во флаг С, записываю в регистр Anodes изначальное состояние.
ldi Anodes,0b00010000
out portD,Anodes
lsl Anodes
brcc Next
ldi Anodes,0b00001000
...
Собственно, здесь всё понятно. А вот как опрашивать кнопки? Если нажата любая из четырёх кнопок, на PortB,0 появляется единичка. Чтобы понять, какая именно кнопка нажата, у меня только одна идея: cpi Anodes,0b00010000 и так четыре раза для всех четырёх возможных состояний. Может, есть какой-то более изящный способ, чем тупо перебирать все возможные состояния путём сравнения с константой?
Сканирование сделал просто логическим сдвигом влево. Когда единичка вылезает во флаг С, записываю в регистр Anodes изначальное состояние.
Спойлер
...ldi Anodes,0b00010000
out portD,Anodes
lsl Anodes
brcc Next
ldi Anodes,0b00001000
...
Фак, кот грызёт провод! Сейчас его ударит либо током, либо тапком! ))
Как-то заморочено сильно и не универсально. Я как-то делал по другому, заводишь массив с масками анодов, перебираешь индекс массива, выставляешь маску засвета анодов и опрашиваешь порт общего провода кнопок(через 100...500мкс, дабы не попасть на переходный процесс и не получить ложняк от емкостной наводки), появится активный уровень - НОМЕР КНОПКИ равен индексу. Можно без задержки, но считывать порт кнопки ДО того как меняешь анод, но там надо будет вычислять предыдущее значение индекса... и что-то сделать с первым считанным значением т.к. оно точно будет мусором - лишняя морока. Если частота опроса анода будет 200Гц, то считаешь до 5 и если номер кнопки не меняется - регистрируешь нажатие.
Можно заменить диоды резисторами 1кОм, посадить общую точку кнопок на общий и избавиться от PB0. В конце каждого периода индикации переводить текущую лапу на ввод с подтяжкой и опрашивать кнопку.
[uquote="Гефестион",url="/forum/viewtopic.php?p=3464065#p3464065"]А вот как опрашивать кнопки?[/uquote]Как вариант
Спойлер
Спойлер
Код: Выделить всё
.include "tn2313Adef.inc"
.def R_KEY=R0
.def R_ANODE=R19
.cseg
.org 0
RJMP START
TB_ANODE:
.DB 0b10000000,0b01000000,0b00100000,0b00010000
;*******Инициализация*****************************
START:
LDI R16,RAMEND
OUT SPL,R16 ; инициализация стека
CLR R_ANODE
SER R16
OUT DDRD,R16 ; настройка порта D
OUT DDRA,R16 ; настройка порта A
OUT DDRB,R16 ; настройка порта B
;*************************************************
TEST_ANODE_KEY:
CLR ZH
LDI ZL,LOW(TB_ANODE*2)
ADD ZL,R_ANODE
LPM R22,Z
OUT PORTB,R22
COM R22
OUT DDRB,R22
RCALL PAUSE
IN R_KEY,PINB ;
OUT DDRB,R16
INC R_ANODE
ANDI R_ANODE,0b00000011
RJMP TEST_ANODE_KEY
PAUSE:
RET
.EXIT- Вложения
-
- KEY.jpg
- (37.9 КБ) 485 скачиваний
В программе обязательно присутствует счетчик знакомест и маска активации знакоместа.
Вот значение первого встречного из нажатых и фиксируется (код согласно счетчика).
На следующем проходе развертки повторно сравниваем статус входной линии - ежли совпало
значит исполняем, ежли нет - пропускаем опрос до конца текущего цикла развертки.
А в следующем - все заново.
Правда при таком варианте "одновременное нажатие нескольких кнопок" отследить затруднительно
- процедура значительно по-сложнее.

Вот значение первого встречного из нажатых и фиксируется (код согласно счетчика).
На следующем проходе развертки повторно сравниваем статус входной линии - ежли совпало
значит исполняем, ежли нет - пропускаем опрос до конца текущего цикла развертки.
А в следующем - все заново.
Правда при таком варианте "одновременное нажатие нескольких кнопок" отследить затруднительно
- процедура значительно по-сложнее.
Ещё такой вопрос - допустимы ли прерывания в прерываниях? У меня используется прерывание по таймеру с частотой 500 Гц для динамической индикации и внешнее прерывание от часовой микросхемы с частотой 1 Гц. По внешнему прерыванию происходит чтение секунд, минут, часов, даты по I2C, и в этот момент динамическая индикация дёргается. Тогда я в обработчике этого прерывания прописал SEI, чтобы разрешить прерывание от таймера. Вроде всё работает, но иногда (раз в несколько часов, иногда раз в сутки) часы начинают глючить. Подозреваю, что это какая-то "коллизия" между прерываниями происходит.
Фак, кот грызёт провод! Сейчас его ударит либо током, либо тапком! ))
Низкоприоритетному прерыванию (секунды) можно включить флаг ISR_NOBLOCK, тогда оно будет прерываться другими. Фактически, то же самое, что Вы сделали, но, что ли, чуть правильнее.
А самый правильный вариант - в прерывании секунд просто взводить какой-нибудь флажок, а уже секунды по I²C вычитывать в основном цикле программы, по наличию этого флага. А по окончании вычитки - сбрасывать этот флаг.
А самый правильный вариант - в прерывании секунд просто взводить какой-нибудь флажок, а уже секунды по I²C вычитывать в основном цикле программы, по наличию этого флага. А по окончании вычитки - сбрасывать этот флаг.
И не надо вообще входить в прерывание по секунде, а просто опрашивать его в фоне, и вычитывать по I²C и сбрасывать запрос на прерывание.
I2C допускает приостановку на некоторое время (если обработчик мастера программный).
Замена данных в буфере отображения/вывода ВСЕГДА производится в конце текущей строки развертки при погашенной индикации (тогда и "дерготни" не будет)
А глазу наблюдателя смена показаний что на 0,016 секунды раньше, что на такое же время позже АБСОЛЮТНО БЕЗ РАЗНИЦЫ.
Насчет "глючения" в разные относительно длинные и неравномерные интервалы времени - это к гадалкам.
Обычно нормально написанная программа таких дефектов не имеет.

Кстати... обычно чтение ВСЕХ данных из RTC делается или однократно при запуске устройства по подаче питания или только по "жизненной необходимости" (включая коррекцию данных").
В остальное время работает модуль "внутренних часов" в самом МК с приращением от ежесекундного прерывания от RTC.
Остальные программы подбираются с учетом секундного интервала - должны или вписыватся в него или "дробиться" на участки менее 1 секунды.

Замена данных в буфере отображения/вывода ВСЕГДА производится в конце текущей строки развертки при погашенной индикации (тогда и "дерготни" не будет)
А глазу наблюдателя смена показаний что на 0,016 секунды раньше, что на такое же время позже АБСОЛЮТНО БЕЗ РАЗНИЦЫ.
Насчет "глючения" в разные относительно длинные и неравномерные интервалы времени - это к гадалкам.
Обычно нормально написанная программа таких дефектов не имеет.
Кстати... обычно чтение ВСЕХ данных из RTC делается или однократно при запуске устройства по подаче питания или только по "жизненной необходимости" (включая коррекцию данных").
В остальное время работает модуль "внутренних часов" в самом МК с приращением от ежесекундного прерывания от RTC.
Остальные программы подбираются с учетом секундного интервала - должны или вписыватся в него или "дробиться" на участки менее 1 секунды.
- Сообщения: 615
- Зарегистрирован: Вс дек 28, 2014 21:54:05
Гефестион, я бы в прерывании от часов просто считал бы до 60, а с часами по i2c синхронизировался бы по истечении тех 60 сек, т.е. раз в минуту. А 500 герц считаю слишком много, для динамики имхо, хватило б и 100. Тогда и не надо будет разрешать прерывания в прерывании.
Я всё-всё узнAю и стану профессором.
- Сообщения: 3385
- Зарегистрирован: Пн окт 11, 2010 19:00:08
С каких пор AVR аппаратно поддерживают вложенные прерывания? Эта возможность появилась в более новых МК например с ядром ARM.WiseLord писал(а):Низкоприоритетному прерыванию (секунды) можно включить флаг ISR_NOBLOCK
Зависит от числа разрядов и количества сегментных портов.
0,016 секунды на всю развертку (~ 62,5 Гц)
при 8 знакоместах и одном сегментном порте 0,016/8 = 0,002 секунды на знакоместо (те же 500 Гц)
Можно конечно еще и "прошимить"...
Но даже такой вариант при правильной смене данных и грамотном распределении ресурсов заметного мерцания не даст.
Как вариант гашение одного из нескольких циклов развертки в уж оччень жестких условиях для процедур, не терпящих прерываний.

Синхронизация с RTC не имеющими программной коррекции точности хода в энергонезавсимом режиме даст гораздо меньшую точность, чем отработка собственного КВАРЦЕВОГО генератора МК, да еще на гораздо более высокой частоте и при программной коррекции точности хода. RTC более как "хранилище опорных данных" во время отключенного состояния устройства использовать полезно.

МУРИК...
Ну не ожидал такого "ляпсуса" насчет вложенных прерываний у АВРок...
Достаточно добавить внутри открытого прерывания команду разрешения (как и у всех типовых МК).
Другой вопрос контроллер приоритетных прерываний как например у MCS51

0,016 секунды на всю развертку (~ 62,5 Гц)
при 8 знакоместах и одном сегментном порте 0,016/8 = 0,002 секунды на знакоместо (те же 500 Гц)
Можно конечно еще и "прошимить"...
Но даже такой вариант при правильной смене данных и грамотном распределении ресурсов заметного мерцания не даст.
Как вариант гашение одного из нескольких циклов развертки в уж оччень жестких условиях для процедур, не терпящих прерываний.
Синхронизация с RTC не имеющими программной коррекции точности хода в энергонезавсимом режиме даст гораздо меньшую точность, чем отработка собственного КВАРЦЕВОГО генератора МК, да еще на гораздо более высокой частоте и при программной коррекции точности хода. RTC более как "хранилище опорных данных" во время отключенного состояния устройства использовать полезно.
МУРИК...
Ну не ожидал такого "ляпсуса" насчет вложенных прерываний у АВРок...
Достаточно добавить внутри открытого прерывания команду разрешения (как и у всех типовых МК).
Другой вопрос контроллер приоритетных прерываний как например у MCS51
- Сообщения: 3385
- Зарегистрирован: Пн окт 11, 2010 19:00:08
BOB51, я про аппаратную поддержку, а то что вы предлагаете это программная. При некоторых обстоятельствах программно разрешая прерывания можно получить переполнение стека. При аппаратной поддержке прервать текущее прерывание, может только то что имеет больший приоритет чем текущее, которое выполняется. В AVR (ATtiny и ATmega) такого нет.BOB51 писал(а):Достаточно добавить внутри открытого прерывания команду разрешения
И где это Вы в моих словах вычитали что-то про аппаратную поддержку прерывания? Я вроде как всё совсем наоборот сказал.Мурик писал(а):С каких пор AVR аппаратно поддерживают вложенные прерывания?
Зато там нет блокировок, свойственных аппаратным контроллерам - запрет на повторный вызов того же прерывания внутри текущего исполнения. Пресловутое "нельзя выполнить снова, пока хотя бы одна команда после возврата не будет выполнена".
Хотя то конечно ВЕЛИКИЙ ИЗВРАТ не для начинающих.
И не путать ВЛОЖЕННЫЕ ПРЕРЫВАНИЯ
с
АППАРАТНЫМ КОНТРОЛЛЕРОМ ПРИОРИТЕТНЫХ ПРЕРЫВАНИЙ,
тем более, что ни Z80 ни MCS51 "новыми" никак назвать нельзя...

Да и переполнение стека при 32х регистр-акумуляторах и одновременно минимум 64 байтах ОЗУ под стек...
Это уж только ежли некорректности с возвратом из подпрограмм допустить. Надо весьма умудриться...

Хотя то конечно ВЕЛИКИЙ ИЗВРАТ не для начинающих.
И не путать ВЛОЖЕННЫЕ ПРЕРЫВАНИЯ
с
АППАРАТНЫМ КОНТРОЛЛЕРОМ ПРИОРИТЕТНЫХ ПРЕРЫВАНИЙ,
тем более, что ни Z80 ни MCS51 "новыми" никак назвать нельзя...
Да и переполнение стека при 32х регистр-акумуляторах и одновременно минимум 64 байтах ОЗУ под стек...
Это уж только ежли некорректности с возвратом из подпрограмм допустить. Надо весьма умудриться...


