Bluepill-DDS-Generator          


Elektronik-Labor  Projekte   


Gerade ist mein Interesse an der Bluepill-Platine wieder neu erwacht, weil ich hier hervorragende Anwendungen in der Messtechnik sehe. Der STM32F103C8 kann mit 72 MHz getaktet werden. Dieser Takt geht auch auf die Timer, mit denen schnelle PWM-Signale erzeugt werden können. Mit einem Clock von 72 MHz und einer PWM-Auflösung von 10 Bit (1024) beträgt die PWM-Frequenz noch rund 70 kHz (genauer 70312,5 Hz).



Für eine DDS braucht man eine Funktionstabelle, deren Werte als PWM-Werte ausgegeben werden. Hier wird eine Sinus-Tabelle in dds[4096] berechnet. Eine zweite Sinus-Funktion wird in der While-Schleife verwendet und über die virtuelle serielle Schnittstelle ausgegeben. Die 500 Werte für eine volle Sinusschwingung passen gut zum Arduino-Plotter, der die Daten über die USB-COM empfängt.

  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);
TIM2->CCR1 = 200;
TIM2->CCR2 = 100;
TIM2->CCR3 = 400;
for (n=0;n<4096;n++){
dds[n]= 512+511*sin(n/4096.0* 2*3.1415);
}
HAL_TIM_Base_Start_IT(&htim2); //Timer-Interrupt freigeben
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
for (n=0;n<500;n++){
k= 512+511*sin(n/500.0* 2*3.1415);
sprintf(buffer,"%d \r\n", k);
CDC_Transmit_FS(buffer, strlen(buffer));
HAL_Delay (0.01);
}
HAL_Delay (500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */





Der eigentliche DDS-Code steht in einer Interrupt-Funktion, die beim Überlauf des PWM-Timers aufgerufen wird. Man holt jeweils Stützwerte aus der Sinus-Tabelle und gibt sie als PWM-Weite aus. In diesem Beispiel werden gleich zwei unterschiedliche Frequenzen im Verhältnis 6/5 erzeugt, die Werte werden numerisch addiert und dann erst ausgegeben. Auskommentiert ist der vergleichbare Code ohne eine Tabelle, aber mit einer Echtzeit-Berechnung von zwei Dreiecksignalen.

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //Timer-Interrupt
{
i+=500;
j+=600;
out1 = dds[i>>4] >>1;
out1 = out1 + dds[j>>4] >>1;
TIM2->CCR2 = out1 ;
// i+=5;
// j+=6;
// if (i>1023) i=0;
// if (j>1023) j=0;
// if (i<511) out1 = i;
// if (i>511) out1 = 1024-i;
// if (j<511) TIM2->CCR2 = j + out1;
// if (j>511) TIM2->CCR2 = 1024-j+ out1;*)
}
/* USER CODE END 4 */



Zwischen PA1(=PWM Ch 2) und den Scope wurde ein Tiefpassfilter mit 100 k und 2,7 nF eingefügt. Die höhere Frequenz beträgt 70312,5 Hz * 600 /4096/16 =643,73 Hz, die tiefere ist 536,44 Hz.



Elektronik-Labor  Projekte