Elektronik-Labor
Projekte
Mikrocontroller
Raspberry
Aus RPi Pico Schaltungen und Projekte Kap. 29
Die meisten Klänge enthalten nicht nur eine Frequenz, sondern mindestens noch Vielfache der Grundfrequenz mit abnehmender Amplitude bei steigender Ordnungszahl. Jede Kurvenform lässt sich aus Sinusschwingungen der passenden Frequenz, Phase und Amplitude zusammensetzen. In einigen Fällen reichen schon zwei Schwingungen, um bestimmte Klänge zu erzeugen. Eine andere Anwendung des Zweitongenerators ist die Messtechnik. Man steuert z.B. einen Kurzwellensender mit zwei Tönen an und misst dann die hoffentlich sehr schwachen Nebenausstrahlungen, die durch Linearitätsfehler entstehen können.
Die Abtastrate wurde diesmal auf 50 kHz verringert und damit eine bessere Frequenzauflösung von einem Hertz erreicht. Hier werden zwei Töne mit 440 Hz und 523 Hz und gleichen Amplituden gemischt, es wird also ein typischer Zweiklang erzeugt. Man könnte dazu zwei PWM-Ausgänge verwenden, deren Signale dann mit Widerständen zusammengeführt werden. Man kommt jedoch mit einem Ausgang aus, wenn man die Signale nummerisch addiert und dann erst ausgibt. Über die serielle Eingabe können beliebige neue Frequenzen eingegeben werden.
Zusätzlich wird der Ausgang zu einem Klasse-D-Verstärker erweitert, sodass ein hochohmiger Lautsprecher direkt zwischen D0 und D1 angeschlossen werden darf. Das PWM-Signal an D1 verläuft gegenphasig zu dem an D0, sodass sich die Signalspannung am Lautsprecher verdoppelt. Das im Oszilloskop angezeigte Signal ist wahlweise das für die Ausgabe berechnete Signal oder das über A0 gemessene Signal.
//Pico_ScopeDDS2
Zweiton
#include
"pico/stdlib.h"
#include
"hardware/adc.h"
#include
"hardware/pwm.h"
#include
"pico/multicore.h"
unsigned
int scope[1000];
unsigned
int dds[1024];
uint16_t
akku1, akku2, i;
unsigned
int f, f1, f2, dp1, dp2, t;
void
setup() {
f1=440;
dp1=f1*64/50;
f2=523;
dp2=f2*64/50;
Serial.begin(115200);
for (int j = 0; j < 1024; j++){
dds[j]=625+400* sin(2*PI*j/1024.0);
}
while(true){
if (Serial.available()){
f = Serial.parseInt();
if( f>0){
t++;
if (t>2)t=1;
if (t==1) dp1=f*64/100;
if (t==2) dp2=f*64/100;
}
}
i=0;
sleep_ms(1000);
for (int j = 0; j < 500; j++){
Serial.println ((int) scope[j]*3300/4095);
}
}
}
void
loop() {}
void
setup1() {
adc_init();
adc_gpio_init(26);
adc_select_input(0);
gpio_set_function(0, GPIO_FUNC_PWM);
gpio_set_function(1, GPIO_FUNC_PWM);
pwm_set_wrap(0, 2499); //PWM 50 kHz
pwm_set_gpio_level(0, 1250);
pwm_set_gpio_level(1, 1250);
pwm_set_enabled(0, true);
pwm_set_irq_enabled(0, true);
irq_set_exclusive_handler(PWM_IRQ_WRAP, pwm_int);
irq_set_enabled(PWM_IRQ_WRAP, true)
while (true);
}
void
pwm_int() {
pwm_clear_irq(0);
unsigned int u=dds[akku1>>6]+ dds[akku2>>6];
pwm_set_gpio_level(0,u);
pwm_set_gpio_level(1,2499-u);
akku1+=dp1;
akku2+=dp2;
if (i<500){
scope[i]=u;
//scope[i]=adc_read();
i++;
}
}
void loop1() {}
Die Summe zweier Schwingungen von
1200 kHz und 1600 Hz ergibt wieder eine periodische Kurvenform, die sich nach wenigen
Schwingungen wiederholt. Schneller wiederholt sich das Muster, wenn man genaue
Vielfache der Grundfrequenz hinzumischt. Das zweite Oszillogramm zeigt die
Mischung aus 1,5 kHz und 3 kHz.