Funderar på att bygga en DDS med en STM32F4 Discovery.

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Funderar på att bygga en DDS med en STM32F4 Discovery.

Inlägg av lillahuset »

Jo jag har funderat lite till och från de senaste åren på att bygga en "direct digital synthesizer" eller DDS. http://www.analog.com/media/en/training ... torial.pdf En typ av funktionsgenerator.

Igår började jag kolla lite närmare. Bristande arbetslust? Om man baserar den på en STM32F4 Discovery kan man komma undan med det kortet, en skaplig quad OP, spänningsmatning och lite krafs runtomkring. Mina önskemål är i första hand 0,1..20kHz sinus som helst ska orka driva en koax med 10V P-P. Liten drift är viktigare än absolut noggrannhet eftersom jag lätt kan kalibrera den. Den är tänkt att ingå i produktionstest av ett övervakningssystem för vibrationer.

Det klassiska sättet att skapa en sinus i en DDS är med en "look up table", LUT. Effektivt, billigt, bra. Och trist. När jag läste om DDS (eller egentligen NCO) på Wikipedia såg jag en länk till en polsk artikel om att använda taylorserier istället. http://mechatronika.polsl.pl/owd/pdf2009/030.pdf Då triggade mitt minne från åttiotalet och jag kollade upp maclaurinserier som fascinerade mig på universitetet. Idag skrev jag ett litet testprogram för att se hur bra det skulle fungera istf LUT och kom fram till att det definitivt är en rimlig lösning. I alla fall om man har en 168MHz Cortex-M4 "under huven".

Sju multiplikationer, fyra additioner/subtraktioner och två jämförelser per sample. En bagatell med den "DSP-funktionalitet" som finns i processorn. Sedan DMA för att i lugn och ro skyffla data till DAC.

Hur bra blir resultatet för beräkning av sinus då? Se bilden som visar absoluta felet. Duger det inte så lägg till två multiplikationer och en addition så blir det, om jag minns rätt, åtminstone en faktor 10 bättre. Till ingen nytta om man har en 12 bits DAC. :)
mlsin.jpg

Kod: Markera allt

/* Mclaurin series 2015-12-30 */

#include <math.h>
#include <stdio.h>


double mlsin(double x);


int main(int argc, char **argv)
{
  double fi, mls, s;

  fi = -M_PI;
  while (fi <= M_PI) {
    mls = mlsin(fi);
    s = sin(fi);

    printf("%.8f\t%.8f\t%.8f\t%.8f\n", fi, mls, s, mls - s);

    fi += (M_PI / 18000);
  }

  return 0;
} /* main */


double mlsin(double x)
{
  double xx, p, ret;

  if (x < 0.0) {
    if (x < -M_PI_2) {
      x = -M_PI - x;
    }
  } else {
    if (M_PI_2 < x) {
      x = M_PI - x;
    }
  }

  xx = x * x;
  p = x;

  ret = p;

  p *= xx;
  ret -= (p * (1.0 / 6.0));

  p *= xx;
  ret += (p * (1.0 / 120.0));

  p *= xx;
  ret -= (p * (1.0 / 5040.0));

#if 0
  p *= xx;
  ret += (p * (1.0 / 362880.0));
#endif

  return ret;
} /* mlsin */
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
LHelge
Inlägg: 1772
Blev medlem: 2 september 2007, 18:25:31
Ort: Östergötland
Kontakt:

Re: Funderar på att bygga en DDS med en STM32F4 Discovery.

Inlägg av LHelge »

STM32F4 har flyttalsprocessor och pratar du 20 kHz är det ingen anledning att implementera något eget. Inkludera math.h och använd float sinf(float); istället.
SvenW
Inlägg: 1156
Blev medlem: 24 april 2007, 16:23:10
Ort: Göteborg

Re: Funderar på att bygga en DDS med en STM32F4 Discovery.

Inlägg av SvenW »

Det går bra att använda flyttalsprocessorn, glöm bara inte att den måste aktiveras, dels med en liten programsnutt, dels med flaggor till kompilatorn och länkaren.
Annars tror jag att den mest effektiva metoden är att använda 32 bitars heltal och uppslagstabell, eller en kombination av uppslagstabell och taylorserie. Dvs uppslagstabell med interpolation, ev. upp till andra ordningen.
En enda uppslagstabell utan interpolation kan också gå bra, men då blir tabellen stor, kanske 256 Kbyte. Men det finns ju gott om flashminne.

Problemet är väl att 12-bitars DAC inte räcker om man vill ha bra dynamik. Översampling hjälper till viss del, men inte mot fel i DACen.
Möjligen går det att kombinera PWM och DAC om man har bra precision i kringkretsarna.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Funderar på att bygga en DDS med en STM32F4 Discovery.

Inlägg av lillahuset »

LHelge: Jag är mycket medveten om att STM32F4 har FPU och använder den mycket till vibrationsmätningen. Och existensen av sinf() & Co.
Men till en DDS finns ingen anledning att använda flyttal. Det här var bara ett test av hur lång Mclaurinserien behöver vara för tillräckligt litet fel.
20kHz är som du påpekar ingen hög frekvens men jag vill översampla för att förenkla rekonstruktionsfiltret.

SvenW: Jo tolv bittar är lite lite om man vill ha stort utspänningsområde. Jag hade tänkt använda båda DACarna och summera signalerna med olika skalning för att få större upplösning. Det borde funka med tanke på att man kan uppdatera båda utgångarna samtidigt. Kräver förmodligen någon typ av automatisk kalibrering vid start.

Min första tanke var att använda en digital pot som volymkontroll men tänkte "äh, va fan". Och projektet är än så länge bara på funderingsstadiet.
Användarvisningsbild
Greve Hamilton
EF Sponsor
Inlägg: 544
Blev medlem: 4 september 2004, 15:03:35
Ort: GBG

Re: Funderar på att bygga en DDS med en STM32F4 Discovery.

Inlägg av Greve Hamilton »

Nu spånar jag bara här, du är säkert nöjd med noggrannheten, men skulle man inte kunna använda variabla Taylorkoefficienter för att minska felet ytterligare? Alltså att man i förväg har beräknat koefficienterna för kanske 10 delinterval av sinusfunktionens domän, istället för bara vid 0. Blir ju lite mer overhead såklart.
Skriv svar