Reputation: 11
I am generating a sweep signal (a sine wave whose frequency increases over time) on STM32F4 Discovery board by using a look-up table and changing the Prescaler value of TIM2. Unfortunately, the transition from one frequency to another is not smooth and continuous because Prescaler can only be an integer value. For example, if I want my sweep to start from 500Hz and reach 800Hz, I expect the output to be a continuous sinusoid which takes all values between this range. In my case, the generated wave seems to take only 500Hz, then it turns into a size with 620Hz, etc.
This is how I do that:
uint8_t Nchrip = 0; // Number of Completed Chirps [-]
uint8_t Nrepeat = 5;
double Fs = 500.0; //Chirp start frequency
double Ff = 800.0; //Chirp final freq
double Tc = 2.5; // Chirp Half Period [s]
double alpha = 0; // Frequency Sweep Rate [Hz/s]
double Cf = 0; // Maximum Allowable Frequency [Hz]
double deltat = 0; // Time Period of Wave [s]
double t = 0; // Time Variable [s]
double Ft = 0; // Wave Instantaneous Frequency Variable [Hz]
uint32_t MyClkFreq = 80000000; // Fixed APB1 Clock Frequency [Hz]
uint32_t MyPrescaler = 1 - 1; // Minimum Prescaler Value [cycles]
uint32_t MyPeriod = 80 - 1; // Fixed Period Value [cycles]
#define NS 128
uint32_t Wave_LUT[NS] = {2048, 2149, 2250, 2350, 2450, 2549, 2646, 2742, 2837,
2929, 3020, 3108, 3193, 3275, 3355, 3431, 3504, 3574, 3639, 3701, 3759,
3812, 3861, 3906, 3946, 3982, 4013, 4039, 4060, 4076, 4087, 4094, 4095,
4091, 4082, 4069, 4050, 4026, 3998, 3965, 3927, 3884, 3837, 3786, 3730,
3671, 3607, 3539, 3468, 3394, 3316, 3235, 3151, 3064, 2975, 2883, 2790,
2695, 2598, 2500, 2400, 2300, 2199, 2098, 1997, 1896, 1795, 1695, 1595,
1497, 1400, 1305, 1212, 1120, 1031, 944, 860, 779, 701, 627, 556, 488,
424, 365, 309, 258, 211, 168, 130, 97, 69, 45, 26, 13, 4, 0, 1, 8, 19,
35, 56, 82, 113, 149, 189, 234, 283, 336, 394, 456, 521, 591, 664, 740,
820, 902, 987, 1075, 1166, 1258, 1353, 1449, 1546, 1645, 1745, 1845,
1946, 2047};
alpha = (Ff - Fs) / Tc;
Cf = ((double) MyClkFreq / ((double) (MyPeriod + 1) * (double) NS));
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*) Wave_LUT (uint32_t) NS, DAC_ALIGN_12B_R);
htim2.Init.Prescaler = MyPrescaler;
htim2.Init.Period = MyPeriod;
HAL_TIM_Base_Init(&htim2);
sConfig.DAC_Trigger = DAC_TRIGGER_T2_TRGO;
HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1);
HAL_TIM_Base_Start(&htim2);
if (Nchrip == Nrepeat) {
HAL_DAC_Stop_DMA(&hdac, DAC_CHANNEL_1);
HAL_TIM_Base_Stop(&htim2);
}
void MY_TIM_UPDATE() {
htim2.Init.Prescaler = MyPrescaler;
HAL_TIM_Base_Init(&htim2);
}
void MY_DAC_UPDATE(void) {
MY_TIM_UPDATE();
deltat = (double) (((double) MyPrescaler + 1) / Cf);
// Update Time Variable [s]
(t > (2.0 * Tc)) ? (t = 0, Nchrip += 1) : (t += deltat);
Ft = (double) (Fs + alpha / 2 * t); // Update Frequency Variable [Hz]
(Ft > Ff) ? (Ft = Ff) : 1; // Check Frequency Variable
(Ft > Cf) ? (Ft = Cf) : 1; // Check Frequency Variable
MyPrescaler = (uint32_t)((Cf / Ft) - 1); // Compute Prescaler Value [-]
}
void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac) {
MY_DAC_UPDATE();
}
Could you suggest something to have a gradual transition from one frequency to another to have a similar signal?
The result that I have now is displayed on these figures: the signal in the time domain and in the frequency domain (FFT) for 300-400Hz and 400-500Hz, respectively. As it can be seen, the signal is abrupt and there is no smooth transition.
Upvotes: 0
Views: 126