Цитата(andreichk @ Apr 1 2008, 22:33)

это вы про ФИФО ? а какие тогда правильные.
Понимаете, ситуация у вас следующая: Допустим тактируете вы запись FIFO 80 МГц.
Вы заходите в процедуру pix_A(), ресетите буфер. Далее начианете искать фронт синхронизации. Частота считывания данных процом из FIFO, будет при этом порядка 100 кГц. Одновременно он заполняется данными на скорости 80 Мгц. Т.е. в 400 раз быстрее. Т.е. реально вы успеете считать 2 отсчета, и ФИФО буфер заткнется. (т.к. в нем стоит защита от переполнения). Далее вы считываете третий отсчет. И так как появилась свободная ячейка, ФИФО принимает еще один байт с АЦП. Затем, такая же ситуация с четвертым и последующими отсчетами. Т.е. картина следующая: первые, примерно 512 отсчетов заполняются на скорости 80 Мгц. все последующие заполняются на частоте вашего считывания.
Все хорошо, и вашего FIFO буффера достаточно, если порог синхронизации был найден в примерно в первых 256-ти отсчетах, т.к. после этого вы отрисовываете еще 253 отсчета (которые еще были оцифрованны на 80 Мгц). Но, чем дальше вы уходите при поиске фронта за первые 256 отсчетов, тем больше косячится конец буфера (т.к. все последующие отсчеты были занесены в буфер с частотой вашего считывания). Т.е. теоретически, если вы нашли фронт синхронизации за пределами первых 512 ти отсчетов, то вы как раз и отрисуете частокол, т.к. получиться эффект aliasing-а про который вы упоминали.(потому что вы с низкой частотой, выхватываете отсчеты из высокочастотного сигнала, а т.к. частоты не кратные, получается практически случайная картина).
Исходя из всего вышесказанного, можно сделать вывод, что ваш осцилл. будет работать "на ура", если будет находить фронты синхронизации, в
первых 256 байтах ФИФО буфера. И как только, по каким либо причинам, он выходит за этот предел, начинаеться "каша".
Такчто, первое что нужно сделать - это исправить вашу программу - если нет фронта синхронизации в первых 256 ти байтах, то ресетить ФИФО, и искать заново. А по прошествии, допустим 10 попыток, если не нашелся фронт синхронизации, тупо отрисовывать оставшуюся часть буфера. Т.е.
никогда не вылазить за первые 512 байт, т.к. там все равно информация собранная на другой частоте, а следовательно неправильная и отображению
не подлежит!Во вторых можно увеличить размер ФИФО буферов.
А вообще я бы посоветовал, взять ПЛИСку подороже, с внутренней памятью, и запрограммировать ее, чтобы она сама, напрямую загребала данные с АЦП, и на автомате искала фронты синхронизации. А процу доставался бы лишь готовый, синхронизированный массивчик для отображения на экране. ИМХО нефиг загружать проц такой работой, ибо MIPSов на это у него явно не достаточно

(Заодно сэкономите на буферах - они я смотрю не дешевые)

Измененная процедура pix_A() будеу выглядеть вот так:
Код
#define TIMEOUT 10
#define MAXN 258
void pix_A(unsigned int8 y_pos_A) // рисуем кривую, типа синусоиды и пр.
{ unsigned int16 n;
unsigned int8 try=TIMEOUT;
while(try--){
n=0;
Output_bit(PLCD_FIFO_RES ,0); //PIN_C0// сброс FIFO в "0"
Output_bit(PLCD_FIFO_RES ,1); //PIN_C0// и разрешение на считывание
Output_bit(READ_FIFO_B ,1); //PIN_C1 запрет канала B
// слабая попытка синхронизации
do{ Output_bit(READ_FIFO_A ,0);//PIN_C2
adcA=input_b();
Output_bit(READ_FIFO_A ,1);//PIN_C2
if (n++>MAXN) break;// В этой попытке смотреть дальше неимеет смысла
}while( adcA == 0);
if (n>MAXN) contiune;// Начнем с начала
do{ // ещё одна попытка синхронизации
Output_bit(READ_FIFO_A ,0);//PIN_C2
adcA=input_b();
Output_bit(READ_FIFO_A ,1); //PIN_C2
if (n++>MAXN) break;// В этой попытке смотреть дальше неимеет смысла
}while(input_b()== adcA ); //уже лучше,но всё равно плохо
if (n>MAXN) contiune;// Начнем с начала
//-------------------- синхронизация ---------------------------
while(1){
Output_bit(READ_FIFO_A ,0); //PIN_C2. разрешить
adcA=input_b(); //чтение порта В
Output_bit(READ_FIFO_A ,1); //PIN_C2.запретить
adcA = (adcA > 200) ? 200 : adcA; //ограничитель до выбранной величины
adcA = 255 - adcA; // разворот на 180° по вертикали
if (n++>MAXN) break;// В этой попытке смотреть дальше неимеет смысла
if (syncA){
if(adcA>sync_volume_A) continue;
else break;
}else{
if(adcA<=sync_volume_A+115) continue;
else break;
}
}
if (n>MAXN) contiune;// Начнем с начала
else break;//Иначе выйдем из цикла и отрисуем кривую
}
curve_A(y_pos_A); // Сюда попадем только если нашли фронт синхронизации, либо исткло количество попыток
}
TIMEOUT - количество попыток синхронизации
MAXN - максимальное значение до которого ищем порог синхронизации.
Измененная процедура curve_A() будеу выглядеть вот так:
Код
//--------------- собственно кривая ---------------------------
void curve_A(unsigned int8 y_pos_A){
unsigned int8 x, y , yy;
for(x=1;x<255;x++){
yy = y;
Output_bit(READ_FIFO_A ,0); //PIN_C2. разрешить
adcA=input_b(); //чтение порта В
Output_bit(READ_FIFO_A ,1); //PIN_C2.запретить
adcA = (adcA > 200) ? 200 : adcA; //ограничитель до выбранной величины
y = (255 - adcA) + y_pos_A; // разворот на 180° по вертикали и сдвиг
if (yy>y) front(x,yy,y); // Рисуем фронт A
if (yy<y) spad(x,yy,y); // Рисуем спад A
pixel(x,y,1); // Рисуем вершину A
}
}
Я убрал массив, т.к. он не имеет смысла. Торопиться здесь некуда. Данные лежат в ФИФО буфере и никуда не денуться пока мы их не считаем. Хотя, если одновременно еще строить спектр то можно завести глобальный массив, и заполнить его в этой процедуре.