Глючит команда lpm ATmega16

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
AG
Родился
Аватара пользователя
Сообщения: 15
Зарегистрирован: Вт июл 01, 2008 16:49:30
Откуда: Москва

Сообщение AG »

Написал программку на asm в AVRStudio 4.14 для ATMega16.

В proteus'e сие творение моделируется без проблем (кроме отображения русских букв на LCD).

Прошил контроллер, заметил также неправильную работу с русскими буквами.

После коваряний стало ясно, что в регистре R0 после команды lpm в любом случае оказывается 0xFF (0b11111111) (выводил результат на экран).

Проверял адрес считывания в регистре - адрес задан верно.

Написал подпрограмму, которая "считывает" (с помощью lpm) память программы и выводит на экран LCD с небольшими интервалами побайтно... На экране гордо красовались 1111 1111.

Из всего это получается, что lpm загружает не то что нужно....

Помогите, может у кого были такие проблемы

Заранее спасибо.
Вложения
LCD-Controller.asm
(15.38 КБ) 408 скачиваний
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18786
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

будьте любезны: разместите прямо на форуме только небольшой участок кода, где вы работаете с LPM - все "лишнее" откиньте... поверьте - искать в большом коде жалдкие 3 строчки - лишние усилия... а помочь, вроде, хочется... да и можется наверняка :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
AG
Родился
Аватара пользователя
Сообщения: 15
Зарегистрирован: Вт июл 01, 2008 16:49:30
Откуда: Москва

Сообщение 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
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18786
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

во-первых: вы уверены, что все предыдущие команде LPM строки не портят указатель Z?
во-вторых: я вообще не вижу загрузки в указатель Z какого-то осмысленного значения. обычно в программе должно быть нечто типа

Код: Выделить всё

str:   .db   'кукареку',0
а потом где-то еще что-то типа

Код: Выделить всё

ldi ZL, low(str)
ldi ZH, high(str)
не наблюдаю такого...
в-третьих: адресация внутри сегмента кода у AVR идет по словам, т.е. по 2 байта сразу, а адресация LPM - побайтная. поэтому в вышеупомянутом примере правильно было бы писать (если б вы так написали)

Код: Выделить всё

ldi ZL, low(str*2)
ldi ZH, high(str*2)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
AG
Родился
Аватара пользователя
Сообщения: 15
Зарегистрирован: Вт июл 01, 2008 16:49:30
Откуда: Москва

Сообщение 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.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18786
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

вообще-то LPM работает, как часы - сами понимаете :) а вот что у вас не так - непонятно. выходит,

Код: Выделить всё

      mov      DATA,ZL 
      rcall   LCDWriteByteNum 
выводит 0, а следующий после LPM вывод - уже все единички?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
AG
Родился
Аватара пользователя
Сообщения: 15
Зарегистрирован: Вт июл 01, 2008 16:49:30
Откуда: Москва

Сообщение 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

Извините, что сразу не привел все "историю болезни", думал может "вылечат"....
Нашел транзистор. Понюхал.
Сообщения: 190
Зарегистрирован: Пт сен 21, 2007 17:53:23
Откуда: Зарайск

Сообщение mrFox »

если хочешь проверить - возьми WinAVR
и воспользуйся например strcpy_P, strncpy_P
они выводят строку в буфер и выведи на дисплей
сразу станет ясно, что глючит МК или руки

выриант 2 - покупаешь новую мегу ...

PS
и сделай полную таблицу прерываний
а то ты выставляешь бит TWIE
и если включишь прерывание то :)))
AG
Родился
Аватара пользователя
Сообщения: 15
Зарегистрирован: Вт июл 01, 2008 16:49:30
Откуда: Москва

Сообщение AG »

Я тоже думаю съездить купить новую мегу, и попробую небольшой отрезок кода на CAVR написать и посмотреть, что будет, но это позже.

Что интересно... с утра включил это чудо устройство... не чего не менял в коде=)... прошил... и все заработало... чудеса!

А вообще мега могла начать глючить от того, что к примеру, порт на котором установлен высокий уровень замкнуть на землю?

PS: A TWEI забыл убрать ), хотел в начале делать с прерываниями.
Нашел транзистор. Понюхал.
Сообщения: 190
Зарегистрирован: Пт сен 21, 2007 17:53:23
Откуда: Зарайск

Сообщение mrFox »

AG
А вообще мега могла начать глючить от того, что к примеру, порт на котором установлен высокий уровень замкнуть на землю?

врядли - у меня в такой ситуации mega32 пробыла более 5 минут без каких-либо последствий - в таком режиме ножка скорее всего будет стабилизатором тока
а вот статикой mega32 убилась - слегка щелкнуло и усе :(
а FT232 оказалось не любит переплюсовки питания :?
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»