Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SED1335,PIC18F4550 и LCD320x240
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > PIC
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9
andreichk
может я не прав, но мне кажется, что такие вычисления, вплоть до самого момента рисования, нужно производить только с переменными типа float, а не int.И только потом приводить их к int, иначе весь этот процесс округляется до невозможности.
Провёл все последние изменения- результат никакой, то есть никаких изменений sad.gif
попробовал заменить процедуру ффт на всякие другие- тоже ничего не изменилось.

Цитата
Мы же ей передаем указатель на начало буфера. она присваивает его a. А дальше тупо обращается по индексам...

сдаётся мне, что этого как раз и не происходит,так как при закоментировании строки
//four2(Buf_FFT, 512, 0); в тестовой процедуре не приводит ни к каким изменениям.
вывод- обращение к процедуре преобразования не изменяет содержимое буфера sad.gif
нужно копать глубже help.gif
Ilya_A
Цитата(andreichk @ Apr 10 2008, 15:12) *
может я не прав, но мне кажется, что такие вычисления, вплоть до самого момента рисования, нужно производить только с переменными типа float, а не int.И только потом приводить их к int, иначе весь этот процесс округляется до невозможности.

Нет, у вас АЦП всего 8 разрядов. int предостаточно (тем более у вас памяти нехватит под массив float smile.gif )

А вычистения для конкретной точки делаються во float

Цитата(andreichk @ Apr 10 2008, 15:12) *
вывод- обращение к процедуре преобразования не изменяет содержимое буфера sad.gif

Короче, если у вас такая хрень не проканает, то выкидывайте свой компилятор куда подальше:

Код
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
с прямой не проканал(возможно не попал в нужный диапазон по оси у, но зато проканал с синусной функцией
Код
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.gif
Ilya_A
Цитата(andreichk @ Apr 10 2008, 16:03) *
Синус нарисовался точно в центре экрана- 8 периодов. Выкидывать или помучаемся ищо ? 07.gif

Значит адресация работает...

Вы все-таки выложите процедуру realFFT() которая используется у вас на данный момент
Ilya_A
Для начала, давайте уберем лишнее (то что касается обратного преобразования, все равно мы его не используем) что бы глаза не мозолило:
Код
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, и следите как выполняются операции в этой функции и изменяются ли данные в буффере
Ilya_A
Цитата(andreichk @ Apr 10 2008, 16:30) *
симулятор без подключения какой-то оригинальной хрени к ком или усб порту не работает

Я говорю не про "железный" отладчик (ICD 2). А про эмуляцию работу PICа вашим CCS. посмотрите, гденить наверное должна быть галочка для настройки.

Тогда просто делаете чтонить типа Set PC at Cursor напротив вызова функции testspectr(). А дальше по шагам...
Ilya_A
Цитата(andreichk @ Apr 10 2008, 16:49) *
да нету там нифига такого, я бы уже его давно обнаружил, обычно симулятор сидит на кнопках F7 F8.

ОЧЕНЬ ХРЕНОВО

Чтобы вым еще посоветовать....

у меня такое ощущение, что он вообще в этой процедуре какой-то хренью занимаеться... можно попробывать повставлять в разных местах процедуры RealFFT() return-ы и распечатывать на экран получившиеся данные...

или например в этой же процедуре попробывать поставить в разных местах поочереди какиенибудь операции над данными.... и тоже выходить...

короче нужно отлаживать ее как-то...
andreichk
непонятки с размерностью некоторых переменных
realFFT(Buf_FFT, 512);
а в процедуре она unsigned int8
unsigned int8 занимает от 0 до 255, значит н и 512 ни 256 уже не катит, а 255 не кратно 2.Остаётся только одно макс.допустимое значение- 128. и при нём рисуется что-то отдалённо напоминающее спектр, но только при искусственном меандре.При заполнении буфера реальным сигналом от ФИФО- опять полная каша help.gif
Ilya_A
Цитата(andreichk @ Apr 10 2008, 21:53) *
непонятки с размерностью некоторых переменных
realFFT(Buf_FFT, 512);
а в процедуре она unsigned int8

несколькими постами выше написано:
Код
void realFFT(int *a, unsigned int tnn)

и где здесь unsigned int8???

unsigned int === WORD === 2 байта
andreichk
Илья, 512 не попадает ни в инт ни в инт8(оба в CCS равнозначны, тоже с unsigned).
-127 +127 или 0-255 соотв.
в тестовой процедуре вызов такой realFFT(Buf_FFT, 512);unsigned int16 или просто int16.
в самой процедуре естьместо, где сравнивается 512 с переменной int (n = tnn;) фигня получается. я об этом
Ilya_A
Цитата(andreichk @ Apr 11 2008, 00:34) *
Илья, 512 не попадает ни в инт ни в инт8(оба в CCS равнозначны, тоже с unsigned).

Бред какой-то 07.gif

Тогда меняйте все int на signed int16
а все unsigned int на unsigned int16

Везде, включая определение массива Buf_FFT[]
andreichk
Итак, при заданных параметрах меандра
Код
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);           // Рисуем вершину
                   }
}
//##########################################

правая картинка спектр-синуса(параметры в процедуре).
Палки какие-то частые.
Какие будут предложения?
Ilya_A
Картина, все еще далека от нужной.
В спектре синуса должна быть только одна палка, а спектр меандра долен быть один в один как у меня.

Нашел косяк:
перед циклом
Код
  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
странно, но зануление никак не повлияло .Вернее совсем немножечко, в самом начале внизу слева, вместо сплошняка палка вниз до начального уровня.
Ilya_A
Цитата(andreichk @ Apr 11 2008, 16:44) *
странно, но зануление никак не повлияло .

Должно было повлиять на первые отсчеты, и вся картинка должна была немного сдвинуться в право, в зависимости от того при каком значении k начался цикл (для синуса, конечно изменений никаких небудет)

Для синуса, вы мало чего увидите, т.к. слишком низкая частота. Картинка вот:
Нажмите для просмотра прикрепленного файла

Сделайте частоту повыше:
120 + 100.0*(sin( s+=0.5));
Должно получиться вот так:
Нажмите для просмотра прикрепленного файла
andreichk
поменял значение синуса.Результат- практически сплошной частокол.палки имеют разную высоту

Илья, чем вы такие красивые графики строите?

мне кажется , что некорректно выполняется функция
Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5);
В справке написано , что обе переменные должны быть float, а у нас только одна из них
Ilya_A
Цитата(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)
andreichk
автоматом нет наверное, но есть другой механизм приведения
Buf_FFT[k++]=pow((float)(Buf_FFT[i]*Buf_FFT[i]+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5);
я попробовал- толку мало
борланд где-то валялся,не знаю теперь где он. а exe-шник отдельно от него работает? если да, то давайте
Ilya_A
Вот программка:
Нажмите для просмотра прикрепленного файла

В левый столбец забейте исходный сигнал.
Укажите N - число точек в сигнале (должно быть 2^n)
Для подсчета нажмите CALC

Программка слеплена за несколько минут, такчто извиняйте). Никаких защит от дурака в программке конечно нет, такчто следите за тем, что вы вводите.

Программа специально все расчеты делает в unsigned int. Для того чтобы можно было сравнить с контроллером. Также перед выводом спектр нормируется на максимльное значение 230


Вот исходник:
Нажмите для просмотра прикрепленного файла
Найдите десять отличий)
andreichk
мысли поводу формулы
Buf_FFT[k++]=pow((float)(Buf_FFT[i]*Buf_FFT[i]+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5);
255*255 + 255*255=130050 тут уже никакой int16 не справится, только Long или float
скорее всего из-за этого на экране столько лишних палок
Ilya_A
Тогда сделайте так:

Buf_FFT[k++]=pow((float)(Buf_FFT[i])*Buf_FFT[i]+(float)(Buf_FFT[i+1])*Buf_FFT[i+
1],0.5);
Ilya_A
Цитата(andreichk @ Apr 12 2008, 00:19) *
так я уже пробовал, не помогает

Значит проблема не в этом.... Как видите код абсолютно рабочий, неужели компилер гонит? Может в нем отключить какуюнибудь оптимизацию?
andreichk
Считаю что нужно точно определиться с типами переменных и диапазоном их значений.
Итак,
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 ; ???
Иначе получается полная ерунда, потому что ПИК где-то искажает результаты вычислений.
andreichk
Ура !!!! Совершенно неожиданно нашёл решение проблемы.
Самым подходящим типом переменных для буфера оказался
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МГц

Илье очередной a14.gif и уважуха beer.gif
andreichk
Нашёл более удачный способ обновления экрана.
Мерцание экрана исчезло и смена кадра происходит практически незаметно . Картинка стала ярче.
Код
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
//##################################################
andreichk
Слышал я краем уха, что в спектроанализаторах, для того , чтобы повысить точность показаний и убрать ложные сигналы с экрана, применяют какие-то оконные процедуры. Что это за зверь такой ?
Ilya_A
Очень рад за вас, что у вас хоть что-то получилось, но все равно остаются
"тонкие моменты"....

я смотрю вы буфер переопределили как 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);
}


Короче, блин, я как всегда ПРОБУХАЛ все самое интересное..... И требую в
студию последние варианты процедур, для очередной критики! wink.gif

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

Есть такое, что конкретно хотите про это узнать??? wink.gif
andreichk
Код
Очень рад за вас, что у вас хоть что-то получилось, но все равно остаются
"тонкие моменты"....

спасибо, а какие имено?

Цитата
я смотрю вы буфер переопределили как 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);
}
такой цикл хорошо работал, когда я использовал для прорисовки только левую половину экрана, но поскольку я растянулся на весь экран , пришлось немножко извратиться.Но уверяю вас, всё выглядит в наилучшем виде.

Цитата
Есть такое, что конкретно хотите про это узнать??? wink.gif
всё, что влезет в оставшиеся 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 МГц. Внизу шкала, всё соответствует реалиям.
andreichk
Вторая часть марлезонского балета
http://ru.youtube.com/watch?v=x_T5DVZDE3w
andreichk
Насколько я понял, если теперь применить обратное преобразование Фурье, то можно восстановить и вывести на экран первоначальную форму сигнала? Если это так , то можно считать, что верхняя частота осциллографа поднимается до 40 МГц ?
Ilya_A
Цитата(andreichk @ Apr 15 2008, 01:31) *
Насколько я понял, если теперь применить обратное преобразование Фурье, то можно восстановить и вывести на экран первоначальную форму сигнала?

Получить первоначальную форму сигнала, можно только, если сразу же после прямого преобразования сделать обратное. А после всего того, что мы с ним сделали, ничего хорошего из обратного преобразования у вас не выйдет.
Цитата(andreichk @ Apr 15 2008, 01:31) *
Если это так , то можно считать, что верхняя частота осциллографа поднимается до 40 МГц ?

А вот этого вывода я совсем не понял.... wacko.gif


Насчет предыдущих вопросов: мне пока совсем некогда, даже видео еще не скачал... так что как освобожусь посмотрю поподробнее...
andreichk
Цитата
Получить первоначальную форму сигнала, можно только, если сразу же после прямого преобразования сделать обратное. А после всего того, что мы с ним сделали, ничего хорошего из обратного преобразования у вас не выйдет.

ну дык никто же не мешает сделать это сразу, хотя бы из любопытства

Цитата
А вот этого вывода я совсем не понял.... wacko.gif

Ну как же? Если мы с помощью прямого преобразования сигнала можем нарисовать палку аж до 40 Мгц, то разве после обратного мы не можем нарисовать исходный сигнал этой же частоты, да ещё так, чтобы его можно было разглядеть? 07.gif
andreichk
Вввиду явной нехватки памяти решил я заменить PIC18F4550 на PIC18F4680. Он тоже 44ногий , но имеет в два раза больше памяти.
А что скажет купечество ? или 8BIT FLASH MCU,18F4685,TQFP44

http://www.ixbt.com/staticnews/06/56/99.html
VDLab
Цитата(andreichk @ Apr 15 2008, 20:10) *
Вввиду явной нехватки памяти решил я заменить PIC18F4550 на PIC18F4680. Он тоже 44ногий , но имеет в два раза больше памяти.
А что скажет купечество ? или 8BIT FLASH MCU,18F4685,TQFP44

http://www.ixbt.com/staticnews/06/56/99.html

Тогда уж лучше на 24 серию переходить. Тот же 24FJ64GA004 - 64 кило флеша, 8 кило оперативы, 16 мипсов, да и разрядность больше, вычисления соответственно значительно быстрее будут производится. Опять же периферия побогаче, ну и цена - тут 18я серия в пролете.
andreichk
даташит бы на него почитать
если это они, то мне это не подходит
http://www.mercateo.com/kw/pic24fj64ga004/...4fj64ga004.html
1. кол-во ног не соответствует старой печатке
2.тактовая частота у них всего 32 МГц
Не, нихацу wink.gif
VDLab
Дык а как же, семейство то другое, а развести печатку на те же 44 ноги(ну или больше) ИМХО не проблема.
Насчет частоты - а чем мало 32 Мгц? Мало 16 мипсов, возьмите 24H серию, там 40, только периферия победнее будет,зато DMA есть.
З.Ы. все даташиты обычно берутся у производителя
Ilya_A
Цитата(VDLab @ Apr 16 2008, 06:17) *
Ну как же? Если мы с помощью прямого преобразования сигнала можем нарисовать палку аж до 40 Мгц, то разве после обратного мы не можем нарисовать исходный сигнал этой же частоты, да ещё так, чтобы его можно было разглядеть?

И что у вас поменялось? Вы можете его нарисовать и так, без всяких преобразований туда обратно....
Вот чем может быть действительно полезно обратное преобразование, так это тем, что можно после прямого сделать цифровую фильтрацию сигнала, а затем уже преобразовывать обратно!

Цитата
Вввиду явной нехватки памяти решил я заменить PIC18F4550 на PIC18F4680. Он тоже 44ногий , но имеет в два раза больше памяти.
А что скажет купечество ? или 8BIT FLASH MCU,18F4685,TQFP44

Под вашу задачу я бы однозначно взял: dsPIC33FJ128GP206. Вот на нем можно реально замутить качественную и скоростную цифровую обработку сигнала! Да и цена подходящая - на trt.ru в розницу за 129 р. отдают: http://trt.ru/Stock.php?Part=300

Цитата
если это они, то мне это не подходит
http://www.mercateo.com/kw/pic24fj64ga004/...4fj64ga004.html
1. кол-во ног не соответствует старой печатке

Если же хотите Pin to Pin совместимость, тогда берите лучше: PIC18F4515 у него RAM почти 4К а цена в 1,5 раза дешевле. (ROM 48K)

Если же хотите еще побольше ROM тогда PIC18F4610, у него 64K. Цена тоже ниже вашего.

Если еще необходимо наличие EEPROM, тогда PIC18F4620
andreichk
Всё , выбор пал на ПИК18Ф4685, он уже впаян и загружен. Процедуры восстановлены до состояния , указанного сенсеем Ильёй. теперь спектр выглядит значительно красивее, так как имеет бОльшее кол-во отсчётов. a14.gif
Проц имеет 3.5 кб ОЗУ и 96 кб ROM. Появилось много свободного места для дальшейших эксперементов. Я думаю, что этот ПИК вполне подходит для такого любительского проекта, а более совершенные процессоры оставим для будущих поколений.Пока достаточно того, что уже несколько пользователей И-нета изьявили желание повторить и развивать этот проект.Лично я считаю это своей маленькой победой над злобными и жадными буржуями.
Теперь по делу, как вы считаете,эти самые оконные функции нужны или в принципе можно обойтись без них?
Если нет, то настало время вернуться к нашим баранам, то есть кнопкам.Всвязи с увелечением кол-ва последних, было замечено, что работать они стали с заметными тормозами,это в первую очередь касается тех кнопок, которые посылают хитрый код в ПИК.
Мне тут на дружественном форуме предлагали на простеньком ПИКе типа 16Ф84 смастерить кнопочный шифратор и по ISP гнать с него код в главный ПИК.Как вам такая идея? Мне не очень, я всё ж таки хочу ПЛИСку использовать для этого дела.
Ilya_A
Цитата(andreichk @ Apr 18 2008, 02:24) *
Всё , выбор пал на ПИК18Ф4685, он уже впаян и загружен. Процедуры восстановлены до состояния , указанного сенсеем Ильёй. теперь спектр выглядит значительно красивее, так как имеет бОльшее кол-во отсчётов. a14.gif

Вери Гуд )
Цитата
Проц имеет 3.5 кб ОЗУ и 96 кб ROM. Появилось много свободного места для дальшейших эксперементов. Я думаю, что этот ПИК вполне подходит для такого любительского проекта, а более совершенные процессоры оставим для будущих поколений.Пока достаточно того, что уже несколько пользователей И-нета изьявили желание повторить и развивать этот проект.Лично я считаю это своей маленькой победой над злобными и жадными буржуями.

Поздравляю beer.gif
Цитата
Теперь по делу, как вы считаете,эти самые оконные функции нужны или в принципе можно обойтись без них?

Эффект частокола- Если синусоидальный сигнал имеет целое число периодов во временной области, спектр мощности такого сигнала, полученный с прямоугольным окном, будет иметь острый пик, в точности соответствующий исходной синусоидальной волне по амплитуде и частоте. В остальных случаях спектральный пик, полученный с прямоугольным окном, будет ниже и шире.

Наивысшая точка спектра может оказаться на 3,92 дБ (в 1,57 раз) ниже, если частота исходного сигнала находится посередине между двумя дискретными частотами. Эта вариация амплитуды спектральных составляющих носит название эффекта частокола (соответствующие потери на ослабление называются гребешковыми потерями).

Все оконные функции в той или иной мере компенсируют эти потери, но наилучшая компенсация достигается с плоским окном.
Цитата
настало время вернуться к нашим баранам, то есть кнопкам.В связи с увелечением кол-ва последних, было замечено, что работать они стали с заметными тормозами, это в первую очередь касается тех кнопок, которые посылают хитрый код в ПИК.
Мне тут на дружественном форуме предлагали на простеньком ПИКе типа 16Ф84 смастерить кнопочный шифратор и по ISP гнать с него код в главный ПИК.Как вам такая идея? Мне не очень, я всё ж таки хочу ПЛИСку использовать для этого дела.

Безусловно, раз уже есть ПЛИСка то нефиг сюда прикручивать никакие дополнительные пики...
Я бы вам все-таки предложил изменить алгоритм передачи кода нажатой клавиши.
Осатвляем те же 2 линии: линия Разрешения (будет функционировать также как и сейчас)
линия данных

А Код нажатых клавиш передавать в виде 16ти битов. каждый из которых будет означать:
0 - клавиша с номером этого бита не нажата
1 - клавиша с номером этого бита нажата в данный момент

Кодировать биты можно кучей разных способов. Т.к. нету дополнительной линии синхронизации то желательно конечно использовать самосинхронизирующийся код (модуляция с возвращением к нулю, или например манчестерская модуляция). Но т.к. передается всего 2 байта, а плиска и пик тактируются от одного генератора, то можно сделать гораздо проще.

Пусть PR будет означать период сигнала
Пусть Key будет хранить код состояния всех клавиш:

unsigned int16 Key

Алгоритм следующий:
1. При переходе линии разрешение из 0 в единицу, происходит прерывание.
Вы заходите в прерывание и стартуете таймер (перед стартом в таймере уже должно лежать значение 0xFFFF-PR/2)
2. далее ждете флага переполнения таймера:
while(TMRxIF==0);, где x - номер таймера.
как только происходит переполнение ложите в таймер новое значение TMRx=0xFFFF-PR
очищаете флаг TMRxIF=0;
3. опрашиваете линию данных, сдвигаете влево код клавиши, что-то типа такого:
if (Data) Key|=1;
Key<<=1;

4. повторяете пункты 2-3 16 раз.
5. останавливаете таймер. ложите в него значение 0xFFFF-PR/2 (для следующего вход в прерывание)
6. выходите из прерывания.

Таким образом у вас в переменной key будет храниться последнее состояние всех клавиш.

Для проверки нажата ли клавиши делаем просто:

Код
#define Key1   0x0001
#define Key2   0x0002
#define Key3   0x0004
................................
#define Key16 0x8000

if (Key&Key1){            // проверка нажата ли клавиша №1
....
}else if(Key&Key2){    // проверка нажата ли клавиша №2
....
}
...

Все просто!

При таком алгоритме, за один раз у вас передастся все состояние клавиатуры. Код будет работать очень быстро
andreichk
Не уверен, что это правильное оформление кода прерывания, но это всё, что мне удалось вычитать и понять из справки по CSS 05.gif crying.gif help.gif

setup_timer_1(T1_INTERNAL | T1_DIV_BY_8 );//инициализация таймера1
Код
unsigned int16 Keyy,PR,Data;

#int_timer1
void timer1_isr(void){
char x;
         set_timer1(0xFFFF-PR/2);  //записываем значение в таймер
   for(x=0;x<16;x++){
              
while (get_timer1()==0);//while(TMR1IF==0);//ждём флаг переполнения таймера        
     set_timer1(0xFFFF-PR); //записываем новое значение в таймер
        clear_interrupt(int_timer1);//clears the timer1 interrupt flag//TMR1IF=0;//очищаем флаг            
   if (Data) Keyy|=1;
                 Keyy<<=1;
                }
                 set_timer1(0xFFFF-PR/2);//записываем значение в таймер
}//--------------------------??
//##############################################
Ilya_A
Что-то вы опять немного намудрили.... второе прерывание по таймеру не нужно

Блин, я совсем забыл, что у вас порт B уже занят другим, следовательно прерывания по фронту TASTE_EN оргнизовать неудастся, ну ничего, сделаем по другому.
Долго мучался как научить ваш CCS иметь прямой доступ к регистрам, и наконец-то у меня получилось!!!!
Вот бы я этим писателям компилятора smile3009.gif !!!! Все приходиться делать через задний проход... maniac.gif twak.gif

Ну да ладно, теперь к делу.

Для начала нужно сделать следующие объявления:
Код
unsigned int16 Keyy=0;

#define PR2    (*(unsigned char *) 0x0FCB)
#define T2CON  (*(unsigned char *) 0x0FCA)
#define TMR2   (*(unsigned char *) 0x0FCC)
#define PIR1   (*(unsigned char *) 0x0F9E)
#define T2IF   1
#define T2ON   2
#define PR     100


Теперь изменим вашу функцию обработчика прерываний:

Код
//Непосредственно обработчик прерываний
#int_timer0
void timer0_isr(void){
  char i;
  set_timer0(0); // TMR0IF=0;// Очистим флаг прерывания
  //...... Этими кнопками изменяем показания SEC/DIV Канал А ....  
  if (input(OUT_A_UP)){
     while(input(OUT_A_UP));div_A++;
  }else if (input(OUT_A_DOWN)){
     while(input(OUT_A_DOWN));div_A--;
  }
  if(div_A>8) div_A=1;
  if(div_A<1) div_A=8;//ограничиваем div_A от 1 до 8
  //-------Этими кнопками изменяем показания SEC/DIV Канал B ....-------                
  if (input(OUT_B_UP)){
     while(input(OUT_B_UP));div_B++;
  }else if (input(OUT_B_DOWN)){
     while(input(OUT_B_DOWN));div_B--;
  }
  if(div_B>8) div_B=1;
  if(div_B<1) div_B=8;//ограничиваем div_B от 1 до 8                      
  // Теперь ждем начала передачи и принимаем код клавиши
  if(input(TASTE_EN)){
     while(input(TASTE_EN));//если зашли уже в момент передачи кода кнопки то дождаться окончания передачи
  }
  while(!input(TASTE_EN));//Ждем начала передачи
  bit_set(T2CON,T2ON); //Включим таймер
  Keyy=0;//Занулим перед считыванием
  for(i=0;i<16;i++){
    while(bit_test(PIR1,T2IF));//Ждем флага переполнения
    bit_clear(PIR1,T2IF);// Очистим флаг переполнения
    if (input(Code_Out)) Keyy|=1; //Если клавиши нажата
    Keyy<<=1;//Сдвигаем
  }
  bit_clear(T2CON,T2ON); //Отключим таймер
  set_timer2(PR/2); //Установим начальное значение
  bit_clear(PIR1,T2IF);// Очистим флаг переполнения
}//--------------------------OK


В самом начале программы, перед бесконечным циклом for(;;) нужно сделать следующее:

Код
setup_timer_2(T2_DIV_BY_4, PR, 2);// Настроим таймер
bit_clear(T2CON,T2ON); //Отключим таймер
set_timer2(PR/2); //Установим начальное значение


Все, что вам осталось сделать это подобрать прескалер, постскалер и регистр переполнения (PR) для таймера 2, чтобы период его переполнения, был равен времени передачи одного бита от плиски.

А правильнее всего не подобрать, а расчитать! wink.gif

ЗЫ: Думаю время одного бита <10 мкс вполне реально организовать
ЗЫ ЗЫ: Передача битов должна быть от старшего к младшему, если хотите чтобы Key1 была младшим битом переменной Keyy
или тогда перепешите считывание вот так:
if (input(Code_Out)) Keyy|=0x8000; //Если клавиши нажата
Keyy>>=1;//Сдвигаем
ЗЫ ЗЫ ЗЫ: В основной программе остается только опрашивать переменную Keyy и проверять ее значение, как описано выше
andreichk
кодировака кнопок ,значит, вот так будет выглядеть?

Код
#define Key1    0b0000000000000001//0x0001//1
#define Key2    0b0000000000000010//0x0002//2
#define Key3    0b0000000000000100//0x0004//4
#define Key4    0b0000000000001000//0x0008//8
#define Key5    0b0000000000010000//0x0010//16
#define Key6    0b0000000000100000//0x0020//32
#define Key7    0b0000000001000000//0x0040//64
#define Key8    0b0000000010000000//0x0080//128
#define Key9    0b0000000100000000//0x0100//256
#define Key10   0b0000001000000000//0x0200//512
#define Key11   0b0000010000000000//0x0400//1024
#define Key12   0b0000100000000000//0x0800//2048
#define Key13   0b0001000000000000//0x1000//4096
#define Key14   0b0010000000000000//0x2000//8192
#define Key15   0b0100000000000000//0x4000//16384
#define Key16   0b1000000000000000//0x8000//32768

то есть длительность каждого последующего импулься в два раза больше предыдущего?
Ilya_A
Цитата(andreichk @ Apr 20 2008, 17:01) *
кодировака кнопок ,значит, вот так будет выглядеть?

Код
#define Key1    0b0000000000000001//0x0001//1
#define Key2    0b0000000000000010//0x0002//2
#define Key3    0b0000000000000100//0x0004//4
#define Key4    0b0000000000001000//0x0008//8
#define Key5    0b0000000000010000//0x0010//16
#define Key6    0b0000000000100000//0x0020//32
#define Key7    0b0000000001000000//0x0040//64
#define Key8    0b0000000010000000//0x0080//128
#define Key9    0b0000000100000000//0x0100//256
#define Key10   0b0000001000000000//0x0200//512
#define Key11   0b0000010000000000//0x0400//1024
#define Key12   0b0000100000000000//0x0800//2048
#define Key13   0b0001000000000000//0x1000//4096
#define Key14   0b0010000000000000//0x2000//8192
#define Key15   0b0100000000000000//0x4000//16384
#define Key16   0b1000000000000000//0x8000//32768

Да, именно так
Цитата
то есть длительность каждого последующего импулься в два раза больше предыдущего?

Нет, длительность каждого импульса одинкова и равна PR (с учетом прескалера и постскалера для TMR2). Иначе работать не будет. Если кнопка с номером текущего импульса нажата, то имульс заполняется +5В. Если не нажата то 0 В.
andreichk
я тут наверное неправильно выразился- я имел ввиду, что длительность импульса каждой последующей кнопки в два раза больше предыдущей
Ilya_A
Цитата(andreichk @ Apr 20 2008, 19:14) *
я тут наверное неправильно выразился- я имел ввиду, что длительность импульса каждой последующей кнопки в два раза больше предыдущей

Нифига не понимаю ваших выводов 07.gif

С чего она в два раза больше предыдущей? если все длительности равны....

Сигнал следующий:

KEY1 | KEY2 | KEY3 | ... |KEYn |..... | KEY16 |


все временные интервалы для каждого импульса одинаковые и равны PR. Заполнение интервала либо 0 либо 1 в зависимости от того нажата ли клавиша....
Ilya_A
Цитата(andreichk @ Apr 20 2008, 20:43) *
теперь я нифига не понимаю, что я должен с ПЛИСки в ПИК гнать?
такими должны быть импульсы?

Вот, что я имел ввиду:
Нажмите для просмотра прикрепленного файла
В данный момент одновременно нажаты клавишы: 2,5,12,16

Т.е. за одну посылку передается все состояние клавиатуры.
andreichk
Цитата
Вот, что я имел ввиду:

я так и подозревал, но боялся об этом подумать.
теперь рассказывайте мне , как мне ПЛИСину перерисовать для такого случая. wacko.gif

зы.попробовал перезагрузить код с обновлённым прерыванием, так вот проц запускается только , если закомментировать строчку // while(bit_test(PIR1,T2IF));//Ждем флага переполнения.
на обоих входах- TASTE_EN и Code_Out лог.0

а если при этом нажать любую кнопку, то картинка оживает.
На входе TASTE_EN появляется лог.1, а Code_Out лог.0( я его временно заземлил)
Ilya_A
Цитата(andreichk @ Apr 20 2008, 23:43) *
теперь рассказывайте мне , как мне ПЛИСину перерисовать для такого случая. wacko.gif

Тут навеное вам виднее...

Цитата
зы.попробовал перезагрузить код с обновлённым прерыванием, так вот проц запускается только , если закомментировать строчку // while(bit_test(PIR1,T2IF));//Ждем флага переполнения.
на обоих входах- TASTE_EN и Code_Out лог.0

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

Так и должно было получиться. Вам нужно отправлять состояние клавиатуры постоянно, независимо от того, нажата или нет хоть одна клавиша.
andreichk
Ок, вот такой кнопочник мне предложили запихнуть в ПЛИСку. Я его собрал и проверил.Сигналы соответствуют тому графику , который вы нарисовали.На входе счётчика 156кГц(если надо, то можно выбрать от 80ти МГц и далее делением на 2).
На ножке Taste_EN меандр активная часть 100мкс,пауза тоже 100мкс, а на CODE_OUT короткие импульсы прим. 8мкс. Если одновременно нажать все 16 кнопок, то они как раз умещаются в активную часть Taste_EN, то есть тут , как я полагаю всё правильно.
дальнейшей проверкой работы кнопок пока не занимался, уже поздно и спать хочу wassat.gif
Ilya_A
Цитата(andreichk @ Apr 22 2008, 02:06) *
Ок, вот такой кнопочник мне предложили запихнуть в ПЛИСку. Я его собрал и проверил.Сигналы соответствуют тому графику , который вы нарисовали.На входе счётчика 156кГц(если надо, то можно выбрать от 80ти МГц и далее делением на 2).
На ножке Taste_EN меандр активная часть 100мкс,пауза тоже 100мкс, а на CODE_OUT короткие импульсы прим. 8мкс. Если одновременно нажать все 16 кнопок, то они как раз умещаются в активную часть Taste_EN, то есть тут , как я полагаю всё правильно.
дальнейшей проверкой работы кнопок пока не занимался, уже поздно и спать хочу wassat.gif

Замечательно! Теперь немного посчитаем:

Точная длительность одного импульса равна:

1/(80000000/512)=6,4 мкс

Это означает 64 такта процессора, работающего на частоте 10 Мгц.

Для получения такого периода нужно следующим образом настроить таймер2:
Код
#define PR     63
setup_timer_2(0, PR, 0);// Настроим таймер

т.е. Прескалер и постскалер должны быть нулевыми.

Насколько я понял, таймер 0 у вас настроен так:
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
Если он в 16-ти битном режиме то получится период примерно в 50 мс. Т.е. в прерывание вы будете заходить 20 раз в секунду. С этой же частотой будет обновляться состояние клавиатуры.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.