Bro Bro
Bro Bro

Reputation: 11

How to achieve a gradual change in frequencies for a sweep (chirp) signal on STM32F4?

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?

enter image description here

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.

enter image description here enter image description here

Upvotes: 0

Views: 126

Answers (0)

Related Questions