Перейти к содержанию
    

shkal

Свой
  • Постов

    279
  • Зарегистрирован

  • Посещение

Весь контент shkal


  1. Имеем вычисление по простейшей формуле F=A*B/C. A, B, C имеют тип long int, F - long double. Строка F=(((long double)(А))*B )/С; при А=65535, В=2500000, С=5000002 даёт результат, совпадающий с виндовым калькулятором только до 9 знака. Где я теряю точность? Компилятор Микрочип С30, мк PIC24H.
  2. Да не закрыт. Даташит покажите хоть один. МКЭ-333 МКЭ 332 Да, нужно полпитания
  3. Не стоит так откровенно демонстрировать своё ламерство. В табличке, на которую вы ссылаетесь, люди забыли чёрточки между цифрами поставить :) :) тыц Andrey_1 , кстати, в измерительных микрофонах по $100 типа Behringer ECM8000 или Nady CM 100 как раз и стоят капсули panasonic WM-61 за $2
  4. Это ошибка примерно в 20 раз. Обычно 50-60 мв/Па микрофоны Соответственно и уровень на выходе - единицы-десятки милливольт. Поэтому и повторитель после него никому не нужен, нужен усилитель.
  5. Так тоже нельзя ;) Вот так можно. Стабилитрон на 2.5 В Вы хотя-бы первую главу про ОУ из "Искусства схемотехники" прочитайте, нельзя так, право же.
  6. 1) первый ОУ так нельзя включать. 2) При закорачивании входа его Ку стремиться к бесконечности, что вы и наблюдаете. 3) TL072 - не подходит для микрофонного преда, поскольку довольно шумное. Из недорогих - возьмите RC4580 4) Питание от USB очень грязное. 5) 7805 от 5В входа работать не будет.
  7. Добрый день всем. Существуют ли дсп с параллельными интерфейсами, позволяющими напрямую подключить ацп 14 бит 170-250 msps? Какова потоковая скорость передачи интерфейс-память для ддр? Прикидочно общая задача - оцифровка 4М отсчётов, запись в память, обработка не в реальном времени, выдача результатов на DVI
  8. А если состояние порта В сохранить в переменной, а следующей командой присвоить ее порту Е - работает?
  9. Если я правильно понял, у вас захват двух последовательных фронтов входного сигнала, т.е. измеряется время одного периода. В этом случае нужна информация о приблизительной входной частоте, иначе как определить нужный коэфициент деления? В алгоритме , описанном GM, изменение коэфициента деления происходит как-бы автоматически при изменении входной частоты таким образом, чтобы время измерения оставалось постоянным. Кроме того, этот алгоритм не имеет нижней граничной частоты - он просто ждет второго фронта, если он не появился за время гейта. Еще вот какой вопрос-очищается ли у ПИК24 ФИФО захвата при выключении модуля захвата?
  10. Интервал счета формируется от фронтов входного сигнала
  11. Уважаемый, читайте внимательно алгоритм по ссылке из первого поста, вы его нифига не поняли.
  12. Отказался в итоге от захвата таймера, считающего входную частоту. Захватываю только таймер, считающий опору, а в прерывании от IC1 просто читаю входной таймер первой командой. При высокой входной частоте этот таймер, конечно, успевает сосчитать несколько фронтов за время входа в прерывание, но, поскольку это время однинаково в начале и конце цикла измерения, то ошибка не возникает. Ессно, при такой схеме требуется , что приоритет прерывания IC1 был наивысшим. Там есть один тонкий момент, связаный с возможностью совпадения прерывания от IC1 и прерывания от переполнения таймеров, но это вроде решаемо, тут где-то была ветка на эту тему.
  13. Сейчас оптимальное по цене\качеству - Quick 202D, Quick 301/303
  14. Нашёл я ответ в документации на pic24f Note1 просто убило. -Таймер, ты сколько импульсов сосчитал? -Ну, сэм-восэм, не больше.
  15. Так изучай-не изучай, повлиять на работу ея я всё равно не могу, отключить - тоже. С таймером всё более-менее понятно и оговорено в даташите - время от входного фронта до изменения состояния 0.75-1.75 цикла. 0-1 цикл - задержка синхронизации, то есть обычный Д-триггер, 0.75 цикла - сам таймер. А вот с input capture тайминги не оговариваюся. есть старый аппнот 96 года по семейству pic17, appnote где на стр.8 нарисованы тайминги работы, так как я их себе представлял (но не так, как на самом деле в pic24)
  16. Написал простейшую тестовую программу (инициализацию опускаю). IC1 захватывает TMR3. int main() { while (1) {}; } void __attribute__((__interrupt__)) _IC1Interrupt(void) { unsigned int a,b; b=TMR3; a=IC1BUF; if (a==b ) { ok1++; } else { error1++; } counter++; IFS0bits.IC1IF=0; //reset interrupt flag } независимо от входной частоты этот код дает 75% счётчика ок и 25% счётчика error от общего числа циклов. Я в ах.... прострации
  17. При любых. Даже очень низких, хоть 1 Гц. Тут, похоже, дело не в алгоритме. У меня есть такое впечатление, что, когда один и тот же фронт приходит и на IC1, и на таймер, который она захватывает, то иногда сначала срабатывает таймер, а потом IC, а иногда наоборот, и зависит это от фазы входного фронта по отношению к фронту тактовой.
  18. Опора на внешний пин не заводится, Т3 считает внутренний клок. Вы ссылку на алгоритм посмотрели, которую я дал? Там извращенность подхода тщательно обсуждается.
  19. Добрый день всем. Я попал в некоторый затык и не могу выбраться из него без посторонней помощи. Итак, пишется реализация частотомера по алгоритму, приведённому здесь Входные импульсы считаются таймером Т2, опорные - Т3. Входы IC1 IC2 T2CK - физически один пин, мэппинг с помощью PPS. IC1 захватывает Т2, IC2 захватывает T3. Функция F_init() инициализирует переферию. Функция F_start() запускает цикл измерения частоты. По первому прерывнию от IC1 сохраняются пары значений F_osc_start, F_in_start и счётчики переполнения таймеров over2_start, over3_start. Далее модули IC1 IC2 выключаются и запускается на время gate_time таймер Т5. По его прерыванию модули IC1 IC2 опять включаются, и после очередного фронта входного сигнала в прерывании IC1 сохраняются пары значений F_osc_end, F_in_end и счётчиков переполнения таймеров over2_end, over3_end. Устанавливается флаг new_data. В main'е крутиться простейшая state machine, после установки флага new_data значение частот вычисляется функцией F_calc() и отображается на ЛСД. main() { F_init(); while(1) { switch (main_state) { case 0: F_start(200); main_state=1; break; case 1: if (new_data) { Freq=F_calc(); LCDWriteCmd(0x01); // clear display delay_ms(2); if (Freq == 0) { LCDputstr ("NO SIGNAL"); } else { sprintf(F_display, "%15f", Freq); LCDputstr(F_display); } new_data=0; main_state=0; } break; } } void F_init(void) { // init timer2 for external clock T2CONbits.TON = 0; // Disable Timer T2CONbits.TCS = 1; // Select external clock T2CONbits.TGATE = 0; // Disable Gated Timer mode T2CONbits.TCKPS = 0b00; // 1:1 prescaler T2CONbits.T32 = 0; // 16bit mode TMR2 = 0x00; // Clear timer register PR2=0xffff; IPC1bits.T2IP = 6; // INT priority=6 IFS0bits.T2IF = 0; // Clear Timer1 Interrupt Flag IEC0bits.T2IE = 1; // Enable Timer1 interrupt // init timer 3 T3CONbits.TON = 0; // Disable Timer T3CONbits.TCS = 0; // Select internal clock T3CONbits.TCKPS = 0b00; // 1:1 prescaler T3CONbits.TGATE = 0; // Disable Gated Timer mode TMR3 = 0x00; // Clear timer register PR3=0xffff; IPC2bits.T3IP = 6; //INT priorty=6 IFS0bits.T3IF = 0; // Clear Timer1 Interrupt Flag IEC0bits.T3IE = 1; // Enable Timer1 interrupt // init timer 5 for 0.2c T5CONbits.TON = 0; // Disable Timer T5CONbits.TCS = 0; // Select internal clock T5CONbits.TCKPS = 0b11; // 1:256 prescaler T5CONbits.TGATE = 0; // Disable Gated Timer mode TMR5 = 0x00; // Clear timer register PR5=2879; IPC7bits.T5IP = 4; //INT priorty=4 IFS1bits.T5IF = 0; // Clear Timer1 Interrupt Flag IEC1bits.T5IE = 1; // Enable Timer1 interrupt // init input capture 1 on Timer 2 IC1CONbits.ICM= 0b000; // Disable Input Capture 1 module IC1CONbits.ICTMR= 1; // Select Timer2 as the IC2 Time base IC1CONbits.ICI= 0b00; // Interrupt on every capture event IPC0bits.IC1IP = 6; // Setup IC1 interrupt priority level IFS0bits.IC1IF = 0; // Clear IC1 Interrupt Status Flag IEC0bits.IC1IE = 1; // Enable IC1 interrupt // init input capture 1 on Timer 3 IC2CONbits.ICM= 0b000; // Disable Input Capture 2 module IC2CONbits.ICTMR= 0; // Select Timer3 as the IC2 Time base IC2CONbits.ICI= 0b00; // Interrupt on every capture event - INT from IC2 DISABLED!!! // IPC0bits.IC1IP = 6; // Setup IC1 interrupt priority level // IFS0bits.IC1IF = 0; // Clear IC1 Interrupt Status Flag // IEC0bits.IC1IE = 1; // Enable IC1 interrupt gate_flag=0; } void F_start (unsigned int gate_time) { unsigned int scale; T5CONbits.TON = 0; scale = gate_time*(3125/(TOSC*8)) ; TMR5 = 0x00; // Clear timer register PR5=scale; new_data=0; T2_over=0; //Clear TMR2 overflow T3_over=0; //Clear TMR3 overflow TMR2 = 0x00; //Clear timer 2 TMR3 = 0x00; //Clear timer 3 T2CONbits.TON = 1; //Start Timer 2 T3CONbits.TON = 1; //Start Timer 3 IC1CONbits.ICM= 0b011; // Enable IC1, every rising edge IC2CONbits.ICM= 0b011; // Enable IC2, every rising edge } void __attribute__((__interrupt__)) _T2Interrupt( void ) { T2_over++ ; IFS0bits.T2IF = 0; /* reset timer interrupt flag */ } void __attribute__((__interrupt__)) _T3Interrupt( void ) { T3_over++ ; IFS0bits.T3IF = 0; /* reset timer interrupt flag */ } void __attribute__((__interrupt__)) _T5Interrupt( void ) { T5CONbits.TON = 0; IC1CONbits.ICM= 0b011; //Enable IC1 , on every rising edge IC2CONbits.ICM= 0b011; //Enable IC2 , on every rising edge IFS1bits.T5IF = 0; /* reset timer interrupt flag */ } // Capture Interrupt Service Routine void __attribute__((__interrupt__)) _IC1Interrupt(void) { unsigned int tmp; if (!gate_flag) { F_osc_start=IC2BUF; IC2CONbits.ICM= 0b000; //Turn OFF IC2 F_in_start=IC1BUF; IC1CONbits.ICM= 0b000; //Turn OFF IC1 module over2_start=T2_over; over3_start=T3_over; while (IC1CONbits.ICBNE) { tmp=IC1BUF; } while (IC2CONbits.ICBNE) { tmp=IC2BUF; } gate_flag=1; T5CONbits.TON = 1; //start timer5 } else { F_osc_end=IC2BUF; IC2CONbits.ICM= 0b000; //Turn OFF IC2 F_in_end=IC1BUF; IC1CONbits.ICM= 0b000; //Turn OFF IC1 module over2_end=T2_over; over3_end=T3_over; T2CONbits.TON = 0; //Stop Timer 2 T3CONbits.TON = 0; //Stop Timer 3 while (IC1CONbits.ICBNE) { tmp=IC1BUF; } while (IC2CONbits.ICBNE) { tmp=IC2BUF; } gate_flag=0; new_data=1; } IFS0bits.IC1IF=0; //reset interrupt flag } float F_calc(void) { float F; float M; //input pulse count float N; //clock pulse count unsigned long A1,A2 ; A1=((unsigned long)(over2_end-over2_start))<<16; A2=((unsigned long)(over3_end-over3_start))<<16; M=A1+(F_in_end-F_in_start); N=A2+(F_osc_end-F_osc_start); if (M == 0) F=0; else F=(OSCIL*M)/N; return F; } Проблема заключается в том, что данный код примерно в 80% циклов выдаёт правильное значение частоты, а в 20% - таймер Т2 пропускает 1 входной импульс, причем это происходит совершенно хаотично, никакой закономерности я уловить не смог. Уже довольно долго бьюсь с отладкой, но всё мимо. Будут ли какие-нибудь идеи о причинах такого поведения?
  20. Опору измерять значительно проще, т.к. постоянное напряжение, да и полно ЦАПов со встроенными опорами. Для измерения 10-20КГц с такой точность нужно что-то типа Agilent 34410a
  21. Такой например http://focus.ti.com/docs/prod/folders/print/pcm1781.html Можно и промышленный 14-16 битный цап взять с SPI-интерфейсом, контроллеров с I2S на борту не очень много.
  22. Микроконтроллер с выходом I2S и звуковой ЦАП. Контроллер формирует отсчёты синуса в цифре и отдаёт ЦАПу. Точность напряжения равна точности ЦАПа. 16 бит хватит с большим запасом. Возможно ещё выходной буфер, редкий ЦАП с выходом по напряжению работает на 200 Ом.
×
×
  • Создать...