Jump to content
skef

Команда Lpm

Recommended Posts

память в большинстве AVR 16-разрядная, при косвенной адресации мы адресуемся к слову (2 байта), команда lpm выгружает один байт в r0, вопрос в том можно ли и как адресоваться ко второму байту?

Share this post


Link to post
Share on other sites

LPM - у этой команды самый нижний бит определяет байт - при 0 берёт нижний байт, при 1 верхний байт. Адрес должен быть удлжен в регистре Z.

Share this post


Link to post
Share on other sites

ldi ZH, high(Table*2)

ldi ZL, low(Table*2)

=========================

lpm temp, Z

=========================

table:

.dw 0b1100110011111111

т.е если указан 0, то в temp 11111111

а если указан 1, то в temp 11001100, так?

и еще вопрос, где указывать этот 0 или 1?

Share this post


Link to post
Share on other sites

Литиевые батарейки Fanso для систем телеметрии и дистанционного контроля

Системы телеметрии находят все более широкое применение во многих отраслях на промышленных и коммунальных объектах. Требования, предъявляемые к условиям эксплуатации приборов телеметрии и, как следствие, источников питания для них, могут быть довольно жесткими. Fanso предоставляет широкую линейку продукции, рассчитанной на различные условия эксплуатации, что позволяет подобрать батарейку для каждого конкретного применения, в том числе и для устройств телеметрии.

Подробнее

ага! все, понял,

Example:

ldi ZH, high(Table_1<<1) ; Initialize Z pointer

ldi ZL, low(Table_1<<1)

lpm r16, Z ; Load constant from program

; memory pointed to by Z (r31:r30)

...

Table_1:

.dw 0x5876; 0x76 is addresses when ZLSB = 0

; 0x58 is addresses when ZLSB = 1

Share this post


Link to post
Share on other sites

нет, блин, не все понял, переписал программу под другой процессор, и там начались проблемы, командой lpm извлекается непонятно что (а точнее обсолютно не то, что дожно быть)

программа должна по прерыванию от таймера извлечь сл. значение из таблицы, определить, не конечное ли значение таблицы, если конечное - загрузить начало и выйти из прерывания. все.

кто-нибудь может подсказать почему она не работает? (у меня уже нет вариантов)

.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8535def.inc"

.def temp=r16

rjmp RESET ; Reset Handler

reti;rjmp EXT_INT0 ; IRQ0 Handler

reti;rjmp EXT_INT1 ; IRQ1 Handler

reti;rjmp TIM2_COMP ; Timer2 Compare Handler

reti;rjmp TIM2_OVF ; Timer2 Overflow Handler

reti;rjmp TIM1_CAPT ; Timer1 Capture Handler

reti;rjmp TIM1_COMPA ; Timer1 Compare A Handler

reti;rjmp TIM1_COMPB ; Timer1 Compare B Handler

reti;rjmp TIM1_OVF ; Timer1 Overflow Handler

reti;rjmp TIM0_OVF ; Timer0 Overflow Handler

reti;rjmp SPI_STC ; SPI Transfer Complete Handler

reti;rjmp USART_RXC ; USART RX Complete Handler

reti;rjmp USART_UDRE ; UDR Empty Handler

reti;rjmp USART_TXC ; USART TX Complete Handler

reti;rjmp ADC ; ADC Conversion Complete Handler

reti;rjmp EE_RDY ; EEPROM Ready Handler

reti;rjmp ANA_COMP ; Analog Comparator Handler

reti;rjmp TWSI ; Two-wire Serial Interface Handler

reti;rjmp EXT_INT2 ; IRQ2 Handler

rjmp TIM0_COMP ; Timer0 Compare Handler

reti;rjmp SPM_RDY ; Store Program Memory Ready Handler

RESET:

;íàñòîðîéêà ñ÷åò÷èêà Ò0

ldi temp,(1<<CS02)

out tccr0,temp

ldi temp,127

out ocr0,temp

ldi temp,(1<<ocie0)

out timsk,temp

;íàñòðîéêà ïîðòîâ

ldi temp,255

out ddrb,temp

;íàñòðîéêà èíäåêñíîãî ðåãèñòðà

ldi ZH, high(sinus*2)

ldi ZL, low(sinus*2)

;íàñòðîéêà óêàçàòåëÿ ñòåêà

ldi r16,high(RAMEND)

out SPH,r16

ldi r16,low(RAMEND)

out SPL,r16

sei ; Enable interrupts

main:

rjmp main

TIM0_COMP:

nop

LPM temp,Z+

out portb,temp

cpi temp,0b11111111

breq reload

out_TIM0_COMP:

reti

reload:

ldi ZH,high (sinus*2)

ldi ZL,low (sinus*2)

rjmp out_TIM0_COMP

sinus:

.dw 1010101010101010

.dw 0101010101010101

.dw 1111111111111111

Share this post


Link to post
Share on other sites
                     

Приглашаем на вебинар Решения для построения ультразвуковых счетчиков жидкостей и газов на базе MSP430

Компэл совместно с Texas Instruments 23 октября 2019 приглашают на вебинар, посвященный системам-на-кристалле для построения ультразвуковых расходомеров жидкостей и газов на базе ядра MSP430. Вебинар проводит Йоханн Ципперер – эксперт по ультразвуковым технологиям, непосредственно участвовавший в создании данного решения. На вебинаре компания Texas Instruments представит однокристальное решение, позволяющее создавать точные недорогие счетчики жидкостей и газов.

Подробнее...

Мнене непонятно НАФИГА там это умножение адреса на 2??? Ненужно оно там!!! Команда и так отдаёт правильный адрес...

Share this post


Link to post
Share on other sites

в какой-то книге прочел... на память не вспомню в какой, но пробовал и с умножением, и без оного. результаты одинаковы.

Share this post


Link to post
Share on other sites

ldi ZH,high (sinus<<1)

ldi ZL,low (sinus<<1)

Я обычно так адресую. Все проходит. Только вот о каком втором байте вы говорите? Может это не у AVR? В описании говорится: команда LPM загружает ОДИН БАЙТ... И она используется либо без операндов, либо в качестве операнда идет номер регистра. Больше ничего.

Skef, а зачем тебе второй байт (dw 0101010101010101, бинар пишется dw 0b01010101...), ведь ты берешь только 8бит (temp 8-ми битный), да и порт тоже 8-ми битный. Перепиши:

sinus:

.db 0b10101010

.db 0b01010101

.db 0b11111111

или так

sinus:

.db 0xAA, 0x55, 0xFF (db $AA, $55, $FF)

индексный регистр устанавливай, как указано выше (или как у тебя). Если надо по два байта (16 бит), просто считывай два раза за один проход (не забудь в массив включить ВСЕ нужные байты). В памяти они расположатся линейно по адресам. С каждым LPM ...,Z+ индексный регистр будет инкременитроваться на 1. Все-равно "пройдешь" побайтно. 

Edited by Геннадий

Share this post


Link to post
Share on other sites

поставил в каждой строчке в таблице .db, все как надо запустилось.

на контроллере будет светодинамическое устройство, крутится цилиндр, на нем стоят 16 светодиодов, создает рисунки, надписи, и пр. так что для понятности надо в шестнадцать разрядов все подробно писать. будет по два считывания в два порта

и еще можно пару вопросов?

1) почему sinus<<1? для чего нужен сдвиг (<<)

2)когда ставил не .dw, a .db, он выдавал: .db warning: .cseg .db misalignment - padding zero byte

Share this post


Link to post
Share on other sites

Когда ругается на padding - надо настроить начало сегмента данных!!!

Share this post


Link to post
Share on other sites

Хоть организация памяти 16-ти разрядная (кратная слову), но все же процессор 8-ми битный. Отсюда "1) почему sinus<<1? для чего нужен сдвиг (<<)" объясняется тем, что компилятор вычисляет адрес слова, а камень работает с адресом байта, поэтому и делается сдвиг (умножение на 2), т.к. в одном слове два байта. В твоей проге получается, что первый байт данных находится по адресу слова $002E, а адрес байта будет $002E*2 (или 002E<<1)= $005C, куда и обратится камень за данными, используя индексный регистр Z, который адресует не слова, а байты. Т.е. процессор, используя регистр Z, может адресоваться к одному байту данных, поэтому твое дело вычилить правильно адрес в программе.

директива .dw (data word) резервирует два байта (одно слово) и укладывает твои 0b1010101010101010 так $AAAA

директива .db (data byte) резервирует один байт и ей требуется только 0b10101010

Передавая директиве .db 16бит данных "2)когда ставил не .dw, a .db, он выдавал: .db warning: .cseg .db misalignment - padding zero byte" ты сводил с ума компилятор, который, повинуясь директиве, мог брать только 8бит из 16-ти, но и игнорировать 16-ти битное значение не мог. Поэтому в память укладывалось 00AA (вместо АААА). АА-взято 8-ми битной директивой из твоих данных, а 00-добавлено, потому что ты пытался уложить 16 бит. О чем ты и получал сообщение, которое можно расценить примерно так "неправильное размещение, добавлен нулевой байт".

В принципе и твой вариант адресуется правильно, но при эмуляции у меня не работало прерывание. И еще "...при косвенной адресации мы адресуемся к слову (2 байта), команда lpm выгружает один байт в r0, вопрос..." откуда взял? Мы адресуемся всегда к байту. 

Edited by Геннадий

Share this post


Link to post
Share on other sites

Доброго дня, друзья. У меня возникла проблема с использованием команды LPM в симуляторе AVR studio 4, version 4.19 Build 730.

   mov   r30,ir
   mov   r31,irdop
   lpm   
   mov   ir,r0
   inc   r30  
   lpm   

Перед выполнением инструкции LPM в регистре Z число 0x0082, по этому адресу в памяти программ значение 0xbb. Однако в регистре R0 после исполнения я получаю 0xff.

В чём может быть проблема? 

Share this post


Link to post
Share on other sites
52 минуты назад, mazzi сказал:

по этому адресу в памяти программ значение 0xbb

Может ты на 2 просмотрел умножить/поделить адрес - посмотри по адресу 0х0082/2 или 0х0082*2 - положи в них что то осмысленное чтобы понять!, скорее всего не тот адрес смотришь-читаешь!!!

Share this post


Link to post
Share on other sites

avrstd.thumb.png.95f8d360cbdaa1cb3de4a078a65667c7.png

Вот так выглядит экран непосредственно перед выполнением инструкции LPM. Здесь видно содержимое Z и памяти программ. Делить зачем?

Share this post


Link to post
Share on other sites

111.jpg.be5780e161655b63005ad02c7cf881d9.jpg

У вас в регистр R0 заносится младший байт с адреса 0х41

Share this post


Link to post
Share on other sites
20 часов назад, mazzi сказал:

Здесь видно содержимое Z и памяти программ. Делить зачем?

Действительно все видно! Смотрите внимательнее!

потому что адресация памяти программ 2-х байтная (по слову), а вам надо по байтную адресацию.

Share this post


Link to post
Share on other sites

Сейчас проверю.

Действительно, умножил на 2 и всё заработало. Спасибо за подсказку.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...