|
|
  |
SED1335,PIC18F4550 и LCD320x240, разбираем по косточкам модуль SED1335.c |
|
|
|
Apr 11 2008, 09:03
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Цитата(andreichk @ Apr 11 2008, 17:23)  Илья, чем вы такие красивые графики строите? Данные обсчитываю в программке которую написал вчера. А график строю в Excell Цитата мне кажется , что некорректно выполняется функция Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); В справке написано , что обе переменные должны быть float, а у нас только одна из них Дык она должна ее автоматом во флоат переколбасить, или CCS и это не делает??? ЗЫ могу выслать программку с исходником. Если у вас есть Borland)
|
|
|
|
|
Apr 11 2008, 09:35
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Вот программка:
FFT.rar ( 229.4 килобайт )
Кол-во скачиваний: 298В левый столбец забейте исходный сигнал. Укажите N - число точек в сигнале (должно быть 2^n) Для подсчета нажмите CALC Программка слеплена за несколько минут, такчто извиняйте). Никаких защит от дурака в программке конечно нет, такчто следите за тем, что вы вводите. Программа специально все расчеты делает в unsigned int. Для того чтобы можно было сравнить с контроллером. Также перед выводом спектр нормируется на максимльное значение 230 Вот исходник:
fftcpp.rar ( 1.48 килобайт )
Кол-во скачиваний: 284Найдите десять отличий)
|
|
|
|
|
Apr 11 2008, 15:44
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Цитата(andreichk @ Apr 12 2008, 00:19)  так я уже пробовал, не помогает Значит проблема не в этом.... Как видите код абсолютно рабочий, неужели компилер гонит? Может в нем отключить какуюнибудь оптимизацию?
|
|
|
|
|
Apr 11 2008, 18:44
|

Знающий
   
Группа: Свой
Сообщений: 507
Регистрация: 15-04-06
Из: Германия
Пользователь №: 16 143

|
Считаю что нужно точно определиться с типами переменных и диапазоном их значений. Итак, 1. буфер Buf_FFT[256 или 512];//Global Buffers for FFT. Диапазон на входе- данные с порта от 0 до 240. Подходящие типы - unsigned int, unsigned int8 0-255, unsigned int16 0 to 65535, signed int16 -32768 to 32767, unsigned int32 0 to 4294967295, signed int32 -2147483648 to 2147483647 float32 -1.5 x 1045 to 3.4 x 1038
диапазон значений буфера после ДФТ realFFT(Buf_FFT,256 или 512); ?????
диапазон значений буфера после Buf_float[k++]=pow((Buf_float[i]*Buf_float[i]+ Buf_float[i+1]*Buf_float[i+1]),0.5); ??? тоже тут Buf_FFT[i] =226.0 - 190.0*Buf_float[i]/max ; ??? Иначе получается полная ерунда, потому что ПИК где-то искажает результаты вычислений.
--------------------
|
|
|
|
|
Apr 12 2008, 12:33
|

Знающий
   
Группа: Свой
Сообщений: 507
Регистрация: 15-04-06
Из: Германия
Пользователь №: 16 143

|
Ура !!!! Совершенно неожиданно нашёл решение проблемы. Самым подходящим типом переменных для буфера оказался signed int32 Buf_FFT[256]; // переобъявим массив как int32 -2147483648 to 2147483647 процедура void realFFT(signed int32 *a, unsigned int16 tnn) также приняла этот тип далее привожу полный текст рисования спектра и полученные фото 1. синус ( данные в тексте ) 2. меандр ( данные в тексте ) 3. реальный меандр 10 МГц Код void spectrum() { unsigned int16 i=0,k=0;float32 max=0.0, s=0.0; unsigned int8 x=1 , y , yy;
for(i=0;i<256;i++){ #asm BCF 0x0F8B,2//LATC2=0;//Output_bit(READ_FIFO_A ,0);//PIN_C2. разрешить #endasm Buf_FFT[i] = input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1;//Output_bit(READ_FIFO_A ,1);//PIN_C2.запретить #endasm } //----------------------------------------------------------------------------- //for(i=0;i<256;i++){ // if (k<14) {Buf_FFT[i]=10;k++;} // else if (k<28) {Buf_FFT[i]=150;k++;} // else {Buf_FFT[i]=10;k=1;} // } //for(i=0;i<256;i++) // { // Buf_FFT[i]=120.0 - 100.0*(sin( s+=0.5)); // } realFFT(Buf_FFT,256);k=0;
for(i=0;i<256;i+=2){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Buf_FFT[0]=Buf_FFT[1]; for(i=0;i<128;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i]; //ищем max for(i=0;i<128;i++) Buf_FFT[i] =226.0 - 190.0*Buf_FFT[i]/max;//нормировка по max, и инвертирование перед распечаткой for(x=1;x<127;x++){ yy=y; y = Buf_FFT[x]; if (yy>y) front(x,yy,y);// Рисуем фронт if (yy<y) spad(x,yy,y);// Рисуем спад pixel(x,y,1); // Рисуем вершину } } //############################################## картинка получается хоть и немного бледноватой из-за частого обновления , но устойчивой. Единственное огорчение, это то, что её нельзя растянуть на весь экран из-за недостаточности объёма внутренней ОЗУ, но и на пол-экрана это уже замечательно. Хотя можно растянуть на весь экран, если изменить эти циклы Код for(i=0;i<256; i++ ){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Buf_FFT[0]=Buf_FFT[1]; for(i=0;i<255;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i]; //ищем max for(i=0;i<255;i++) Buf_FFT[i] =226.0 - 190.0*Buf_FFT[i]/max;//нормировка по max, и инвертирование перед распечаткой for(x=1;x<254;x++){ Как это выглядит, видно на последней фото реального меандра 10МГц Илье очередной  и уважуха
--------------------
|
|
|
|
|
Apr 12 2008, 17:18
|

Знающий
   
Группа: Свой
Сообщений: 507
Регистрация: 15-04-06
Из: Германия
Пользователь №: 16 143

|
Нашёл более удачный способ обновления экрана. Мерцание экрана исчезло и смена кадра происходит практически незаметно . Картинка стала ярче. Код void spectrum() { unsigned int16 i=0,k=0;float32 max=0.0, s=0.0; unsigned int8 x=1 , y , yy;
for(i=0;i<256;i++){//переписываем порт в буфер #asm BCF 0x0F8B,2//LATC2=0;//Output_bit(READ_FIFO_A ,0);//PIN_C2. разрешить #endasm Buf_FFT[i] = input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1;//Output_bit(READ_FIFO_A ,1);//PIN_C2.запретить #endasm }
realFFT(Buf_FFT,256);k=0;//вызываем ДТФ(FFT)
for(i=0;i<256;i++){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Buf_FFT[0]=Buf_FFT[1]; for(i=0;i<255;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i]; //ищем max for(i=0;i<255;i++) Buf_FFT[i] =226.0 - 190.0*Buf_FFT[i]/max;//нормировка по max, и инвертирование перед распечаткой //-------------------- ОБНОВЛЕНИЕ ЭКРАНА --------------------------- setCursorAddress(0x2581); // чистить экран clear_graphic(); //-------------------- РИСОВАНИЕ --------------------------- for(x=1;x<254;x++){ yy=y; y = Buf_FFT[x]; if (yy>y) front(x,yy,y);// Рисуем фронт if (yy<y) spad(x,yy,y);// Рисуем спад pixel(x,y,1); // Рисуем вершину } }//--------------------------OK //##################################################
--------------------
|
|
|
|
|
Apr 12 2008, 20:21
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Очень рад за вас, что у вас хоть что-то получилось, но все равно остаются "тонкие моменты".... я смотрю вы буфер переопределили как signed int32 Buf_FFT[256]; Следовательно половина циклов потеряло смысл... Во первых, я не понял от куда взялся цикл: Код for(i=0;i<256;i++){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Я, конечно понимаю, что может быть для некоторых сигналов такая обработка выглядит "красивее" но здравого смыла в ней нет!!!! Должно быть: Код for(i=0;i<255;i+=2){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Короче, блин, я как всегда ПРОБУХАЛ все самое интересное..... И требую в студию последние варианты процедур, для очередной критики!  Цитата Слышал я краем уха, что в спектроанализаторах, для того , чтобы повысить точность показаний и убрать ложные сигналы с экрана, применяют какие-то оконные процедуры. Что это за зверь такой ? Есть такое, что конкретно хотите про это узнать???
|
|
|
|
|
Apr 12 2008, 21:38
|

Знающий
   
Группа: Свой
Сообщений: 507
Регистрация: 15-04-06
Из: Германия
Пользователь №: 16 143

|
Код Очень рад за вас, что у вас хоть что-то получилось, но все равно остаются "тонкие моменты".... спасибо, а какие имено? Цитата я смотрю вы буфер переопределили как signed int32 Buf_FFT[256]; Следовательно половина циклов потеряло смысл... никакая другая размерность не прокатила.Размер буфера пришлось уменьшить наполовину и как следствие это Код for(i=0;i<256;i++){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } потому что с этим правая половина, начиная со 128 пикселя по горизонтали выглядит ужасно Код for(i=0;i<255;i+=2){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } такой цикл хорошо работал, когда я использовал для прорисовки только левую половину экрана, но поскольку я растянулся на весь экран , пришлось немножко извратиться.Но уверяю вас, всё выглядит в наилучшем виде. Цитата Есть такое, что конкретно хотите про это узнать???  всё, что влезет в оставшиеся 4 кБ Код //#################################################################### // --------------- ЦИФРОВОЙ АНАЛИЗАТОР СПЕКТРА ---------------------- //Диапазон зависит от текущей частоты оцифровки (F) следующим образом: // от 0 до F/2 //промежуточные частоты равны: i*F/512, где 1<i<N/2 //#################################################################### void spectrum_analizator(void) // Рисуем спектр сигнала { unsigned int16 n=0;unsigned int8 amplitude; #asm BCF 0x0F8B,0 //Output_bit(PLCD_FIFO_RES,0);//PIN_C0 сброс FIFO в "0" BSF 0x0F8B,0 //Output_bit(PLCD_FIFO_RES,1);//PIN_C0 и разрешение на считывание BSF 0x0F8B,1 //Output_bit(READ_FIFO_B,1);//PIN_C1 запрет канала B #endasm //-------------------- синхронизация --------------------------- for(ever){ #asm BCF 0x0F8B,2//LATC2=0;//Output_bit(READ_FIFO_A ,0);//PIN_C2. разрешить #endasm amplitude=input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1;//Output_bit(READ_FIFO_A ,1);//PIN_C2.запретить #endasm amplitude = (amplitude > 200) ? 200 : amplitude; //ограничитель до выбранной величины amplitude = 255 - amplitude; // разворот на 180° по вертикали if (n++>MAXN) break;// В этой попытке смотреть дальше не имеет смысла if (syncA){//синхронизация по фронту A if(amplitude>sync_volume_A) continue; else break; }else{//синхронизация по спаду A if(amplitude<=sync_volume_A+115) continue; else break; } } spectrum();n=0;//Сюда попадем только если нашли фронт синхронизации }//--------------------------OK //#################################################################### void spectrum() { unsigned int16 i=0,k=0, max=0; unsigned int8 x=1 , y , yy;
for(i=0;i<256;i++){//переписываем порт в буфер #asm BCF 0x0F8B,2//LATC2=0;//Output_bit(READ_FIFO_A ,0);//PIN_C2. разрешить #endasm Buf_FFT[i] = input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1;//Output_bit(READ_FIFO_A ,1);//PIN_C2.запретить #endasm }
realFFT(Buf_FFT,256);k=0;//вызываем ДПФ(FFT)
for(i=0;i<256;i++){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Buf_FFT[0]=Buf_FFT[1]; for(i=0;i<255;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i]; //ищем max for(i=0;i<255;i++) Buf_FFT[i] =226 - 190*Buf_FFT[i]/max;//нормировка по max, и инвертирование перед распечаткой //-------------------- ОБНОВЛЕНИЕ ЭКРАНА --------------------------- setCursorAddress(0x2581); // чистить экран clear_graphic(); //-------------------- РИСОВАНИЕ --------------------------- for(x=1;x<254;x++){ yy=y; y = Buf_FFT[x]; if (yy>y) front(x,yy,y);// Рисуем фронт if (yy<y) spad(x,yy,y);// Рисуем спад pixel(x,y,1); // Рисуем вершину } }//--------------------------OK //####################################### вот фото меандра 4 МГц. Внизу шкала, всё соответствует реалиям.
--------------------
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|