Bonjour, je dois faire un NCO ( numerically controlled oscillator ) en c. Quelqu'un à t-il d'jà réalisé cela? Car je ne vois pas trop comment le faire. Je ne trouve d'algorithme!
Merci de votre aide.
Bonjour, je dois faire un NCO ( numerically controlled oscillator ) en c. Quelqu'un à t-il d'jà réalisé cela? Car je ne vois pas trop comment le faire. Je ne trouve d'algorithme!
Merci de votre aide.
- Avec un accumulateur dont la sortie est réduite modulo N.
L'accumulateur réalise l'opération acc = (acc+x)modulo(N). La fréquence est fixée par le nombre x placé à l'entrée de l'accumulateur et par le cadencement de l'accumulateur et on obtient en sortie acc qui est la phase (la valeur N correspondant à 2*pi) de l'oscillateur.
- La fréquence est donnée par Freq = x/N/T, T étant le temps entre deux accumulations.
- On peut réaliser un déphasage en initialisant l'accumulateur.
- Si on souhaite une sortie sinusoïdale, il suffit de calculer le sinus de la phase en sortie ou utiliser une table.
Quelle est le format des données de sortie ? Binaire, analogique ?Envoyé par sandball22
Pour binaire, c'est simple :
[unixoide]
Mais c'est sans garantie, car usleep() fait ce qu'il peut. Pour avoir de la précision, il faut utiliser un générateur matériel (timer) qui est fait pour ça, et qu'il suffit de programmer correctement. C'est pour quelle plateforme ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 void oscillator(double frequence_hz) { /* demi-periode en micro-secondes : HPus = 1E6 / (2 x Fhz) */ unsigne long half_period_us = 5E5 / frequence_hz; for (;;) { output(1); usleep(half_period_us); output(0); usleep(half_period_us); } }
Les formats en entrées et en sortie doivent etre en binaire.
x doit être sur 24bits. Je dois utilser une table. La sortie de cette table sera sur 16bits. Avez-vous déjà réalisé ceci en c?
J'ia trouvé un programme en C++ mais je ne le comprend pas trop. Je ne sais pas si cela fait bien ce qu'à décrit diogene.
.h
.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 namespace SPUC { /*! \brief NCO with 32 bit accumulator \ingroup pll */ //!: //! Numerically controlled oscillator (with 32 bits accumulator) //! returns the top (mask_bits) MSBs from accumulator //! Useful for carrier recovery where top bits used for input to //! sine,cos lookup table. //! FCW : frequency control word //! ACC : accumulator //! Frequency must be set through interface routines set_frequency //! or reset_frequency. //! Load routine is to allow frequency to be updated (typically with //! a loop filter). //! When not changing frequency call "clock" routine. class nco { public: unsigned long phase; // char v[20]; protected: unsigned long acc; unsigned long fcw; unsigned long new_fcw; unsigned long mask_bits; public: //! Constructor nco(long bits=8); //! Reset object inline void reset() { phase = new_fcw = fcw = acc = 0; } //! Set frequency control word inline void set_frequency(unsigned long freq) { fcw = freq; } //! Set frequency control word and register for frequency control word inline void reset_frequency(unsigned long freq) { new_fcw = fcw = freq; } //! Return current phase inline long get_phase(void) { return(phase);} //! Load new frequency control word inline void load(long loop_filter_out) {new_fcw = fcw + loop_filter_out;} //! Clock NCO with new frequency control word input long clock(long loop_filter_out); //! Clock NCO without changing frequency control word long clock(); }; } // namespace SPUC #endif
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 // Set nco.h for description. #include <spuc.h> #include <nco.h> namespace SPUC { nco::nco(long bits) { acc = fcw = new_fcw = phase = 0; mask_bits = MASK_NEG_HI(bits); } long nco::clock() { acc += new_fcw; phase = acc & mask_bits; // truncate return(phase); } long nco::clock(long loop_filter_out) { new_fcw = fcw + loop_filter_out; return(clock()); } } // namespace SPUC
Alors c'est du numérique (24-bit / 16-bit) et non du binaire ! (1-bit).Envoyé par sandball22
Je ne connais pas. Il y a des math là-dessous et je sens que ça ne va pas me plaire... Je connais mes limites...
Oui, c'est basé sur ce principe.Je ne sais pas si cela fait bien ce qu'à décrit diogene.
Partager