Bluepill-DDS-Generator
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.