zi4rox 0 23 мая, 2009 Опубликовано 23 мая, 2009 · Жалоба ATMega16 управляет внешним АЦП TLV1570 по встроенному SPI и пытаемся оцифровать гармонический сигнал с частотами до 20кгц. Немного о TLV1570 - 8ми канальный 10ти разрядный последовательный АЦП 1.25MSPS. Входные напряжения: 0 .. 5В По теореме Котельникова, частота дискретизации: Fдиcкр > 2Fmax В моём случае 2Fmax = 40кГц, а частота дискретизации АЦП по даташиту считается так: Fдискр = 1/16*Fsclk (на каждую выборку нужно передать 2 байта) (в обвязке к ATMega стоит резонатор на 16МГц, при настройках SPI получил: Fsclk = 4Mhz ) => Fдиск = 1\16*4Mhz = 250кГц Т.е. мы укладываемся с головой. Частота дискретизации 250 кГц, а сигнал 20кГц Код прошивки такой: while (1) { for (i=0;i<100;i++) { ADC_CS = 0; adc_result_hi[i] = spi(0x00); adc_result_low[i] = spi(0x60); ADC_CS = 1; } for (i=0;i<100;i++){ putchar(adc_result_hi[i]); putchar(adc_result_low[i]); } } * я сначала собираю отсчеты по 100 точек и сохраняю их в буффер, а затем отправляю по UART на COM порт в ПК. (так быстрее производительность, т.к. отправка по уарту занимает значительное время) Просимулировал этот код в VMLAB, получил следующие тайминги: С учетом всех погрешностей на запись в переменные и т.п - получил, что снятие одного отсчета займет 10мкс - т.е. частота дискретизации 100кГц - все равно укладываемся. Итак, на практике вот что я получаю: Оцифровка сигнала частотой 10кГц амплитуда около 1В: Здесь около 10ти точек на период. Качество оцифровки неудовлетворительное. Сразу же в настройках SPI выставил галочку SCLK x2 Rate - т.е. удвоили частоту тактирующего импульса (я предполагал что и качество оцифровки увеличится в 2 раза) Вот как получилось с этой настройкой: Оцифровка сигнала частотой 10кГц амплитуда около 1В (SPI SCLK x2 rate): Получилось 13 точек на период - совсем небольшой прирост =( Мучил код, пробывал и так и сяк, симулировал. Вот как получается, если после получения отсчета от АЦП - сразу выплевывать его на UART: while (1) { ADC_CS = 0; putchar(spi(0x00)); putchar(spi(0x60)); ADC_CS = 1; } Совсем не так как хотелось бы. * Сигнал с меньшей частотой оцифровывает прелестно. Вот пример оцифровки синуса с частотой 1кГц: Здесь меня всё устраивает. Около 90 точек на период. Качество отличное Прошу помощи - оцифровкой занимаюсь в первый раз, как быть, вроде бы всё правильно - а на деле выходит совсем не то. Возможно код можно ещё как то более оптимизировать, или ещё где ошибку сделал? Прошу совета. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 23 мая, 2009 Опубликовано 23 мая, 2009 · Жалоба ... Т.е. мы укладываемся с головой. Частота дискретизации 250 кГц, а сигнал 20кГц ... На вид все картинки у вас правильные. Разве что иногда у вас теряются отсчёты (видно на второй картинке "синуса"). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dx! 0 23 мая, 2009 Опубликовано 23 мая, 2009 (изменено) · Жалоба То вам "Fдиcкр > 2Fmax" А то 10 точек на период мало 8) Тогда и считайте частоту, отталкиваясь от минимально количества этих самых точек 8) Эти десять точек на период в 10КГц синусоиды.... уже 100Кгц дискретизации. Мне собственно непонятно - что вам не нравится. На вид все картинки у вас правильные. Разве что иногда у вас теряются отсчёты (видно на второй картинке "синуса"). Это имхо не потеря, а места склейки семплов по 100 точек. Изменено 23 мая, 2009 пользователем Dx! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 24 мая, 2009 Опубликовано 24 мая, 2009 · Жалоба Это имхо не потеря, а места склейки семплов по 100 точек. ага. похоже на то. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zi4rox 0 24 мая, 2009 Опубликовано 24 мая, 2009 · Жалоба Да, сейчас тоже пересчитал - получается что ацп правильно работает - и там получается 10 точек на период. Буду пытаться увеличить частоту дискретизации каким то образом. Непонятно пока - сколько этих точек на период в среднем необходимо для более менее верной оцифровки? Или это определяется исходя из личных условий задачи? Вы как считаете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 24 мая, 2009 Опубликовано 24 мая, 2009 · Жалоба Непонятно пока - сколько этих точек на период в среднем необходимо для более менее верной оцифровки? Или это определяется исходя из личных условий задачи? Вы как считаете? Верной для чего? Чтобы измерить частоту? Амплитуду? С какой точностью? P.S. В хороших цифровых осциллографах частоту дискретизации выбирают в 10 раз большую, чем максимальная наблюдаемая. В дешёвых от 2х раз. Правда там ещё дополнительно применяют цифровую интерполяцию. Для наблюдения синуса достаточно хорошо подходит "sin(x)/x correction". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zi4rox 0 24 мая, 2009 Опубликовано 24 мая, 2009 (изменено) · Жалоба Измерять нужно амплитуду. Про цифровую интерполяцию интересно! Пойду искать информацию по этой теме, спасибо за идею. * Если кто нибудь знает хорошую ссылку на алгоритм/или мат. описание интерполяции sinc(x) прошу поделится Изменено 24 мая, 2009 пользователем zi4rox Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smac 0 24 мая, 2009 Опубликовано 24 мая, 2009 · Жалоба Измерять нужно амплитуду. Про цифровую интерполяцию интересно! Пойду искать информацию по этой теме, спасибо за идею. * Если кто нибудь знает хорошую ссылку на алгоритм/или мат. описание интерполяции sinc(x) прошу поделится Если измерять нужно амплитуду, то не обязательно оцифровывать синус, можно взять пиковый детектор, оцифровывать его выход и сразу получать амплитуду сигнала. Правда, наверняка у вас задача не только амплитуду измерять. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zi4rox 0 24 мая, 2009 Опубликовано 24 мая, 2009 · Жалоба Пытаюсь сделать интерполяцию синком - не получается немного ... Вот формула, для восстановления сигнала: x(t) - исходный сигнал Fmax - частота сигнала, пусть Fmax = 1000 Гц dt = 1/2Fmax (отсчеты идут через этот интервал времени) dt = 1/2*1000 = 0.0005 При это допустим что ацп выдает нам 13 отсчетов сигнала на период. Сам же период T = 1/f = 0.001. Вот на интервале времени в 1 период я и хочу восстановить сигнал. Тогда суммирование будет идти от n=0 до n=2Fmax*T=2000*0.001=2 // Всего 2 отсчета будет использоваться, а не все 13? // s(n*dt) - это как раз сами отсчеты которые у меня есть. // Это массив с отсчетами, которые у меня есть за 1 период data_01[0]:= 1.10929; data_01[1]:= 1.02396; data_01[2]:= 0.85501; data_01[3]:= 0.54537; data_01[4]:= 0.31164; data_01[5]:= 0.08533; data_01[6]:= 0.02226; data_01[7]:= 0.09275; data_01[8]:= 0.26341; data_01[9]:= 0.56763; data_01[10]:= 0.81249; data_01[11]:= 1.0388; data_01[12]:= 1.09445; ... //константы, что обговорили выше: f_max:=1000; dt:= 0.0005; x:= 0.0004; // вычисление значения восстановленного сигнала x(t) в точке x for n:=0 to 2 do begin buff:= data_01[n]*sin(2*3.14*f_max*(x-n*dt))/(2*3.14*f_max*(x-n*dt)); result:= result+buff; end; Я получаю 1,0849 - довольно близкий отсчет. Пробую строить сам график, беру 100 точек интерполяции с шагом в 0.0004 for j:=1 to 100 do begin result:=0; // обнуляю результат вычисления для каждой новой точки dx:= j*0.0004; // шаг восстановления: 0.0004, 0.0008, 0.0016 и.т.д. for n:=0 to 2 do begin buff:= data_01[n]*sin(2*3.14*f_max*(dx-n*dt))/(2*3.14*f_max*(dx-n*dt)); result:= result+buff; end; // И добавляю вычесленную точку на график (x,y) Series2.AddXY(dx,result,'',clRed); В результате получаю вот такую картинку: синк он мне рисует ... но это не восстановленный сигнал. Как я понял - тут должна быть сумма синков - и тогда образуется нужное. Или я ошибаюсь? Помогите пожалуйста разобраться, а то голова кругом уже Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zi4rox 0 27 мая, 2009 Опубликовано 27 мая, 2009 (изменено) · Жалоба Всё, вроде разобрался - нужно быть более аккуратным при подборе коэффициентов. Сигнал действительно можно восстановить с любой точностью, для гармонического сигнала - ещё можно и форму подсгладить. * на рисунку 250 точек на период - это число может быть теоретически любым Всем спасибо кто помогал! Изменено 27 мая, 2009 пользователем zi4rox Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GeorgyBey 0 30 мая, 2009 Опубликовано 30 мая, 2009 · Жалоба Измерять нужно амплитуду. Про цифровую интерполяцию интересно! Если измерять амплитуду - можно сделать аналоговый дифференциатор, т.е. брать первую производную от вашего синуса, получится косинус. Моменты перехода косинуса через 0 будут соответствовать амплитуде синуса. Компаратор контроллера ловит переход косинуса из 0(минус обрезан, понятное дело) в + и запускает замер АЦП. При спаде из + в 0 можно замерять нижнюю амплитуду. Может в перерывах успеет в комп согнать ин-фу? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться