Значит какое-то из прерываний работает без вашего ведома (ну или вы о нем забыли или забыли его запретить), не могу вас заставлять, но хотелось, чтобы вы нашли первопричину.poff писал(а):to smac. Прописал полностью таблицу прерываний и все заработало!!! Огромное спасибо всем соучасникам. Постараюсь в предь не вести себя по козлиному и тоже делиться тем чего знаю. А то иногда и знаешь как проблема решается, но по клаве стычать облом. Всех поздравляю...
Ассемблер (ASM) для AVR в вопросах и ответах
- Реклама
- GRafGRay
- Прорезались зубы
- Сообщения: 223
- Зарегистрирован: Вт окт 02, 2007 14:43:23
- Откуда: Ростов-на-Дону
- Контактная информация:
имею спросить вопрос:
имеется программа (в процессе разработки)
в программе использую прерывание таймера компаратора - 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сек, но думаю это не есть правильно.
При наличии отсутствия пропитанных шпал - это будет не трамвай а одно горе!
GRafGRay писал(а):имею спросить вопрос:
имеется программа (в процессе разработки)
в программе использую прерывание таймера компаратора - 1 раз в секунду, прогрмма работает 2 минуты и 7 секунд, после чего происходит сбой, и начинает отсчёт заново - загружает начальные значения и т.д. в чём может быть причина?
дело в том что перед тем как писать обработчик прерываний, тупо использовал цикл задержки что-то типа
ldi counter,100
delay:
dec counter
brne delay
и всё работало. Понимаю что можно было расчитать значение counter, максимально приблизив время работы цикла к 1сек, но думаю это не есть правильно.
Ну вы хотя бы контроллер какой сказали, и исходник весь привели, чтобы не гадать.
Пока, опираясь только на телепатию могу предположить две причины
1-WDT (очень маловероятно, ибо период большой. но лучше проверить)
2. Не заполнена таблица прерываний (см. неск. предыдущих постов), и по какой-то причине вызваентся прерывание, которое не описано в таблице.
- GRafGRay
- Прорезались зубы
- Сообщения: 223
- Зарегистрирован: Вт окт 02, 2007 14:43:23
- Откуда: Ростов-на-Дону
- Контактная информация:
исходник прикладываю
контроллер Мега8
1. Сторожевой таймер? я в программе его вроде не трогал, или он на то и сторожевой чтоб нежданно срабатывать?
2. Если не заполнена таблица, тогда почему не используя прерывание сбоя не происходит (разрешение на прерывания включено в любом случае)
контроллер Мега8
1. Сторожевой таймер? я в программе его вроде не трогал, или он на то и сторожевой чтоб нежданно срабатывать?
2. Если не заполнена таблица, тогда почему не используя прерывание сбоя не происходит (разрешение на прерывания включено в любом случае)
- Вложения
-
- prog.txt
- (6.35 КБ) 453 скачивания
При наличии отсутствия пропитанных шпал - это будет не трамвай а одно горе!
1. Сторожевой таймер можно настроить фьюзами.GRafGRay писал(а):исходник прикладываю
контроллер Мега8
1. Сторожевой таймер? я в программе его вроде не трогал, или он на то и сторожевой чтоб нежданно срабатывать?![]()
2. Если не заполнена таблица, тогда почему не используя прерывание сбоя не происходит (разрешение на прерывания включено в любом случае)
2. Этого вы не говорили в предыдущем посте.
Прикрепляю просмотренный мной исходник с комментариями, замечаниями и найденными ошибками.
Замечания отмаркированы **, строчки, на которые нужно обратить внимание WW (warning), ошибки -- EE
П. С. Обработчик прерывания никуда не годится.
- Вложения
-
- prog1.txt
- обратите внимание на **, WW, EE
- (7.77 КБ) 487 скачиваний
- Реклама
-
YurkaM
- Нашел транзистор. Понюхал.
- Сообщения: 151
- Зарегистрирован: Пн сен 01, 2008 14:49:03
- Откуда: Казахстан
Ты забыл сохранить регистр SREG в обработчике прерывания таймера.
Там же флаги портятся.. Может - в этом причина.
Войдя в прерывание, сохраняем (хоть в регистре каком, хоть в стек запихать), перед выходом - восстанавливаем.
Упс... опоздал. smac всё подробней расписал.
Да, щас вчитался в обработчик прерывания - так не годится совершенно...
Основная ошибка конечно выход из обработчика прерывания по rjmp.
Это хорошо, что прога не сильно сложная - поэтому она хоть 2 минуты пытается работать с такой абра-кадаброй.. А потом просто переполняется стек.
Всё остальное, отмеченное smac, правильно, но не смертельно..
Там же флаги портятся.. Может - в этом причина.
Войдя в прерывание, сохраняем (хоть в регистре каком, хоть в стек запихать), перед выходом - восстанавливаем.
Упс... опоздал. smac всё подробней расписал.
Да, щас вчитался в обработчик прерывания - так не годится совершенно...
Основная ошибка конечно выход из обработчика прерывания по rjmp.
Это хорошо, что прога не сильно сложная - поэтому она хоть 2 минуты пытается работать с такой абра-кадаброй.. А потом просто переполняется стек.
Всё остальное, отмеченное smac, правильно, но не смертельно..
- GRafGRay
- Прорезались зубы
- Сообщения: 223
- Зарегистрирован: Вт окт 02, 2007 14:43:23
- Откуда: Ростов-на-Дону
- Контактная информация:
В продолжение вопроса
к меге 8 прикручена матричеая клава на порт С
2 линии на РС0 и РС1
3 столбца, резисторами по 300 Ом на + питания, и на порт РС2-4
пробовал код из обучалки (проверял на тини всё работает) АВР студио его кушает, а в реале кнопочки не реагируют
если я правильно понимаю, в программе мы поочередно включаем линии и читаем состояние столбцов?
пробовал втыкать в цикле индикации - не фурычит, попробовал вынести в отдельную подпрограмму:
кусок моей программы
Reset:
.................
ldi Temp,0b01111100 ; PC0, PC1 - входы, остальные выходы
out DDRC,Temp ;
..................
IndicCycle:
rcall Display ; подпрограмма индикации
rcall ButtonClick ; подпрограмма проверки клавиатуры
rjmp IndicCycle
;*******************
в основной программе
ButtonClick:
L1B1: ; блок проверки первой кнопки
ldi Temp,0b00000001 ; подтяжка на PC0
out PortC,Temp
sbic PinC,2 ; кнопка L1B1 нажата?
rjmp L1B2 ; нет - проверяем следующую кнопку
ldi Temp,0b00100001 ; да - PC5 - зажигаем светодиод
out PortC,Temp ;
L1B2:
.............
ret
где я облажался?
к меге 8 прикручена матричеая клава на порт С
2 линии на РС0 и РС1
3 столбца, резисторами по 300 Ом на + питания, и на порт РС2-4
пробовал код из обучалки (проверял на тини всё работает) АВР студио его кушает, а в реале кнопочки не реагируют
если я правильно понимаю, в программе мы поочередно включаем линии и читаем состояние столбцов?
пробовал втыкать в цикле индикации - не фурычит, попробовал вынести в отдельную подпрограмму:
кусок моей программы
Reset:
.................
ldi Temp,0b01111100 ; PC0, PC1 - входы, остальные выходы
out DDRC,Temp ;
..................
IndicCycle:
rcall Display ; подпрограмма индикации
rcall ButtonClick ; подпрограмма проверки клавиатуры
rjmp IndicCycle
;*******************
в основной программе
ButtonClick:
L1B1: ; блок проверки первой кнопки
ldi Temp,0b00000001 ; подтяжка на PC0
out PortC,Temp
sbic PinC,2 ; кнопка L1B1 нажата?
rjmp L1B2 ; нет - проверяем следующую кнопку
ldi Temp,0b00100001 ; да - PC5 - зажигаем светодиод
out PortC,Temp ;
L1B2:
.............
ret
где я облажался?
При наличии отсутствия пропитанных шпал - это будет не трамвай а одно горе!
-
BerZerK-ku
- Мучитель микросхем
- Сообщения: 492
- Зарегистрирован: Вт июл 22, 2008 08:10:54
Че-то непонятно у вас. Вы управляете входами и сканируете выходы? Вы определили PC0, PC1 как входы, остальные пины - как выходы.
При этом записываете занчение в PC0 и PC1, и проверяете состояние на PC2-PC4. При этом у вас в PC2-PC4 всегда пишутся 0 .
При таком раскладе у вас ничего и не будет работать 
Код: Выделить всё
ldi Temp,0b01111100 ; PC0, PC1 - входы, остальные выходы
out DDRC,Temp ;
Код: Выделить всё
ldi Temp,0b00000001 ; подтяжка на PC0
out PortC,Temp
- Neekeetos
- Держит паяльник хвостом
- Сообщения: 993
- Зарегистрирован: Пн сен 18, 2006 11:16:05
- Откуда: Тула
- Контактная информация:
В винде есть программа hyperterminal, ее используй, в ней есть сохранялка. Только вот я не уверен что она на бэйсике написана.Satsuk писал(а):Друзья, помогите найти, какую-нибудь программку (желательно написаную на Вижул Бейсике), которая будет принимать мой код(через РS-232) из АВРа и куда-то складывать его. Может кто-нибудь сам может такое написать?
У меня по прерыванию считывается лог.уровень с одного пина порта "С" (мега8 ) нужно что бы значения от восеми прерываний сложились в регистр (ну R16 например), что бы получился байт.
помогите выразить это в командах асемблера
как то нужно наверное что бы первый бит помещался в регистр, затем по второму прерыванию этот бит перемещался влево, а его место занимал считанный, далее по третьему прерыванию снова смещение уже этих двух битов влево и запись считанного...
как наберется 8 бит, я это вывожу в USART
помогите выразить это в командах асемблера
как то нужно наверное что бы первый бит помещался в регистр, затем по второму прерыванию этот бит перемещался влево, а его место занимал считанный, далее по третьему прерыванию снова смещение уже этих двух битов влево и запись считанного...
как наберется 8 бит, я это вывожу в USART
-
bondpashtet
- Родился
- Сообщения: 1
- Зарегистрирован: Пн янв 05, 2009 14:48:24
- Откуда: южноукрайнск
- Контактная информация:
rjmp RESET
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
rjmp USART_RXC
reti
reti
reti
reti
reti
reti
reti
в подпрограме USART_RXC пусто:
Код:
USART_RXC:
reti
и ещё вопрос: можно ли в одной подпрограме использовать несколько ret или reti ?
А ты же забыл про <sp>registor steka
ldi temp,high(RAMEND)
out SPH,temp
ldi temp,low(RAMEND)
out SPL,temp
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
rjmp USART_RXC
reti
reti
reti
reti
reti
reti
reti
в подпрограме USART_RXC пусто:
Код:
USART_RXC:
reti
и ещё вопрос: можно ли в одной подпрограме использовать несколько ret или reti ?
А ты же забыл про <sp>registor steka
ldi temp,high(RAMEND)
out SPH,temp
ldi temp,low(RAMEND)
out SPL,temp
Как в асме организовать смещение влево при записи в ОЗУ?
у меня пишется циклом с инкрементом по байту, начиная с адреса ОЗУ 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
у меня пишется циклом с инкрементом по байту, начиная с адреса ОЗУ 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
-
YurkaM
- Нашел транзистор. Понюхал.
- Сообщения: 151
- Зарегистрирован: Пн сен 01, 2008 14:49:03
- Откуда: Казахстан
Например, так.
Наверно, можно и лучше, но в отрыве от остальной задачи трудно сообразить для чего это и как оптимизировать... Вообще содержимое буфера как правило не двигают, а двигают только указатели
Код: Выделить всё
_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й... эта команда снова сохранит в первый адрес куда сдвинулся второй байт, а не на место шестого...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 ;возвращаемся на инициализацию указателей и счётчика
сдвигать в буфере мне нужно, т.к. данные последовательно приходят по одному байту, и мне так и нужно что бы они в такой же последовательности и стояли.
тогда мне кажеться что на выходе из цикла мы будем иметь Y указывающий на 5й байт, ведь именно в него в последний раз сохраняли, а потом вышли из цикла без инкременирования Y.YurkaM писал(а):Ну дык цикл повторяется 5 раз и с каждым разом Y увеличивается на 1 (st Y+,R16 ;ложим в [Y], увеличиваем Y на 1). По выходу из цикла как раз имеем Y указывающий на адрес 6-го байта.
тогда, нужно после цикла и получения данных написать Y+ а не просто Y
...
Ответил уже тебе, а потом посмотрел повнимательнее -ты тоже указал Y+ в ответе, а в первом варианте кода просто Y стоит- забыл наверное допечатать "+".
-
YurkaM
- Нашел транзистор. Понюхал.
- Сообщения: 151
- Зарегистрирован: Пн сен 01, 2008 14:49:03
- Откуда: Казахстан
Нет, указывать будет именно на 6-ой.Alexeus писал(а): тогда мне кажеться что на выходе из цикла мы будем иметь Y указывающий на 5й байт, ведь именно в него в последний раз сохраняли, а потом вышли из цикла без инкременирования Y.
st Y+, Rn - по этой команде Rn ложится в Y и только потом делается Y+1. Так что с каждым проходом Y увеличивается на 1 в конце, уже после того как перекинули байт....а потом вышли из цикла без инкременирования Y
зы
Может тебя сбивает с толку эта строка: 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 раза.


