реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Работа с опреативной памятью в AVR ASM
HoboTech
сообщение Jan 18 2011, 09:56
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 27-09-10
Из: Харьков
Пользователь №: 59 762



Здравствуйте, так получилось, что на C/С++ для АВРов начал писать раньше, чем на АСМе. Теперь не совсем понятно как корректно работать с переменными в SRAM.
Если на С задачу копирования адреса я решал так:
Код
unsigned char *ptr1, *ptr2;

ptr2 = ptr1;


и копирование значения (как вариант):
Код
unsigned char *ptr1, *ptr2;

*ptr2 = *ptr1;


то как такие задачи решаются на АСМе?

если написан следующий код:
Код
Tmp1:  .byte 1
Tmp2:  .byte 1

.....

lds r16,SPDR ;для примера взят регистр SPI
st Z+,r16

lds Tmp1,ZH
lds Tmp2,ZL


то что значат последние две строки кода: что я копирую значения старшего и младшего байтов регистра Z или что я копирую новый адрес ячейки памяти, на которую указывает Z после постинкремента?
Вобщем хотелось бы знать как в АСМе скопировать адрес и как скопировать значение.

Надеюсь корректно описал вопрос.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 18 2011, 10:38
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Код
lds Tmp1,ZH
lds Tmp2,ZL

Вы считывете в Tmp1- значение расположенное по адресу находящегося ZH и соответсвенно в Tmp2 в ZL т.е не понятно откуда

Скопировать значение mov TMP1,TMP2
Скопировать адрес MOVW X,Z


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
HoboTech
сообщение Jan 18 2011, 11:52
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 27-09-10
Из: Харьков
Пользователь №: 59 762



Цитата(ILYAUL @ Jan 18 2011, 12:38) *
Вы считывете в Tmp1- значение расположенное по адресу находящегося ZH и соответсвенно в Tmp2 в ZL т.е не понятно откуда

предполагается, что ранее в программе в Z что-то заносилось

Цитата(ILYAUL @ Jan 18 2011, 12:38) *
Скопировать значение mov TMP1,TMP2
Скопировать адрес MOVW X,Z

спасибо, буду пробовать

Вообще, наверно, проще будет описать задачу:
есть буффер из 50 элементов и в него заносятся последовательно байты; есть две байтовых переменных, в которых должна хранится high и low часть адреса следующего элемента, который будет записан (по аналогии с индексом массива в С/С++). В обработчике прерывания я заношу в буффер байт, инкрементирую регистр Z и нужно этот новый адрес записать для того, чтобы в следующем прерывании уже записывать новый элемент

реализация на С для IAR простенького кольцевого буффера:
Код
#include <ioavr.h>
#define EVER;;
#define BUFF_SIZE 50

typedef unsigned char BYTE;

BYTE Buff[BUFF_SIZE];
BYTE index;

void main()
{
     USART_Init();    //к примеру будем забирать из УСАРТа байты

     for(EVER)
    {
        
    }

#pragma vector=USART0_RXC_vect
  __interrupt void usart_rxc(void)
{
      BYTE sym;

      sym = UDR0;
      Buff[index++] = sym;
      index = index % BUFF_SIZE;
}
}

как написать подобное на АСМе?

пробовал написать следующее:
Код
...

.DSEG
USART_Index_H:  .byte 1
USART_Index_L:  .byte 1
USART_BUFF:  .byte 50

...
;инициализации и все такое
...

USART0_RXC:
  push ZH
  push ZL
  push r16

;грузим адрес нового элемента, полученный в предыдущем прерывании
  lds ZH,USART_Index_H
  lds ZL,USART_Index_L
        
  lds r16,UDR0
  st Z+,r16

;сохраняем новый адрес
  lds USART_Index_H,ZH
  lds USART_Index_L,ZL
  reti


но, полагаю, это работать не будет...

Забыл дописать
Код
...
;инициализация
lds ZH,high(USART_BUFF)
lds ZL,low(USART_BUFF)
sts USART_Index_H,ZH
sts USART_Index_L,ZL
...
;и забыл в конце прерывания дописать
pop r16
pop ZL
pop ZH


Сообщение отредактировал HoboTech - Jan 18 2011, 11:53
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 18 2011, 13:17
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Что бы понять до конца задачу - прерывания идут последовательно ? Т.е. 1, 2, 1, 2,1, 2 или нет 1111, 2, 11 ,2 и тд



--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
HoboTech
сообщение Jan 18 2011, 13:51
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 27-09-10
Из: Харьков
Пользователь №: 59 762



Цитата(ILYAUL @ Jan 18 2011, 15:17) *
Что бы понять до конца задачу - прерывания идут последовательно ? Т.е. 1, 2, 1, 2,1, 2 или нет 1111, 2, 11 ,2 и тд


в общем задача сводится к тому, чтобы по приходу символа в USART заносить его последовательно в буфер
прерывание одно - USART0_RXC:
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 18 2011, 15:02
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Код
.def R16,temp
.def R17,count
.def R4,SaveSREG
... Инициализация

.DSEG
USART_BUFF:  .byte 50

SAVE_INDEX_Z: byte 2
          SaveZL =0
          SaveZH=1


MAIN:
ldi ZH,HIGH(USART_BUFF)
ldi ZL,LOW(USART_BUFF)
ldi count,50
.........................

USART0_RXC:
         in  SaveSREG,SREG
         push SaveSREG
         push temp
                                 push ZL
                                 push ZH
                                 lds  ZL,SAVE_INDEX_Z+SaveZL
                                 lds  ZH,SAVE_INDEX_Z+SaveZH
         lds  temp,UDR0
         st   Z+,temp
         dec count
         brne END_RX
         ldi ZH,HIGH(USART_BUFF)
         ldi ZL,LOW(USART_BUFF)
         ldi count,50
END_RX:
                                 sts  SAVE_INDEX_Z+SaveZL,ZL
                                 sts  SAVE_INDEX_Z+SaveZH,ZH
                                 pop ZH
                                 pop ZL
                     pop temp
                     pop SaveSREG
                     out SREG,SAVESREG
reti


Но лучше использовать регисты X или Y вместо Z- через Z идёт обращение к памяти програм и Eeprom и он чаще используется и соответственно его надо отслеживать и при необходимости
PUSH и POP


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
HoboTech
сообщение Jan 18 2011, 15:39
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 27-09-10
Из: Харьков
Пользователь №: 59 762



Я так понял Ваш код будет работать только в случае, когда в основном теле программы не изменяется содержимое ZH и ZL.
Меня интересует именно сохранение адреса, на который указывает регистровая пара Z после постинкремента, в переменную
Если, конечно, такое возможно

Сообщение отредактировал HoboTech - Jan 18 2011, 15:40
Go to the top of the page
 
+Quote Post
Дмитрий Ветра
сообщение Jan 18 2011, 16:31
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 6-12-07
Из: Рига, Латвия
Пользователь №: 33 036



Цитата(HoboTech @ Jan 18 2011, 17:39) *
Я так понял Ваш код будет работать только в случае, когда в основном теле программы не изменяется содержимое ZH и ZL.
Меня интересует именно сохранение адреса, на который указывает регистровая пара Z после постинкремента, в переменную
Если, конечно, такое возможно

Есть два варианта:


- сохраняем в ОЗУ;
.equ ZH_save 0x0100
.equ ZL_save 0x0101

sts ZH_save,ZH
sts ZL_ save,ZL

- копируем регистровую пару;

movw r3:r2,ZH:ZL

в целом:

lds ZH, ZH_save ; восстанавливаем указатель
lds ZL, ZL_save

in r16, UDR ; записываем принятый байт
st Z+, r16

sts ZH_save, ZH ; сохраняем указатель
sts ZL_save, ZL

Сообщение отредактировал Дмитрий Ветра - Jan 18 2011, 16:34
Go to the top of the page
 
+Quote Post
HoboTech
сообщение Jan 18 2011, 17:04
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 27-09-10
Из: Харьков
Пользователь №: 59 762



Цитата(Дмитрий Ветра @ Jan 18 2011, 18:31) *
Есть два варианта:


- сохраняем в ОЗУ;
.equ ZH_save 0x0100
.equ ZL_save 0x0101

sts ZH_save,ZH
sts ZL_ save,ZL

- копируем регистровую пару;

movw r3:r2,ZH:ZL

в целом:

lds ZH, ZH_save ; восстанавливаем указатель
lds ZL, ZL_save

in r16, UDR ; записываем принятый байт
st Z+, r16

sts ZH_save, ZH ; сохраняем указатель
sts ZL_save, ZL


Спасибо, а то я разбаловался языками верхнего уровня, а на уровне "кирпичиков" топчусь как лось на одном месте sm.gif
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 18 2011, 17:26
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(HoboTech @ Jan 18 2011, 18:39) *
Я так понял Ваш код будет работать только в случае, когда в основном теле программы не изменяется содержимое ZH и ZL.
Меня интересует именно сохранение адреса, на который указывает регистровая пара Z после постинкремента, в переменную
Если, конечно, такое возможно

всё верно . Если Вы предполагаете изменять ZL ZH , то хотя бы напишите , что именно будет происходить в основной программе . Тогда будет понятно , каким образом сохранять Z . Толи записывать его в регистры хранения , толи в SRAM, а может будет достаточно push и pop

Я Вам переписал предыдущий пост- сохранив Вам Z для прерывания и для MAIN


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
HoboTech
сообщение Jan 21 2011, 11:19
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 27-09-10
Из: Харьков
Пользователь №: 59 762



И все таки туго что-то до меня доходит работа с адресами...
что означает следующий код:
Код
.DSEG
tmp: .byte 1

...

lds ZL,tmp

что я заношу в регистр ZL значение байта, который находился в памяти по адресу tmp или что я записываю значение младшего байта самого адреса? sad.gif
Go to the top of the page
 
+Quote Post
V_G
сообщение Jan 21 2011, 12:22
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Это вы байт загружаете.
Адрес - другой командой (двумя для полного адреса):

LDI ZL, low(tmp)
LDI ZH,high(tmp)

Я подобные частые действия оформляю макросами, чтобы в одну строчку было
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 21 2011, 13:26
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(V_G @ Jan 21 2011, 15:22) *
Это вы байт загружаете.....

...... из SRAM в регистр ( Sorry V_G) так по понятнее будет. А про макросы наверное рановато


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
V_G
сообщение Jan 21 2011, 13:50
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Как это в SRAM?
LDS - загрузка ИЗ SRAM в регистр (LoaD from Sram - мнемоники вполне работают)
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 21 2011, 14:28
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(V_G @ Jan 21 2011, 16:50) *
Как это в SRAM?
LDS - загрузка ИЗ SRAM в регистр (LoaD from Sram - мнемоники вполне работают)

Конечно , конечно - это я уже ,в конце недели зарапортовался. Поправил


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 14:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.01652 секунд с 7
ELECTRONIX ©2004-2016