Обсуждаем контроллеры компании Atmel.
Вс июл 22, 2018 19:50:04
Сторожевой таймер работает от независимого внутреннего генератора мк. С кварцем и внешним тактовым входом никак не связан. Время срабатывания настраивается специальным регистром.
Пн июл 23, 2018 07:27:39
Все равно не понятно, как посчитать время до прерывание в авр. У меня 1 MHz
Пн июл 23, 2018 09:05:11
С мануалом сходится...
, но почему на симуляторе не видно. Только в железе можно увидеть?
Пн июл 23, 2018 10:52:34
Цитата из Help симулятора Студии 4.19
Notes for ATtiny25/45/85
The Watchdog is not simulated.
Похоже что так.
Вс сен 09, 2018 07:37:26
Всем Привет ! учу ассемблер 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
Вс сен 09, 2018 07:52:08
LPM работает НЕ С ОЗУ, А с ПЗУ!!!!!Вы чего хотите - массивы в ОЗУ изменить или автоперепрошивкой МК заняться?
Если оба исходных массива в ПЗУ
то сначала читаем в буфер А одно значение, затем делаем быстрый обмен содержимого регистровой пары второго адреса (MOVW zl,r2 к примеру), заранее сохраненной в регистровом банке (r2-r15), затем читаем второе значение в буфер В, делаем над данными необходимую операцию и помещаем результат в ОЗУ.
Кроме прочего для однобайтовых данных у тини 13 имеется возможность применения LPM Rd,Z+ с постинкрементом указателя.
Пн сен 24, 2018 17:35:36
Сейчас разбираюсь с динамическим опросом кнопок, сделал так для экономии портов - кнопки сканируются одновременно с анодами индикаторов (см. схему)
Сканирование сделал просто логическим сдвигом влево. Когда единичка вылезает во флаг С, записываю в регистр Anodes изначальное состояние.
Спойлер
...
ldi Anodes,0b00010000
out portD,Anodes
lsl Anodes
brcc Next
ldi Anodes,0b00001000
...Собственно, здесь всё понятно. А вот как опрашивать кнопки? Если нажата любая из четырёх кнопок, на
PortB,0 появляется единичка. Чтобы понять, какая именно кнопка нажата, у меня только одна идея:
cpi Anodes,0b00010000 и так четыре раза для всех четырёх возможных состояний. Может, есть какой-то более изящный способ, чем тупо перебирать все возможные состояния путём сравнения с константой?
Пн сен 24, 2018 23:07:05
Как-то заморочено сильно и не универсально. Я как-то делал по другому, заводишь массив с масками анодов, перебираешь индекс массива, выставляешь маску засвета анодов и опрашиваешь порт общего провода кнопок(через 100...500мкс, дабы не попасть на переходный процесс и не получить ложняк от емкостной наводки), появится активный уровень - НОМЕР КНОПКИ равен индексу. Можно без задержки, но считывать порт кнопки ДО того как меняешь анод, но там надо будет вычислять предыдущее значение индекса... и что-то сделать с первым считанным значением т.к. оно точно будет мусором - лишняя морока. Если частота опроса анода будет 200Гц, то считаешь до 5 и если номер кнопки не меняется - регистрируешь нажатие.
Вт сен 25, 2018 07:28:29
Можно заменить диоды резисторами 1кОм, посадить общую точку кнопок на общий и избавиться от PB0. В конце каждого периода индикации переводить текущую лапу на ввод с подтяжкой и опрашивать кнопку.
Спойлер
А вот как опрашивать кнопки?
Как вариант
Спойлер
- Код:
.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 KiB) Скачиваний: 452
Вт сен 25, 2018 10:25:32
В программе обязательно присутствует счетчик знакомест и маска активации знакоместа.
Вот значение первого встречного из нажатых и фиксируется (код согласно счетчика).
На следующем проходе развертки повторно сравниваем статус входной линии - ежли совпало
значит исполняем, ежли нет - пропускаем опрос до конца текущего цикла развертки.
А в следующем - все заново.
Правда при таком варианте "одновременное нажатие нескольких кнопок" отследить затруднительно
- процедура значительно по-сложнее.
Сб сен 29, 2018 15:08:41
Ещё такой вопрос - допустимы ли прерывания в прерываниях? У меня используется прерывание по таймеру с частотой 500 Гц для динамической индикации и внешнее прерывание от часовой микросхемы с частотой 1 Гц. По внешнему прерыванию происходит чтение секунд, минут, часов, даты по I2C, и в этот момент динамическая индикация дёргается. Тогда я в обработчике этого прерывания прописал SEI, чтобы разрешить прерывание от таймера. Вроде всё работает, но иногда (раз в несколько часов, иногда раз в сутки) часы начинают глючить. Подозреваю, что это какая-то "коллизия" между прерываниями происходит.
Сб сен 29, 2018 16:57:31
Низкоприоритетному прерыванию (секунды) можно включить флаг ISR_NOBLOCK, тогда оно будет прерываться другими. Фактически, то же самое, что Вы сделали, но, что ли, чуть правильнее.
А самый правильный вариант - в прерывании секунд просто взводить какой-нибудь флажок, а уже секунды по I²C вычитывать в основном цикле программы, по наличию этого флага. А по окончании вычитки - сбрасывать этот флаг.
Сб сен 29, 2018 17:39:14
И не надо вообще входить в прерывание по секунде, а просто опрашивать его в фоне, и вычитывать по I²C и сбрасывать запрос на прерывание.
Сб сен 29, 2018 17:42:40
I2C допускает приостановку на некоторое время (если обработчик мастера программный).
Замена данных в буфере отображения/вывода ВСЕГДА производится в конце текущей строки развертки при погашенной индикации (тогда и "дерготни" не будет)
А глазу наблюдателя смена показаний что на 0,016 секунды раньше, что на такое же время позже АБСОЛЮТНО БЕЗ РАЗНИЦЫ.
Насчет "глючения" в разные относительно длинные и неравномерные интервалы времени - это к гадалкам.
Обычно нормально написанная программа таких дефектов не имеет.
Кстати... обычно чтение ВСЕХ данных из RTC делается или однократно при запуске устройства по подаче питания или только по "жизненной необходимости" (включая коррекцию данных").
В остальное время работает модуль "внутренних часов" в самом МК с приращением от ежесекундного прерывания от RTC.
Остальные программы подбираются с учетом секундного интервала - должны или вписыватся в него или "дробиться" на участки менее 1 секунды.
Сб сен 29, 2018 17:54:44
Гефестион, я бы в прерывании от часов просто считал бы до 60, а с часами по i2c синхронизировался бы по истечении тех 60 сек, т.е. раз в минуту. А 500 герц считаю слишком много, для динамики имхо, хватило б и 100. Тогда и не надо будет разрешать прерывания в прерывании.
Сб сен 29, 2018 18:16:20
WiseLord писал(а):Низкоприоритетному прерыванию (секунды) можно включить флаг ISR_NOBLOCK
С каких пор AVR аппаратно поддерживают вложенные прерывания? Эта возможность появилась в более новых МК например с ядром ARM.
У многих из них есть встроенный RTC и внешний не нужен.
Сб сен 29, 2018 18:22:38
Зависит от числа разрядов и количества сегментных портов.
0,016 секунды на всю развертку (~ 62,5 Гц)
при 8 знакоместах и одном сегментном порте 0,016/8 = 0,002 секунды на знакоместо (те же 500 Гц)
Можно конечно еще и "прошимить"...
Но даже такой вариант при правильной смене данных и грамотном распределении ресурсов заметного мерцания не даст.
Как вариант гашение одного из нескольких циклов развертки в уж оччень жестких условиях для процедур, не терпящих прерываний.
Синхронизация с RTC не имеющими программной коррекции точности хода в энергонезавсимом режиме даст гораздо меньшую точность, чем отработка собственного КВАРЦЕВОГО генератора МК, да еще на гораздо более высокой частоте и при программной коррекции точности хода. RTC более как "хранилище опорных данных" во время отключенного состояния устройства использовать полезно.
МУРИК...
Ну не ожидал такого "ляпсуса" насчет вложенных прерываний у АВРок...
Достаточно добавить внутри открытого прерывания команду разрешения (как и у всех типовых МК).
Другой вопрос контроллер приоритетных прерываний как например у MCS51
Сб сен 29, 2018 18:41:55
BOB51 писал(а):Достаточно добавить внутри открытого прерывания команду разрешения
BOB51, я про аппаратную поддержку, а то что вы предлагаете это программная. При некоторых обстоятельствах программно разрешая прерывания можно получить переполнение стека. При аппаратной поддержке прервать текущее прерывание, может только то что имеет больший приоритет чем текущее, которое выполняется. В AVR (ATtiny и ATmega) такого нет.
Сб сен 29, 2018 19:58:16
Мурик писал(а):С каких пор AVR аппаратно поддерживают вложенные прерывания?
И где это Вы в моих словах вычитали что-то про аппаратную поддержку прерывания? Я вроде как всё совсем наоборот сказал.
Сб сен 29, 2018 19:58:32
Зато там нет блокировок, свойственных аппаратным контроллерам - запрет на повторный вызов того же прерывания внутри текущего исполнения. Пресловутое "нельзя выполнить снова, пока хотя бы одна команда после возврата не будет выполнена".
Хотя то конечно ВЕЛИКИЙ ИЗВРАТ не для начинающих.
И не путать ВЛОЖЕННЫЕ ПРЕРЫВАНИЯ
с
АППАРАТНЫМ КОНТРОЛЛЕРОМ ПРИОРИТЕТНЫХ ПРЕРЫВАНИЙ,
тем более, что ни Z80 ни MCS51 "новыми" никак назвать нельзя...
Да и переполнение стека при 32х регистр-акумуляторах и одновременно минимум 64 байтах ОЗУ под стек...
Это уж только ежли некорректности с возвратом из подпрограмм допустить. Надо весьма умудриться...
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.