#assembly #atmega #atmega16
#сборка #atmega #atmega16
Вопрос:
Я пытаюсь написать некоторый код для ATmega16. Я использую avra (версия 1.4.2) под FreeBSD 12.2-RELEASE. В моем сегменте кода у меня есть следующее:
helloStr: .db "Hello World"
Насколько я понимаю, байты символов должны быть непрерывными.
Однако, когда я смотрю на созданный объектный файл, я вижу следующее (я собираю код с помощью команды avra main.asm):
00000190: 0000 3600 0000 2a65 4800 0039 0000 002b ..6...*eH..9...
000001a0: 6c6c 0000 3900 0000 2c20 6f00 0039 0000 ll..9..., o..9..
000001b0: 002d 6f57 0000 3900 0000 2e6c 7200 0039 .-oW..9....lr..9
000001c0: 0000 002f 5c64 0000 3900 0000 3000 3000 .../d..9...0.0.
000001d0: 0039 0000 0031 e2fa 0000 3d00 0000 32e0 .9...1....=...2.
Обратите внимание справа, что символы не являются последовательными.
Я смотрю на файл .obj, который создает avra.
Когда я пытаюсь запустить код, он, похоже, подтверждает мои предположения о том, что символьные байты не хранятся последовательно, поскольку я получаю в основном мусор на дисплее с некоторыми правильными символами, но разнесенными слишком далеко друг от друга.
Я не думаю, что что-то не так с моей процедурой отображения (код ЖК-дисплея будет отображать символ правильно, если я удалю код цикла и сохраню символ непосредственно в r16, используя ldi r16, ‘H’, например.):
WRITE_TO_LCD:
push r16
push r17
START_WRITE_TO_LCD:
lpm r16, Z
ldi r17, 0b0
cp r16, r17 ; Have we hit the null byte?
breq END_WRITE_TO_LCD
;; Output character command.
out PortA, r16
ldi r16, low(registerSelect) ; Set RS control signal
out PortC, r16
;; Set E and RS control siginals.
ldi r16, (low(registerSelect) | low(enable))
out PortC, r16
ldi r16, low(registerSelect) ; Clear E control signal
out PortC, r16
jmp START_WRITE_TO_LCD
END_WRITE_TO_LCD:
pop r17
pop r16
ret
Я загружаю Z с:
ldi r31, low(helloStr)
ldi r30, high(helloStr)
прежде чем я вызову WRITE_TO_LCD . Я не уверен, что низкий уровень до r31 и высокий до r30 — это правильный путь, но я также пробовал другой способ. Я также читал, что память адресуется с использованием 2-байтовых слов, поэтому я должен использовать 2 * helloStr. Я тоже пытался это сделать. Возможно, эти детали, которые я только что упомянул, неверны в коде, который я показал здесь, но я перепробовал все перестановки, и я не думаю, что это проблема (о чем свидетельствует вывод, выведенный на ЖК-дисплей, и то, что я вижу в шестнадцатеричном редакторе).
Также у меня есть define helloStr после моего вектора прерывания. Если я помещу ее перед вектором прерывания, я, похоже, не вижу никаких доказательств этого в файле .obj, и вывод на ЖК-дисплей отличается, когда я его запускаю. Я предполагаю, что это как-то связано с тем, что вектор прерывания должен быть первым в памяти или что-то в этом роде. Но я бы подумал, что это все равно появилось бы в коде, и обработка прерываний была бы испорчена.
В любом случае, что меня действительно интересует, так это получение непрерывной строки во flash, чтобы я мог перебирать ее в цикле.
Если у кого-нибудь есть какие-либо идеи, что я могу делать неправильно, я был бы очень признателен за ваш вклад.
Комментарии:
1. По-видимому, это особенность формата объектного файла. Я просто помещаю вашу строку в файл самостоятельно и вижу то же самое. Однако avra сообщает «Код: 7 слов (14 байт)» , что верно, и
hex
файл также правильный. Как вы создаете окончательное изображение? Вы заглядывали внутрь этого с помощью шестнадцатеричного редактора?2. Когда я запускаю команду avra main.asm, она создает следующие файлы: main.eep.hex, main.hex и main.obj. Я записываю main.hex в микро, используя avrdude. Причина, по которой я не просматривал шестнадцатеричный файл, заключается в том, что это ascii-представление шестнадцатеричного кода, и сложнее понять, что происходит с точки зрения строки. Я думаю, теперь, когда я думаю об этом, не должно потребоваться слишком много времени, чтобы проверить это таким образом. Однако в моем коде все еще должно быть что-то не так:'(ха-ха. Также спасибо за ваш ответ.
3. Да, вы должны использовать
2*helloStr
и убедитесь, что вы ввели младший байтr30
(ваш код перевернут).4. Ваше право. Я не имею в виду, что я вам не поверил. Я просто вложил это в этот удобный прицел: binaryhexconverter.com/hex-to-ascii-text-converter Я предполагаю, что тогда должно быть что-то не так с тем, как я обращаюсь к строке. Я потратил немало времени, пытаясь заставить ее работать. Так что я не совсем уверен, в чем может быть проблема.
5. Это исправило это! Большое спасибо. Я чувствую себя глупо, ха-ха. Клянусь, я пробовал это. Тем не менее, в коде, который я опубликовал, все еще есть пара ошибок. Похоже, что после установки enable требуется некоторое количество nop (я использую micro на частоте 1 МГц, а ЖК-дисплей — 1602A), а также я не думаю, что ассемблер превращает в нулевой байт. В любом случае это работает :).