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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
alexeyv
сообщение Jul 1 2011, 13:07
Сообщение #16


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Цитата
А в пятой студии свой компилятор?

Так же как и в WInAVR, в AStudio использует GNU-toolchain. Про версии не помню, но файлы в каталогах \avr\bin\ совпадают

Цитата
Или кратно 256 и буфер на границе. 5 команд - но 7 тактов (или 6, если контроль на 1 байт). Однако вполне можно сократить до 5 тактов, причем с контролем на 16-битный адрес


Согласен:
Код
ldi    r31,0x04
ldi    r30,0x00
ldi    r25,0x02
ldi    r24,0x00
;cycle:
in    r18, 0x19
st    -Z, r18
cpc    r31, r25
brne    .-8

где ((r31-r25) * 256) - размер массива

Сообщение отредактировал alexeyv - Jul 1 2011, 13:31
Go to the top of the page
 
+Quote Post
Sirko
сообщение Jul 2 2011, 18:33
Сообщение #17


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Цитата
Необходимо снять лог некой шины, у которой частота в районе мегагерца.

Наивный, однако wink.gif

После некоторых телодвижений - Mega162 была задвинута в сторонку.
Еще после некоторых телодвижениий эйфории от юзания XMega тоже поубавилось.

В конечном итоге, в ходе издевательств над собой и процом, оказалось, что Мега, погнанная до 48Мгц с четырьмя тактами на одно измерение, судя по всему, не отражает достоверно состояние шины т.к. есть одиночные показания некоторых бит. Стало быть, есть вероятность, что какие-нибудь данные могут проскочить мимо.
Что-ж, видать, не судьба.

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

Исходник приложу - вдруг какие-нибудь мысли появятся.
CODE
typedef unsigned char u08;
typedef unsigned int u16;
typedef unsigned long u32;

#define F_CPU 48000000UL

#include <avr/io.h>
#include <util/delay.h>


#define USART USARTC0
#define OnLight PORTQ.OUTCLR = PIN2_bm
#define OffLight PORTQ.OUTSET = PIN2_bm
#define ToggleLight PORTQ.OUTTGL = PIN2_bm
#define IsPressedButton (PORTQ.IN & PIN3_bm)

#define GetPortOne PORTK.IN
#define GetPortSecond PORTK.IN

#define ScanPorts10(p) do{*p-- = GetPortOne; *p-- = GetPortSecond; /* 0 */\
*p-- = GetPortOne; *p-- = GetPortSecond; /* 1 */\
*p-- = GetPortOne; *p-- = GetPortSecond; /* 2 */\
*p-- = GetPortOne; *p-- = GetPortSecond; /* 3 */\
*p-- = GetPortOne; *p-- = GetPortSecond; /* 4 */\
*p-- = GetPortOne; *p-- = GetPortSecond; /* 5 */\
*p-- = GetPortOne; *p-- = GetPortSecond; /* 6 */\
*p-- = GetPortOne; *p-- = GetPortSecond; /* 7 */\
*p-- = GetPortOne; *p-- = GetPortSecond; /* 8 */\
*p-- = GetPortOne; *p-- = GetPortSecond; /* 9 */}while(0)

#define ScanPorts100(p) do{ScanPorts10(p); /* 0 */\
ScanPorts10(p); /* 1 */\
ScanPorts10(p); /* 2 */\
ScanPorts10(p); /* 3 */\
ScanPorts10(p); /* 4 */\
ScanPorts10(p); /* 5 */\
ScanPorts10(p); /* 6 */\
ScanPorts10(p); /* 7 */\
ScanPorts10(p); /* 8 */\
ScanPorts10(p); /* 9 */}while(0)

#define ScanPorts1000(p) do{ScanPorts100(p); /* 0 */\
ScanPorts100(p); /* 1 */\
ScanPorts100(p); /* 2 */\
ScanPorts100(p); /* 3 */\
ScanPorts100(p); /* 4 */\
ScanPorts100(p); /* 5 */\
ScanPorts100(p); /* 6 */\
ScanPorts100(p); /* 7 */\
ScanPorts100(p); /* 8 */\
ScanPorts100(p); /* 9 */}while(0)


#define PutChar(ch) do{}while(!(USART.STATUS & USART_DREIF_bm));\
USART.DATA = ch;


#define SIZE_ARRAY 8000
unsigned char array[SIZE_ARRAY];

void sendDigit(u16 digit){
PutChar(digit/1000 + '0'); digit %= 1000;
PutChar(digit/100 + '0'); digit %= 100;
PutChar(digit/10 + '0'); digit %= 10;
PutChar(digit + '0');
PutChar(' ');
PutChar(' ');
}

void sendBusState(u08 state){
for(u08 i=0; i<8; ++i){
PutChar(state & _BV(7) ? '1' : '0');
PutChar('\t');
state <<= 1;
}
}

int main(void){

OSC.XOSCCTRL=0x4b; // диапазон: 2-9 МГц, внешний резонатор, с временем запуска 16 000 циклов
OSC.CTRL=0x08; // включаем генератор на внешнем кварцевом резонаторе
while(!(OSC.STATUS&0x08)); // ждём готовности генератора на внешнем кварцевом резонаторе

OSC.PLLCTRL=0xc6; // внешний источник синхро, множитель=6
OSC.CTRL=0x18; // включаем синтезатор частоты
while(!(OSC.STATUS&0x10)); // ждём готовности синтезатора частоты

CPU_CCP=0xd8; // разрешить (сигнатурой) изменение важного регистра (следущая строка)
CLK.CTRL=0x04; // источник системной синхронизации - синтезатор частоты
CLK.PSCTRL=0x00; // Коэф. деления предделителей A, B и C = 1.

PORTC.DIRSET = PIN3_bm;
PORTC.DIRCLR = PIN2_bm;

USART.CTRLC = (uint8_t) USART_CHSIZE_8BIT_gc | USART_PMODE_DISABLED_gc;
USART.BAUDCTRLA = (u08)289; // Битрейт 921600 при 48МГц clock
USART.BAUDCTRLB = (289 >> 8) | ((-7) << USART_BSCALE0_bp);
USART.CTRLB |= USART_TXEN_bm;

PORTQ.DIRSET = PIN2_bm; // PQ2 Лампа
PORTQ.DIRCLR = PIN3_bm; // PQ3 Кнопка
PORTQ.PIN3CTRL = PORT_OPC_WIREDORPULL_gc; // Подтяжка вниз


PORTK.DIR = PORTJ.DIR = 0;
PORTJ.PIN0CTRL =
PORTJ.PIN1CTRL =
PORTJ.PIN2CTRL =
PORTJ.PIN3CTRL =
PORTJ.PIN4CTRL =
PORTJ.PIN5CTRL =
PORTJ.PIN6CTRL =
PORTJ.PIN7CTRL =
PORTK.PIN0CTRL =
PORTK.PIN1CTRL =
PORTK.PIN2CTRL =
PORTK.PIN3CTRL =
PORTK.PIN4CTRL =
PORTK.PIN5CTRL =
PORTK.PIN6CTRL =
PORTK.PIN7CTRL = PORT_OPC_WIREDANDPULL_gc; // Подтяжка вверх


while(1){

while(!IsPressedButton){
_delay_ms(250);
ToggleLight;
}

u08 *p = &array[SIZE_ARRAY-1];

while(!(PORTJ.IN & PIN7_bm)); // Ждать появления питания на девайсе

ScanPorts1000(p);
ScanPorts1000(p);
ScanPorts1000(p);
ScanPorts1000(p);

p = &array[SIZE_ARRAY-1];
u16 index = SIZE_ARRAY-1;

PutChar('-'); PutChar('-'); PutChar('-'); PutChar('-');
static u16 currentSample = 0;
sendDigit(currentSample++); PutChar('\n'); PutChar('\r');

do{
sendDigit(index--);
PutChar('\t');

//sendBusState(*p--);
//PutChar('\t');

sendBusState(*p);
PutChar('\n');
PutChar('\r');
static u08 pause = 0;
if(!pause--)
_delay_ms(10); // Для компенсации "несинхронности UART"
}while(p-- != array);

PutChar('\n');
PutChar('\r');
PutChar('\n');
PutChar('\r');
PutChar('\n');
PutChar('\r');

_delay_ms(500);
}
}


Сообщение отредактировал IgorKossak - Jul 2 2011, 20:08
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jul 2 2011, 20:22
Сообщение #18


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(Sirko @ Jul 2 2011, 17:33) *
Наивный, однако wink.gif

Да, наивный и упрямый, поскольку, чтобы считать сигнал около мегагерца, нужна частота выборок около двух мегагерц. Следовательно, при тактовой частоте проца 20 МГц, необходимое число тактов на цикл 20/2=10 машинных циклов. Десяти циклов должно хватить за глаза. Скажу так, за 5 циклов можно считать из порта, записать в память, передвинуть указатель и проверить его на конец массива. Ну и ещё чего-нибудь, скажем помигать светодиодом и опросить кнопки. Ну или непрерывно писать в буфер циклически и по запросу выдавать весь массив, который записан на текущее время.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Sirko
сообщение Jul 2 2011, 20:50
Сообщение #19


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Цитата
Скажу так, за 5 циклов можно считать, записать, передвинуть, проверить и ещё чего-нибудь

Это че, - шутка юмора такая?
Записать-передвинуть с проверкой менее шести тактов, - не представляю как. Или Вы имеете ввиду 5 команд процессора?


Цитата
чтобы считать сигнал около мегагерца, нужна частота выборок около двух

Это никто не оспаривает. 1Мгц - было предположение, поскольку визуально дорожки длинные, несуразные, тянутся от основого чипа к другим - звездой, через разъемы на разные платы, плюс еще в настоящий момент соплей навешано (шлейф от флопика с макетками) и это все вроде как продолжает функционировать.
На текущий момент у меня скан получается порядка 12МГц, но есть вероятность, что и этого недостаточно.

Цитата
нужно развернуть цикл и повторить 1000 раз фрагмент "прочитать порт в регистр + сохранить регистр с автоинкрементом". Вот вам три такта и будет

У меня получается четыре
.
.
.
lds r24, 0x0728
sts 0x3F42, r24
lds r24, 0x0728
sts 0x3F41, r24
lds r24, 0x0728
sts 0x3F40, r24
.
.
.


Сообщение отредактировал Sirko - Jul 2 2011, 20:56
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Jul 2 2011, 21:45
Сообщение #20


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(Sirko @ Jul 3 2011, 00:50) *
Это че, - шутка юмора такая?
Записать-передвинуть с проверкой менее шести тактов, - не представляю как. Или Вы имеете ввиду 5 команд процессора?

Loop:
in temp,<порт>
st Z+,temp
cp ZL,...
cpc ZH,...
in temp,<порт>
st Z+,temp
brne Loop
Go to the top of the page
 
+Quote Post
Sirko
сообщение Jul 2 2011, 22:33
Сообщение #21


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



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

Loop:
in temp,<порт> - получить состояние шины (1 такт)
st Z+,temp - засунуть это значение в оперативку (2 такта)
cp ZL,... - если младший байт указателя не переходит границу, то перейти к опросу порта (1 такт)
cpc ZH,... - иначе проверить старший байт, если ... - неважно
in temp,<порт> - получить состояние шины (1 такт)
st Z+,temp - засунуть это значение в оперативку (2 такта)
brne Loop - продолжить (если нужно) (1 такт)

Т.е. если не придираться к иногда возникающему CP-CPC, то в среднем по четыре такта на один опрос.
Ну в принципе в настоящий момент у меня тоже их четыре
А вот как-бы засунуть в сишный файл вот это -
in temp,<порт>
st Z+,temp
in temp,<порт>
st Z+,temp
in temp,<порт>
st Z+,temp
...
???
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Jul 3 2011, 07:11
Сообщение #22


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(Sirko @ Jul 3 2011, 02:33) *
Попробую прокоментировать, если че поправьте.

cp ZL,... - если младший байт указателя не переходит границу, то перейти к опросу порта (1 такт)

Вот тут неправильно. Последовательность cp ZL,... cpc ZH,... - это сравнение с 16-битным значением (заданным в регистрах), определяющим границу массива.
Цитата
Т.е. если не придираться к иногда возникающему CP-CPC, то в среднем по четыре такта на один опрос.

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

Go to the top of the page
 
+Quote Post
Sirko
сообщение Jul 3 2011, 07:58
Сообщение #23


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Цитата
Вот тут неправильно.
Понял. Спасибо.

Но тогда выходит, что
Цитата
и не в среднем, а всегда.
- всегда, но чередуясь 5, 4, 5, 4, 5...

Loop:
in temp,<порт> - получить состояние шины (1 такт)
st Z+,temp - засунуть это значение в оперативку (2 такта)
cp ZL,... - если младший и
cpc ZH,... - старший байт указателя переходят границу - выставить флаг (2 такта)
in temp,<порт> - получить состояние шины (1 такт)
st Z+,temp - засунуть это значение в оперативку (2 такта)
brne Loop - продолжить (если нужно) (1 такт)
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Jul 3 2011, 09:45
Сообщение #24


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(Sirko @ Jul 3 2011, 11:58) *
Понял. Спасибо.

Но тогда выходит, что - всегда, но чередуясь 5, 4, 5, 4, 5...
.....
brne Loop - продолжить (если нужно) (1 такт)

При переходе - 2 такта. Поэтому каждый период выборки строго 5 тактов.
Go to the top of the page
 
+Quote Post
Sirko
сообщение Jul 3 2011, 09:51
Сообщение #25


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Спасибо, буду знать.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 4 2011, 13:25
Сообщение #26


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Sirko @ Jul 3 2011, 12:51) *
Спасибо, буду знать.

Эта задача не для AVR. Возьмите простенький CPLD + static RAM + mega162.
подключите CPLD и мегу(по ее шине) к МС памяти.
Внутри CPLD организуется счетчик по отрицательному фронту строба шины которую хотите мониторить.
По стробу внешней шины читайте с нее данные и кладите в SRAM.
при переполнении счетчика, отключите CPLD от памяти и дайте меге строб что та может читать.

CPLD на 150-180Mhz с требуемым количеством ног (вам надо 18+8+2) стоит в районе 5$-8$.
либо готовая макетка за 13$ здесь
МС SRAM брать такую чтобы успевала за шиной которую собрались мониторить. В старых 386-х под кеш использовались 10нс (100Mhz) память 62256 (32KB чип) в DIP копусах вот ее можно взять, но возможно хватит и более медленной памяти.
Go to the top of the page
 
+Quote Post

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

 


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


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