Страница 1 из 1
Глючит команда lpm ATmega16
Добавлено: Сб июл 12, 2008 20:19:42
AG
Написал программку на asm в AVRStudio 4.14 для ATMega16.
В proteus'e сие творение моделируется без проблем (кроме отображения русских букв на LCD).
Прошил контроллер, заметил также неправильную работу с русскими буквами.
После коваряний стало ясно, что в регистре R0 после команды lpm в любом случае оказывается 0xFF (0b11111111) (выводил результат на экран).
Проверял адрес считывания в регистре - адрес задан верно.
Написал подпрограмму, которая "считывает" (с помощью lpm) память программы и выводит на экран LCD с небольшими интервалами побайтно... На экране гордо красовались 1111 1111.
Из всего это получается, что lpm загружает не то что нужно....
Помогите, может у кого были такие проблемы
Заранее спасибо.
Добавлено: Сб июл 12, 2008 21:02:26
ARV
будьте любезны: разместите прямо на форуме только небольшой участок кода, где вы работаете с LPM - все "лишнее" откиньте... поверьте - искать в большом коде жалдкие 3 строчки - лишние усилия... а помочь, вроде, хочется... да и можется наверняка

Добавлено: Сб июл 12, 2008 21:33:52
AG
Вот к примеру вывод памяти программы на LCD дислей от МЕЛТ, вначале выводится адрес байта программы, затем, то что в нем сидит
Код: Выделить всё
DbgWritePMem:
ldi ZH,0x00
ldi ZL,0x00
Loop_Str:
sbi PortA,1
ldi Counter,100
rcall Delay5ms
mov DATA,ZL
rcall LCDWriteByteNum
ldi Counter,100
rcall Delay5ms
cbi PortA,1
ldi Counter,100
rcall Delay5ms
sbi PortA,0
lpm
mov DATA,R0
rcall LCDWriteByteNum
inc ZL
ldi Counter,100
rcall Delay5ms
cbi PortA,0
cpi ZL,0x1B
brne Loop_Str
ret
Вот команда вывода одного байта памяти на LCD в двоичном коде.
Привожу на всякий случая, хотя проверял ее с константой все работает нормально.
Код: Выделить всё
LCDWriteByteNum:
push DATA
ldi DATA,0xC8
rcall LCDWriteCmd
ldi Counter,8
pop DATA
Loop_LCDWBN:
push DATA
andi DATA,0x80
swap DATA
lsr DATA
lsr DATA
lsr DATA
subi DATA,0xD0
rcall LCDWriteData
pop DATA
lsl DATA
dec Counter
brne Loop_LCDWBN
ret
Добавлено: Сб июл 12, 2008 22:03:56
ARV
во-первых: вы уверены, что все предыдущие команде LPM строки не портят указатель Z?
во-вторых: я вообще не вижу загрузки в указатель Z какого-то осмысленного значения. обычно в программе должно быть нечто типа
а потом где-то еще что-то типа
не наблюдаю такого...
в-третьих: адресация внутри сегмента кода у AVR идет
по словам, т.е. по 2 байта сразу, а адресация LPM - побайтная. поэтому в вышеупомянутом примере правильно было бы писать (если б вы так написали)
Добавлено: Сб июл 12, 2008 23:08:55
AG
1) Полностью уверен.
Вот код процедуры записи на экран LCD (входит в процедуру записи байта на экран в двоичном формате, которую приводил выше), как видно, в ней ZL нигде не участвует
Код: Выделить всё
LCDWriteData:
rcall LCDWait
sbi LCDContPort,A0
rcall LCDWriteByte
ret
LCDWriteByte:
cbi LCDContPort,RW
out LCDDataPort,DATA nop nop nop nop
sbi LCDContPort,E nop nop nop nop
cbi LCDContPort,E nop nop nop nop
ret
2) Осмысленными значения должны быть комманды в двоичной форме
Процедура DbgWritePMem: процедура считывает байт памяти и выводит его на экран LCD. (ВСЕ ЗАДЕРЖКИ, для того чтобы посмотреть байт находящийся в памяти программы удалены, оставил только все самое необходимое), я написал такую процедуру только для того чтобы ПРОВЕРИТЬ работу lpm:
Код: Выделить всё
DbgWritePMem:
//Устанавливаем на начало памяти программы указатель:
ldi ZH,0x00
ldi ZL,0x00
Loop_Str:
//Выводим адрес байта
mov DATA,ZL
rcall LCDWriteByteNum
//Загружаем в регистр R0 содержимое байта
lpm
//Выводим байт хранящийся в памяти
mov DATA,R0
rcall LCDWriteByteNum
//Увеличиваем значение указателя на единичку (переходим на следующий байт)
inc ZL
//Если ZL не равен 0x1B, то возвращаемся в начало цикла
cpi ZL,0x1B
brne Loop_Str
ret
То что действительно должно храниться в памяти программы проверял в протеусе, а также сравнил протеус с .hex файлом.
Однако на LCD были только 11111111
3) Я знаю про, то что команда занимает одно слово, а не байт, но в любом случае, если бы я попадал не на то значение в памяти, врядли такое может быть, что lpm ВСЕГДА возвращала 0xFF или 0b11111111.
Добавлено: Сб июл 12, 2008 23:29:58
ARV
вообще-то LPM работает, как часы - сами понимаете

а вот что у вас не так - непонятно. выходит,
выводит 0, а следующий после LPM вывод - уже все единички?
Добавлено: Вс июл 13, 2008 00:23:53
AG
Я понимаю, что lpm обязан работать как часы
Я извиняюсь, но я неправильно выразился про все 1.
На LCD вначале выводится адрес байта, то есть вначале:
0000 0000
Потом (должен быть вывод байта хранящегося в памяти программы), однако на экране:
1111 1111
Далее
0000 0001
За ним
1111 1111
И т.д.
....Может, что с чипом случилось.... но вроде я его не сильно не мучил...
И еще, вначале в программе была записана команда lpm следующим образом:
lpm DATA,Z (то есть сразу загрузить в DATA по адресу Z из памяти программы)
Когда я понял, что проблемы начинаются имено после lpm.
Заменил следующим образом:
lpm
mov DATA,R0
Я даже вначале обадывался - все заработало, но убрав команды которые использовал для поиска неисправности (типа включения светодиода) и заново перепрошив контроллер - все сново перестало работать. Обратно поменяв на lpm DATA,Z результато не дало...
Прошиваю STK200 с помощью программы AVReal.
Возможны такие глюки из не правильно прошитых фьюзов?
Вот содержание батника:
E:\AVReal\avreal32.exe +mega16 -%% -p1 -as -o0 -ew G:\Projects\AVRStudio\LCD-Controller\LCD-Controller.hex -n
pause=null
Извините, что сразу не привел все "историю болезни", думал может "вылечат"....
Добавлено: Вс июл 13, 2008 13:35:29
mrFox
если хочешь проверить - возьми WinAVR
и воспользуйся например strcpy_P, strncpy_P
они выводят строку в буфер и выведи на дисплей
сразу станет ясно, что глючит МК или руки
выриант 2 - покупаешь новую мегу ...
PS
и сделай полную таблицу прерываний
а то ты выставляешь бит TWIE
и если включишь прерывание то

Добавлено: Вс июл 13, 2008 13:57:30
AG
Я тоже думаю съездить купить новую мегу, и попробую небольшой отрезок кода на CAVR написать и посмотреть, что будет, но это позже.
Что интересно... с утра включил это чудо устройство... не чего не менял в коде=)... прошил... и все заработало... чудеса!
А вообще мега могла начать глючить от того, что к примеру, порт на котором установлен высокий уровень замкнуть на землю?
PS: A TWEI забыл убрать ), хотел в начале делать с прерываниями.
Добавлено: Пн июл 14, 2008 00:32:07
mrFox
AG
А вообще мега могла начать глючить от того, что к примеру, порт на котором установлен высокий уровень замкнуть на землю?
врядли - у меня в такой ситуации mega32 пробыла более 5 минут без каких-либо последствий - в таком режиме ножка скорее всего будет стабилизатором тока
а вот статикой mega32 убилась - слегка щелкнуло и усе
а FT232 оказалось не любит переплюсовки питания
