andreichk 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба может я не прав, но мне кажется, что такие вычисления, вплоть до самого момента рисования, нужно производить только с переменными типа float, а не int.И только потом приводить их к int, иначе весь этот процесс округляется до невозможности. Провёл все последние изменения- результат никакой, то есть никаких изменений :( попробовал заменить процедуру ффт на всякие другие- тоже ничего не изменилось. Мы же ей передаем указатель на начало буфера. она присваивает его a. А дальше тупо обращается по индексам... сдаётся мне, что этого как раз и не происходит,так как при закоментировании строки //four2(Buf_FFT, 512, 0); в тестовой процедуре не приводит ни к каким изменениям. вывод- обращение к процедуре преобразования не изменяет содержимое буфера :( нужно копать глубже Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба может я не прав, но мне кажется, что такие вычисления, вплоть до самого момента рисования, нужно производить только с переменными типа float, а не int.И только потом приводить их к int, иначе весь этот процесс округляется до невозможности. Нет, у вас АЦП всего 8 разрядов. int предостаточно (тем более у вас памяти нехватит под массив float :) ) А вычистения для конкретной точки делаються во float вывод- обращение к процедуре преобразования не изменяет содержимое буфера :( Короче, если у вас такая хрень не проканает, то выкидывайте свой компилятор куда подальше: void test(int *a){ unsigned int i=0; for(i=0;i<256;i++){ a[i]=100; } } void testspectr(void) { unsigned int8 x=0,y,yy; unsigned int16 i=0,max=0,k=0; setCursorAddress(0x2581); // чистить экран clear_graphic(); for(i=0;i<512;i++){ if (k<14) {Buf_FFT[i]=10;k++;} else if(k<28) {Buf_FFT[i]=230;k++;} else {Buf_FFT[i]=10;k=1;} } test(Buf_FFT); 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); // Рисуем вершину } } процедура должна заменить значение первых 256 байт массива на 100. Т.е. на экране получится линия Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба с прямой не проканал(возможно не попал в нужный диапазон по оси у, но зато проканал с синусной функцией void test(int *a){ unsigned int16 i=0;float s=0; for(i=0;i<256;i++){ a[i]=120 - 100.0*(sin( s+=0.1)); } } левая половина синус 4 периода, правая меандр тоже 4 периода.Выкидывать или помучаемся ищо ? :07: Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба Синус нарисовался точно в центре экрана- 8 периодов. Выкидывать или помучаемся ищо ? :07: Значит адресация работает... Вы все-таки выложите процедуру realFFT() которая используется у вас на данный момент Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба Для начала, давайте уберем лишнее (то что касается обратного преобразования, все равно мы его не используем) что бы глаза не мозолило: void realFFT(int *a, unsigned int tnn) { float twr,twi,twpr,twpi,twtemp,ttheta; int i,i1,i2,i3,i4; float c1, c2, h1r, h1i, h2r,h2i,wrs, wis; int nn,ii, jj,n, mmax, m,j,istep,isign; float wtemp, wr,wpr, wpi, wi,theta; int tempr,tempi; if( tnn==1 )return; ttheta = 6.28318530717959/tnn; c1 = 0.5; c2 = -0.5; isign = 1; n = tnn; nn = tnn/2; j = 1; for(ii = 1; ii <= nn; ii++) { i = 2*ii-1; if( j>i ) { tempr = a[j-1]; tempi = a[j]; a[j-1] = a[i-1]; a[j] = a[i]; a[i-1] = tempr; a[i] = tempi; } m = n/2; while((m>=2)&&(j>m)) { j = j-m; m = m/2; } j = j+m; } mmax = 2; while(n>mmax) { istep = 2*mmax; theta = 6.28318530717959/(isign*mmax); wpr = -2.0*(sin(0.5*theta))*(sin(0.5*theta)); wpi = sin(theta); wr = 1.0; wi = 0.0; for(ii = 1; ii <= mmax/2; ii++) { m = 2*ii-1; for(jj = 0; jj <= (n-m)/istep; jj++) { i = m+jj*istep; j = i+mmax; tempr = wr*a[j-1]-wi*a[j]; tempi = wr*a[j]+wi*a[j-1]; a[j-1] = a[i-1]-tempr; a[j] = a[i]-tempi; a[i-1] = a[i-1]+tempr; a[i] = a[i]+tempi; } wtemp = wr; wr = wr*wpr-wi*wpi+wr; wi = wi*wpr+wtemp*wpi+wi; } mmax = istep; } twpr = -2.0*(sin(0.5*ttheta))*(sin(0.5*theta)); twpi = sin(ttheta); twr = 1.0+twpr; twi = twpi; for(i = 2; i <= tnn/4+1; i++) { i1 = i+i-2; i2 = i1+1; i3 = tnn+1-i2; i4 = i3+1; wrs = twr; wis = twi; h1r = c1*(a[i1]+a[i3]); h1i = c1*(a[i2]-a[i4]); h2r = -c2*(a[i2]+a[i4]); h2i = c2*(a[i1]-a[i3]); a[i1] = h1r+wrs*h2r-wis*h2i; a[i2] = h1i+wrs*h2i+wis*h2r; a[i3] = h1r-wrs*h2r+wis*h2i; a[i4] = -h1i+wrs*h2i+wis*h2r; twtemp = twr; twr = twr*twpr-twi*twpi+twr; twi = twi*twpr+twtemp*twpi+twi; } h1r = a[0]; a[0] = h1r+a[1]; a[1] = h1r-a[1]; } А теперь, у вас же есть возможность отладки программы, хотя бы в симуляторе? Давайте ставте breakpoint, и следите как выполняются операции в этой функции и изменяются ли данные в буффере Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба симулятор без подключения какой-то оригинальной хрени к ком или усб порту не работает Я говорю не про "железный" отладчик (ICD 2). А про эмуляцию работу PICа вашим CCS. посмотрите, гденить наверное должна быть галочка для настройки. Тогда просто делаете чтонить типа Set PC at Cursor напротив вызова функции testspectr(). А дальше по шагам... Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба да нету там нифига такого, я бы уже его давно обнаружил, обычно симулятор сидит на кнопках F7 F8. ОЧЕНЬ ХРЕНОВО Чтобы вым еще посоветовать.... у меня такое ощущение, что он вообще в этой процедуре какой-то хренью занимаеться... можно попробывать повставлять в разных местах процедуры RealFFT() return-ы и распечатывать на экран получившиеся данные... или например в этой же процедуре попробывать поставить в разных местах поочереди какиенибудь операции над данными.... и тоже выходить... короче нужно отлаживать ее как-то... Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба непонятки с размерностью некоторых переменных realFFT(Buf_FFT, 512); а в процедуре она unsigned int8 unsigned int8 занимает от 0 до 255, значит н и 512 ни 256 уже не катит, а 255 не кратно 2.Остаётся только одно макс.допустимое значение- 128. и при нём рисуется что-то отдалённо напоминающее спектр, но только при искусственном меандре.При заполнении буфера реальным сигналом от ФИФО- опять полная каша Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба непонятки с размерностью некоторых переменных realFFT(Buf_FFT, 512); а в процедуре она unsigned int8 несколькими постами выше написано: void realFFT(int *a, unsigned int tnn) и где здесь unsigned int8??? unsigned int === WORD === 2 байта Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба Илья, 512 не попадает ни в инт ни в инт8(оба в CCS равнозначны, тоже с unsigned). -127 +127 или 0-255 соотв. в тестовой процедуре вызов такой realFFT(Buf_FFT, 512);unsigned int16 или просто int16. в самой процедуре естьместо, где сравнивается 512 с переменной int (n = tnn;) фигня получается. я об этом Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 10 апреля, 2008 Опубликовано 10 апреля, 2008 · Жалоба Илья, 512 не попадает ни в инт ни в инт8(оба в CCS равнозначны, тоже с unsigned). Бред какой-то :07: Тогда меняйте все int на signed int16 а все unsigned int на unsigned int16 Везде, включая определение массива Buf_FFT[] Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба Итак, при заданных параметрах меандра for(i=0;i<512;i++){ if (k<14) {Buf_FFT[i]=10;k++;} else if (k<28) {Buf_FFT[i]=230;k++;} else {Buf_FFT[i]=10;k=1;} } получилась вот такая картинка. Во всяком случае видно, что есть привязка к начальному уровню и всплески имеют постояную амплитуду. теперь о размерности переменных void realFFT(signed int16 *a, unsigned int16 tnn) { float twr,twi,twpr,twpi,twtemp,ttheta; signed int16 i,i1,i2,i3,i4; float c1, c2, h1r, h1i, h2r,h2i,wrs, wis; signed int16 nn,ii, jj,n, mmax, m,j,istep,isign; float wtemp, wr,wpr, wpi, wi,theta, tempr,tempi; signed int16 Buf_FFT[512]; // переобъявим массив как int16 и процедура отрисовки целиком unsigned int co=0; void testspectr(unsigned int16 n) { unsigned int16 i=0,k=0,max=0;float s=0; unsigned int8 x=1 , y , yy; // for(i=0;i<512;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 // } //----------------------------------------------------------------------------- co++; if (co==2){ setCursorAddress(0x2581); // чистить экран clear_graphic();co=0; } for(i=0;i<512;i++){ if (k<14) {Buf_FFT[i]=10;k++;} else if (k<28) {Buf_FFT[i]=230;k++;} else {Buf_FFT[i]=10;k=1;} } //for(i=0;i<512;i++) // { // Buf_FFT[i]= 120 + 100.0*(sin( s+=0.02)); // } realFFT(Buf_FFT, 512); for(i=0;i<512;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<256;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i]; //ищем max for(i=0;i<256;i++) Buf_FFT[i]=226.0 - (200.0*Buf_FFT[i]/max);//нормировка по max, и инвертирование перед распечаткой 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); // Рисуем вершину } } //########################################## правая картинка спектр-синуса(параметры в процедуре). Палки какие-то частые. Какие будут предложения? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба Картина, все еще далека от нужной. В спектре синуса должна быть только одна палка, а спектр меандра долен быть один в один как у меня. Нашел косяк: перед циклом for(i=0;i<512;i+=2){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } нужно занулить k: k=0; Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба странно, но зануление никак не повлияло .Вернее совсем немножечко, в самом начале внизу слева, вместо сплошняка палка вниз до начального уровня. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба странно, но зануление никак не повлияло . Должно было повлиять на первые отсчеты, и вся картинка должна была немного сдвинуться в право, в зависимости от того при каком значении k начался цикл (для синуса, конечно изменений никаких небудет) Для синуса, вы мало чего увидите, т.к. слишком низкая частота. Картинка вот: Сделайте частоту повыше: 120 + 100.0*(sin( s+=0.5)); Должно получиться вот так: Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться