Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Количество стробов ALE
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
tonjo
Не понимаю, зачем при работе с внешним ОЗУ mega посылает три строба ALE за один период чтения или записи? Помогите пожалуйста разобраться!
ReAl
Цитата(tonjo @ Nov 25 2006, 18:21) *
Не понимаю, зачем при работе с внешним ОЗУ mega посылает три строба ALE за один период чтения или записи? Помогите пожалуйста разобраться!

А ты возьми да задай в этой меге для обращения к внешнему ОЗУ максимальную длительность обращения (SRW = 3) да опять погляди осциллографом на то, что вышло. Сравни с картинкой при SRW=0 - где расстояния между ALE изменятся, а где нет.

Hint: ALE генерируется не только в циклах обращения к внешнему ОЗУ.

Using the External Memory Interface
...
...
When the XMEM interface is enabled, also an internal access will cause activity on address, data and ALE ports, but the RD and WR strobes will not toggle during internal access.
tonjo
Спасибо, вот теперь разобрался.
Цитата(ReAl @ Nov 25 2006, 23:39) *
When the XMEM interface is enabled, also an internal access will cause activity on address, data and ALE ports, but the RD and WR strobes will not toggle during internal access.

Для тех кто не изучал англ.яз. переводится примерно так:
Когда работа интерфейса XMEM разрешена, доступ к внутренней памяти будет вызывать изменения на шинах данных и адреса, а также строба ALE, при этом, стробы RD и WR останутся неизменными.
Но есть ещё вопрос: почему-то после 2-го и 3-го строба ALE на AD7:0 разные временные диаграммы. Получается, что если у меня XMEM всегда включен, то на младшие 256 байт внешнего ОЗУ всегда отображаются ещё и значения внутренней памяти. Я прав?
=GM=
Цитата(tonjo @ Nov 25 2006, 16:21) *
Не понимаю, зачем при работе с внешним ОЗУ mega посылает три строба ALE за один период чтения или записи? Помогите пожалуйста разобраться!

Вроде не должно быть так. Мега должна посылать один строб ALE за один цикл чтения/записи в/из внешней памяти (3+ тактов процессора). В цикле чтения/записи внешней памяти не должно быть обращения к внутренней ОЗУ.

Как вы определили, что именно за ОДИН период чтения посылается три строба ALE? Какие команды вы использовали для чтения и записи?
tonjo
Цитата(=GM= @ Nov 27 2006, 16:56) *
Как вы определили, что именно за ОДИН период чтения посылается три строба ALE? Какие команды вы использовали для чтения и записи?

То что за один период чтения или записи - то это посмотрел осциллографом. Т.е. идет строб ALE, затем адрес, данные. Потом строб WR или RD заканчивается и появляются ещё два строба ALE, расстояние между которыми примерно 1мкс (контроллер работает на частоте 8МГц).
На С пишу недавно и не исключаю, что неправильно написал программу (контроллер mega128). Привожу код:

#define offset 0x1100
void WriteByte(unsigned char Addr, unsigned char Data)
{
unsigned char *pSRAM = (unsigned char *)(offset+Addr);
*pSRAM = Data;
}
unsigned char ReadByte(unsigned char Addr)
{
unsigned char *pSRAM = (unsigned char *)(offset+Addr);
return *pSRAM;
}
=GM=
Цитата(tonjo @ Nov 27 2006, 19:04) *
Цитата(=GM= @ Nov 27 2006, 16:56) *

Как вы определили, что именно за ОДИН период чтения посылается три строба ALE? Какие команды вы использовали для чтения и записи?

То что за один период чтения или записи - то это посмотрел осциллографом. Т.е. идет строб ALE, затем адрес, данные. Потом строб WR или RD заканчивается и появляются ещё два строба ALE, расстояние между которыми примерно 1мкс (контроллер работает на частоте 8МГц).
На С пишу недавно и не исключаю, что неправильно написал программу (контроллер mega128). Привожу код:

#define offset 0x1100
void WriteByte(unsigned char Addr, unsigned char Data)
{
unsigned char *pSRAM = (unsigned char *)(offset+Addr);
*pSRAM = Data;
}
unsigned char ReadByte(unsigned char Addr)
{
unsigned char *pSRAM = (unsigned char *)(offset+Addr);
return *pSRAM;
}

Пропустил ваш код (см.ниже) через КоудВижнАВР-компайлер, ужас! В течение одного цикла оператора while насчитал СЕМЬ обращений к памяти, из них только одно - к внешней. Пометил их цифрами от 1 до 7. Теперь я удивляюсь как вам удалось ужаться до трёх! Вы зря, кстати, pSRAM объявили как char, компайлер все равно интерпретирует его как int.

Код
#define offset 0x1100
unsigned char *pSRAM;

unsigned char ReadByte(unsigned char Addr)
{
*pSRAM=offset+Addr;
return *pSRAM;
}

void main(void)
{
unsigned char address=0x1000;
unsigned char byte=0x13;
while(1)
{
  byte=ReadByte(address);
}
}

          .CSEG
         .ORG     0
__RESET:  LDI     R30,LOW(0x25F) ; STACK
          OUT     SPL,R30        ; POINTER
          LDI     R30,HIGH(0x25F); INITIALIZATION
          OUT     SPH,R30
          LDI     R28,LOW(0xE0)  ; DATA INITIALIZATION
          LDI     R29,HIGH(0xE0) ; STACK POINTER
          RJMP    _main

; #define offset  0x1100
          .DSEG
          .ORG    0xE0
_pSRAM:   .BYTE   0x2            ; unsigned char *pSRAM

          .CSEG
; unsigned char ReadByte(unsigned char Addr){
_ReadByte: LD     R30,Y          ;2 *pSRAM=offset+Addr;
           LDI    R26,LOW(4352)  ;
           LDI    R27,HIGH(4352) ;
           CLR    R31            ;
           ADD    R30,R26        ;
           ADC    R31,R27        ;
           LDS    R26,_pSRAM     ;3
           LDS    R27,_pSRAM+1   ;4
           ST     X,R30          ;5
           ADIW   R28,1          ;  return *pSRAM;}
           RET                   ;6-7

;     void main(void){
_main:     LDI    R16,0          ;  address -> R16
           LDI    R17,19         ;  byte -> R17
_0x3:      ST     -Y,R16         ;1 while(1){
           RCALL  _ReadByte      ; byte=ReadByte(address);
           MOV    R17,R30        ;
           RJMP   _0x3           ;  } end while loop
_0x6:      RJMP   _0x6           ;  } end main

tonjo
Спасибо, =GM=, за помощь. Вот не ожидал такого. А как лучше сделать, чтобы не было такого ужаса?Можете примерчик привести? Пожалуйста!
=GM=
Цитата(tonjo @ Nov 28 2006, 15:02) *
Спасибо, =GM=, за помощь. Вот не ожидал такого. А как лучше сделать, чтобы не было такого ужаса?Можете примерчик привести? Пожалуйста!

Зависит от того, чего вы хотите достичь. Обычно советуют писать всё на ассемблере. Может и правильно, но люди иногда экономят свой труд, а не время МК. Тоже подход. Я вам посоветую найти узкие места в своей программе и расширить их, написав подпрограмму на ассемблере, или изменив алгоритм, или еще как-то, это зависит от задачи, а еще больше от конечной цели, которую вы поставили.

По поводу примера. Напишите сами, пусть плохой, приведите его здесь, люди здесь неплохие, покажут как надо делать и как не надо. Самостоятельная работа поможет вам гораздо больше, нежели чужой код, пусть и более компактный. Критический указатель лучше хранить в регистрах, тогда две ваши подпрограммы будут занимать две строчки, ну и зачем тогда нужны подпрограммы? Выкиньте их.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.