|
SED1335,PIC18F4550 и LCD320x240, разбираем по косточкам модуль SED1335.c |
|
|
|
Jan 25 2008, 21:00
|

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

|
Привет народ.Вот решил я слепить себе нечто из указанных в теме компонентов.Нарисовал и изготовил макетку, красиво всё распаял и написал из надёрганных в сети кусков маленькую програмку для управления ЖКИ. Вначале, после нудного изучения даташитов никак не мог инициализировать ЖКИ, но потом разобрался что к чему и наконец он начал подавать признаки жизни и засветился. Компилятор, который я пользую - CCS, имеет в своём составе файл SED1335.C , но как я не пытался приспособить его, так и не смог.Порывшись в сети,я нашёл другой файл с таким же названием, но вроде бы не для ПИКов, а для чего-то другого.Однако , слегка подшаманив его, я смог встроить его в прогу и он заставил таки выдавать на экран символы в текстовом режиме(даже с возможностью размещения в заданое место) и переключаться в графический режим. И на этом всё и закончилось. Все попытки нарисовать линию или круг или просто точку,несмотря на множество примеров, я так и не смог. Позаимствовав из старого файла процедуру
void glcd_pixel(int16 x, int16 y, int1 color) { int8 data; int16 addr; // Calculate the byte address containing the pixel addr = GLCD_GRAPHICS_ADDR + (GLCD_WIDTH/8 * y + x/8); // Read the byte of data at the address data = getData(addr); // Turn the pixel on or off if(color == ON) bit_set(data, 7 - x%8); else bit_clear(data, 7 - x%8); // Write the new data byte to display memory setData(addr, data); }
я попробовал нарисовать на экране пиксель, но он вроде как нарисовался но разместился не в тех координатах, которые я указывал.Как я понимаю, за размещение отвечает строка //GLCD_GRAPHICS_ADDR- нач. адрес- 1200, GLCD_WIDTH- кол во символов в строке- 320 addr = GLCD_GRAPHICS_ADDR + (GLCD_WIDTH/8 * y + x/8); Может кто из вас раскомментирует эту странную формулу и подправит её, если она неправильная.
Сообщение отредактировал andreichk - Jan 25 2008, 21:03
--------------------
|
|
|
|
|
 |
Ответов
(135 - 149)
|
Apr 8 2008, 08:47
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Во первых уберите [x] при вызове функции а во вторых, я уже исправил предыдущий пост, нужно сделать так: Код four2(Buf_FFT,128,1)
|
|
|
|
|
Apr 8 2008, 10:09
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Цитата(andreichk @ Apr 8 2008, 17:00)  всё исправил, но всё равно рисует просто кривую еще раз посмотрел на вашу функцию four2(), во первых это опять функция для комплексного преобразования фурье, вам нужно преобразование для реальных чисел (гдето раньше вы уже выкладывали нужную процедуру) Хотя... лучше возьмите вот эту: Код void realFFT(float a[], unsigned int tnn, char inversefft) { 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,tempr,tempi; if( tnn==1 )return; if( !inversefft ){ ttheta = 6.28318530717959/tnn; c1 = 0.5; c2 = -0.5; }else{ ttheta = 6.28318530717959/tnn; c1 = 0.5; c2 = 0.5; ttheta = -ttheta; twpr = -2.0*(sin(0.5*ttheta))*(sin(0.5*ttheta)); 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] = c1*(h1r+a[1]); a[1] = c1*(h1r-a[1]); } if( inversefft ) isign = -1; else 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; } if( inversefft ) { for(i = 1; i <= 2*nn; i++) { a[i-1] = a[i-1]/nn; } } if( !inversefft ) { 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]; } } вызывайте ее так: Код realFFT(Buf_FFT, 256, 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]=0; Затем распечатайте на экран первые 128 значений буффера Только перед распечаткой нужно еще пронормировать на максимальное значение (чтобы было равно высоте экрана) Да, еще старайтесь чтобы на экран умещалось побольше периодов сигнала, чтобы лучше увидеть пик Кстати, почитайте, очень похожий проект: http://rf.atnn.ru/s10/digital_osc.htmlтам и про FFT че-то написано, даже есть исходник в низу страницы.
|
|
|
|
|
Apr 8 2008, 11:57
|

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

|
экран замирает и ничего не происходит Код void spectrum_analizator(unsigned int8 y_pos) {unsigned int8 x=0,y,yy,k=0,i=0;unsigned int16 n=0; //----------------------------------------------------------------------------- if (n++>8192){// Если дошли до сюда, значит не удалось найти период return;// Занулим частоту (типа не посчитали... ) } //----------------------------------------------------------------------------- for(x=0;x<255;x++){ #asm BCF 0x0F8B,2//LATC2=0; #endasm Buf[x]=255 - input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1; #endasm } for(x=0;x<255;x++){ Buf_FFT[x]=Buf[x];// } realFFT(Buf_FFT, 256, 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]=0;
for(x=0;x<128;x++){ yy=y; y = Buf_FFT[x] + y_pos;// y = (y > 200) ? 200 : y; //ограничитель до выбранной величины if (yy>y) front(x,yy,y);// Рисуем фронт if (yy<y) spad(x,yy,y); // Рисуем спад pixel(x,y,1); // Рисуем вершину } setCursorAddress(0x2581); clear_graphic(); } //######################################### закрыл это- опять стала рисовать просто импульсы Код //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); //} изменил размерность переменной i на unsigned int16- на экране появились импульсы в два раза уже , чем обычные и прим. на одну треть выше
Сообщение отредактировал andreichk - Apr 8 2008, 11:58
--------------------
|
|
|
|
|
Apr 8 2008, 12:42
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Что-то вы шаманством каким-то занимаетесь... Не вижу у вас нормировки сигнала.... Давайте сделаем так: Код signed int16 Buf_FFT[512]; // переобъявим массив как int
void spectrum_analizator(void) { unsigned int8 x=0,y,yy; unsigned int16 i=0,max=0,k=0;
setCursorAddress(0x2581); //Я так понимаю чистить экран нужно перед отрисовкой а не после... clear_graphic();
#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(i=0;i<512;i++){ #asm BCF 0x0F8B,2//LATC2=0; #endasm Buf_FFT[i]=input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1; #endasm } realFFT(Buf_FFT, 512, 0); 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]=0; 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]=236-(Buf_FFT[i]*230/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); // Рисуем вершину } } а процедуру realFFT переобъявим следующим образом: Код void realFFT(signed int16 a[], unsigned int tnn, char inversefft)
|
|
|
|
|
Apr 8 2008, 13:17
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Цитата(andreichk @ Apr 8 2008, 20:55)  по-прежнему просто узкие , но очень большие по аплитуде импульсы. Они теперь даже не влезают в экран. зы.я не шаман,теперь я как все зелёный человечек. Хачу видеть 2 картинки - исходного сигнала и его спектра. Не меняя частоту тактирования FIFO. Сделайте так чтобы на экран при этом входило периодов 8 примерно
|
|
|
|
|
Apr 8 2008, 14:17
|

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

|
выставил сейчас прямоугольники 400кГц, развёртка на 3.2мксек.амплитуда прим. 3 вольта одно могу сказать пока, они в два раза Уже и по аплитуде скачут то вверх, то вниз.Рисуются медленней и плохо синхронизируются как в режиме спектра, так и в осциллографическом. вот и фотки 1 скоп 2 спектр хачу таааак
--------------------
|
|
|
|
|
Apr 8 2008, 15:11
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Цитата(andreichk @ Apr 8 2008, 22:17)  выставил сейчас прямоугольники 400кГц, развёртка на 3.2мксек.амплитуда прим. 3 вольта одно могу сказать пока, они в два раза Уже и по аплитуде скачут то вверх, то вниз.Рисуются медленней и плохо синхронизируются как в режиме спектра, так и в осциллографическом. вот и фотки 1 скоп 2 спектр хачу таааак  Да это у вас совсем не спектр... Приведите в итоге весь цикл как вы получаете и отрисовываете спектр. Не понял что значит рисуется медленней? У вас чтоли одновременно и спектр и сигнал рисуется, или я че-то не догоняю....
|
|
|
|
|
Apr 8 2008, 15:33
|

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

|
вызываем процедуру void spectr_A(unsigned int8 y_pos_A) Код void spectr_A(unsigned int8 y_pos_A) // пытаемся нарисовать спектр { unsigned int16 n=0,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_analizator(y_pos_A,n);//Сюда попадем только если нашли фронт синхронизации }//--------------------------OK //#################################################################### void spectrum_analizator(unsigned int8 y_pos,unsigned int16 n) { unsigned int8 x=0,y,yy; unsigned int16 i=0,max=0,k=0; //----------------------------------------------------------------------------- if (n++>8192){// Если дошли до сюда, значит не удалось найти период return;// Занулим частоту (типа не посчитали... ) } //-----------------------------------------------------------------------------
#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(i=0;i<512;i++){ #asm BCF 0x0F8B,2//LATC2=0; #endasm Buf_FFT[i]=input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1; #endasm } realFFT(Buf_FFT, 512, 0); 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]=0; 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]=236-(Buf_FFT[i]*230/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); // Рисуем вершину } setCursorAddress(0x2581); // чистить экран clear_graphic(); } ну насчёт медленнее рисует-это я наверное погорячился.просто чем больше развёртка, тем медленнее рисует. или чем больше элементов для рисования, тем больше времени на это требуется. #define EVER ;; //приколы нашего двора
--------------------
|
|
|
|
|
Apr 9 2008, 02:56
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Так, на вид, почти все нормально. Но давайте для на чала отладим сам алгоритм FFT. Для этого сделаем тестовую процедуру, и заполним массив известным меандром: (я специально взял такой период (28 отсчетов) чтобы в 512 отсчетов не укладывалось ровное число периодов, иначе картинка будет слишком красивая, и далекая от реальности) Код 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;} }
realFFT(Buf_FFT, 512, 0); 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]=236-(Buf_FFT[i]*230/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); // Рисуем вершину } } Я специально не поленился, и написал программку для Borland. Все один в один. Получились следующие картинки: СИГНАЛ:
СПЕКТР:
P.S. Хочу посмотреть что получиться у вас
|
|
|
|
|
Apr 9 2008, 06:53
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Цитата(andreichk @ Apr 9 2008, 14:39)  фотки пока нет. график представляет из себя следующее, слева-направо с отступом от лев.края в 10 пикселей длинная закрашенная палка на весь экран толщиной в 4 пикселя,далее 17 прямоугольников при по 8 пикселей шапка 8 пикселей яма . Всё это рисуется от самого низа экрана Что-то по описанию явно бред какой-то.....  приведите еще раз ф-ию realFFT(); Просто, не понятно в чем косяк - процедурка то ведь рабочая. Я же проверил...
|
|
|
|
|
Apr 10 2008, 01:37
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 1-12-05
Из: Иркутск
Пользователь №: 11 630

|
Да... такое ощущение что у вас вообще буфер не обрабатывается.... Цитата(andreichk @ Apr 10 2008, 07:44)  первое фото было получено при обозначении процедуры void realFFT(char *a, unsigned int tnn, char inversefft) Так точно не правильно, лучше попробывать так: void realFFT(int *a, unsigned int tnn, char inversefft)еще в функции realFFT() есть цикл: while(m>=2&&j>m)попробуйте заменить на: while((m>=2)&&(j>m))также в процедуре есть float переменные tempr и tempi. сделайте их int: int tempr,tempi;Цитата(andreichk @ Apr 10 2008, 07:44)  я тут подумал и мы решили, а вообще в каком диапазоне частот работает наш спектроскоп? Диапазон зависит от текущей частоты оцифровки ( F) следующим образом: от 0 до F/2промежуточные частоты равны: i*F/512, где 1<i<N/2 Цитата(andreichk @ Apr 10 2008, 07:44)  И ещё вопрос- как эта функция передаёт значения в буфер? void realFFT(signed int16 a[] , unsigned int tnn, char inversefft) Мы же ей передаем указатель на начало буфера. она присваивает его a. А дальше тупо обращается по индексам... А вообще грешить помоему уже надо на компилятор.... все-таки приведите текст вашей realFFT() может че-то в ней случайно изменилось.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|