to smac. Прописал полностью таблицу прерываний и все заработало!!! Огромное спасибо всем соучасникам. Постараюсь в предь не вести себя по козлиному и тоже делиться тем чего знаю. А то иногда и знаешь как проблема решается, но по клаве стычать облом. Всех поздравляю...
Значит какое-то из прерываний работает без вашего ведома (ну или вы о нем забыли или забыли его запретить), не могу вас заставлять, но хотелось, чтобы вы нашли первопричину.
имею спросить вопрос:
имеется программа (в процессе разработки)
в программе использую прерывание таймера компаратора - 1 раз в секунду, прогрмма работает 2 минуты и 7 секунд, после чего происходит сбой, и начинает отсчёт заново - загружает начальные значения и т.д. в чём может быть причина?
дело в том что перед тем как писать обработчик прерываний, тупо использовал цикл задержки что-то типа
ldi counter,100
delay:
dec counter
brne delay
и всё работало. Понимаю что можно было расчитать значение counter, максимально приблизив время работы цикла к 1сек, но думаю это не есть правильно.
_________________ При наличии отсутствия пропитанных шпал - это будет не трамвай а одно горе!
имею спросить вопрос: имеется программа (в процессе разработки) в программе использую прерывание таймера компаратора - 1 раз в секунду, прогрмма работает 2 минуты и 7 секунд, после чего происходит сбой, и начинает отсчёт заново - загружает начальные значения и т.д. в чём может быть причина?
дело в том что перед тем как писать обработчик прерываний, тупо использовал цикл задержки что-то типа
ldi counter,100 delay: dec counter brne delay
и всё работало. Понимаю что можно было расчитать значение counter, максимально приблизив время работы цикла к 1сек, но думаю это не есть правильно.
Ну вы хотя бы контроллер какой сказали, и исходник весь привели, чтобы не гадать.
Пока, опираясь только на телепатию могу предположить две причины
1-WDT (очень маловероятно, ибо период большой. но лучше проверить)
2. Не заполнена таблица прерываний (см. неск. предыдущих постов), и по какой-то причине вызваентся прерывание, которое не описано в таблице.
1. Сторожевой таймер? я в программе его вроде не трогал, или он на то и сторожевой чтоб нежданно срабатывать?
2. Если не заполнена таблица, тогда почему не используя прерывание сбоя не происходит (разрешение на прерывания включено в любом случае)
1. Сторожевой таймер можно настроить фьюзами.
2. Этого вы не говорили в предыдущем посте.
Прикрепляю просмотренный мной исходник с комментариями, замечаниями и найденными ошибками.
Замечания отмаркированы **, строчки, на которые нужно обратить внимание WW (warning), ошибки -- EE
П. С. Обработчик прерывания никуда не годится.
Вложения:
Комментарий к файлу: обратите внимание на **, WW, EE prog1.txt [7.77 KiB]
Скачиваний: 439
Карма: 1
Рейтинг сообщений: 3
Зарегистрирован: Пн сен 01, 2008 14:49:03 Сообщений: 151 Откуда: Казахстан
Рейтинг сообщения:0
Ты забыл сохранить регистр SREG в обработчике прерывания таймера.
Там же флаги портятся.. Может - в этом причина.
Войдя в прерывание, сохраняем (хоть в регистре каком, хоть в стек запихать), перед выходом - восстанавливаем.
Упс... опоздал. smac всё подробней расписал.
Да, щас вчитался в обработчик прерывания - так не годится совершенно...
Основная ошибка конечно выход из обработчика прерывания по rjmp.
Это хорошо, что прога не сильно сложная - поэтому она хоть 2 минуты пытается работать с такой абра-кадаброй.. А потом просто переполняется стек.
Всё остальное, отмеченное smac, правильно, но не смертельно..
В продолжение вопроса
к меге 8 прикручена матричеая клава на порт С
2 линии на РС0 и РС1
3 столбца, резисторами по 300 Ом на + питания, и на порт РС2-4
пробовал код из обучалки (проверял на тини всё работает) АВР студио его кушает, а в реале кнопочки не реагируют
если я правильно понимаю, в программе мы поочередно включаем линии и читаем состояние столбцов?
пробовал втыкать в цикле индикации - не фурычит, попробовал вынести в отдельную подпрограмму:
ldi Temp,0b00000001
я кроме подтяжки РС0 отключал остальные выводы порта
а если использовать команду
sbi PortC,0
а при переходе на другую линию отключать cbi PortC,0 дело поправится? или я опять не в ту сторону думаю?
_________________ При наличии отсутствия пропитанных шпал - это будет не трамвай а одно горе!
Друзья, помогите найти, какую-нибудь программку (желательно написаную на Вижул Бейсике), которая будет принимать мой код(через РS-232) из АВРа и куда-то складывать его. Может кто-нибудь сам может такое написать?
Друзья, помогите найти, какую-нибудь программку (желательно написаную на Вижул Бейсике), которая будет принимать мой код(через РS-232) из АВРа и куда-то складывать его. Может кто-нибудь сам может такое написать?
В винде есть программа hyperterminal, ее используй, в ней есть сохранялка. Только вот я не уверен что она на бэйсике написана.
Зарегистрирован: Вс мар 04, 2007 01:17:12 Сообщений: 690
Рейтинг сообщения:0
У меня по прерыванию считывается лог.уровень с одного пина порта "С" (мега8 ) нужно что бы значения от восеми прерываний сложились в регистр (ну R16 например), что бы получился байт.
помогите выразить это в командах асемблера
как то нужно наверное что бы первый бит помещался в регистр, затем по второму прерыванию этот бит перемещался влево, а его место занимал считанный, далее по третьему прерыванию снова смещение уже этих двух битов влево и запись считанного...
Зарегистрирован: Вс мар 04, 2007 01:17:12 Сообщений: 690
Рейтинг сообщения:0
Как в асме организовать смещение влево при записи в ОЗУ?
у меня пишется циклом с инкрементом по байту, начиная с адреса ОЗУ 0х200, стоит счетчик на ораничение записи в 6 байт- потом обнуляю регистровую пару с адресом ОЗУ и запись снова начинается с адреса 0х200.
А нужно, что бы по достижению 6го байта все данные смещались влево и следующий байт писался на место 6го и так циклично...
кто знает- подскажите пожалуйста.
сейчас что то вроде этого:
Obnulenie:
ldi YL,0x00
ldi YH,0x02
ldi R17,0
Write_in_RAM:
st Y+,R16
inc R17
cpi R17,6
breq Obnulenie
.... тут иду на получение новых данных
jmp Write_in_RAM
Карма: 1
Рейтинг сообщений: 3
Зарегистрирован: Пн сен 01, 2008 14:49:03 Сообщений: 151 Откуда: Казахстан
Рейтинг сообщения:0
Например, так.
Код:
_Obnulenie: ldi YL,0x00 ldi YH,0x02 ldi R17,5
_Sdvig: ldd R16,Y+1 ;берём из ячейки [Y+1] st Y+,R16 ;ложим в [Y], увеличиваем Y на 1 dec R17 ;уменьшаем счетчик brene _Sdvig ;если не ноль, то повторяем .... тут иду на получение новых данных st Y,R16 ;ложим данные на место 6-го байта rjmp _Obnulenie ;возвращаемся на инициализацию указателей и счётчика
Наверно, можно и лучше, но в отрыве от остальной задачи трудно сообразить для чего это и как оптимизировать... Вообще содержимое буфера как правило не двигают, а двигают только указатели
Зарегистрирован: Вс мар 04, 2007 01:17:12 Сообщений: 690
Рейтинг сообщения:0
YurkaM писал(а):
Например, так.
Код:
_Obnulenie: ldi YL,0x00 ldi YH,0x02 ldi R17,5
_Sdvig: ldd R16,Y+1 ;берём из ячейки [Y+1] st Y+,R16 ;ложим в [Y], увеличиваем Y на 1 dec R17 ;уменьшаем счетчик brene _Sdvig ;если не ноль, то повторяем .... тут иду на получение новых данных st Y,R16 ;ложим данные на место 6-го байта rjmp _Obnulenie ;возвращаемся на инициализацию указателей и счётчика
Вообще содержимое буфера как правило не двигают, а двигают только указатели
вот тут не понял: "st Y,R16" этож после цикла где 2 байт на 1й накладывается, 3й на 2й... эта команда снова сохранит в первый адрес куда сдвинулся второй байт, а не на место шестого...
сдвигать в буфере мне нужно, т.к. данные последовательно приходят по одному байту, и мне так и нужно что бы они в такой же последовательности и стояли.
Карма: 1
Рейтинг сообщений: 3
Зарегистрирован: Пн сен 01, 2008 14:49:03 Сообщений: 151 Откуда: Казахстан
Рейтинг сообщения:0
Ну дык цикл повторяется 5 раз и с каждым разом Y увеличивается на 1 (st Y+,R16 ;ложим в [Y], увеличиваем Y на 1). По выходу из цикла как раз имеем Y указывающий на адрес 6-го байта.
Ну и конечно это место ".... тут иду на получение новых данных" не должно портить Y.
Зарегистрирован: Вс мар 04, 2007 01:17:12 Сообщений: 690
Рейтинг сообщения:0
YurkaM писал(а):
Ну дык цикл повторяется 5 раз и с каждым разом Y увеличивается на 1 (st Y+,R16 ;ложим в [Y], увеличиваем Y на 1). По выходу из цикла как раз имеем Y указывающий на адрес 6-го байта.
тогда мне кажеться что на выходе из цикла мы будем иметь Y указывающий на 5й байт, ведь именно в него в последний раз сохраняли, а потом вышли из цикла без инкременирования Y.
тогда, нужно после цикла и получения данных написать Y+ а не просто Y
...
Ответил уже тебе, а потом посмотрел повнимательнее -ты тоже указал Y+ в ответе, а в первом варианте кода просто Y стоит- забыл наверное допечатать "+".
Карма: 1
Рейтинг сообщений: 3
Зарегистрирован: Пн сен 01, 2008 14:49:03 Сообщений: 151 Откуда: Казахстан
Рейтинг сообщения:0
Alexeus писал(а):
тогда мне кажеться что на выходе из цикла мы будем иметь Y указывающий на 5й байт, ведь именно в него в последний раз сохраняли, а потом вышли из цикла без инкременирования Y.
Нет, указывать будет именно на 6-ой.
Цитата:
...а потом вышли из цикла без инкременирования Y
st Y+, Rn - по этой команде Rn ложится в Y и только потом делается Y+1. Так что с каждым проходом Y увеличивается на 1 в конце, уже после того как перекинули байт.
зы
Может тебя сбивает с толку эта строка: ldd R16,Y+1 ;берём из ячейки [Y+1] ?
Команда ldd Rn,Y+1 - ложит Rn в адрес [Y+1], при этом НЕ ИЗМЕНЯЕТ Y!
зы2
Тьфу блин, чуть перепутал, вот так правильно:
Команда ldd Rn,Y+1 - берёт из адреса [Y+1] и ложит в Rn , при этом НЕ ИЗМЕНЯЕТ Y!
Последний раз редактировалось YurkaM Пт янв 23, 2009 11:32:02, всего редактировалось 2 раз(а).
Сейчас этот форум просматривают: kot-69 и гости: 15
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения