Точность PLL STM32F4

#stm32 #stm32ldiscovery

#stm32 #обнаружение stm32ldiscovery

Вопрос:

Я пытаюсь настроить часы на обнаружении STM32F4 для точного измерения времени. У меня такая конфигурация:

 int main(void)
{
NVIC_InitTypeDef nvici;
GPIO_InitTypeDef gpioi;
TIM_TimeBaseInitTypeDef timtbi;
SystemInit();
RCC_HSEConfig(RCC_HSE_ON);
RCC_PLLConfig(RCC_PLLCFGR_PLLSRC_HSE, 8, 320, 8, 8);
RCC_PLLCmd(ENABLE);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCK);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
nvici.NVIC_IRQChannel = TIM2_IRQn;
nvici.NVIC_IRQChannelPreemptionPriority = 0;
nvici.NVIC_IRQChannelSubPriority = 1;
nvici.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(amp;nvici);

gpioi.GPIO_Pin = GPIO_Pin_15;
gpioi.GPIO_Mode = GPIO_Mode_OUT;
gpioi.GPIO_OType = GPIO_OType_PP;
gpioi.GPIO_Speed = GPIO_Speed_100MHz;
gpioi.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD,amp;gpioi);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
timtbi.TIM_Period = 20000000;
timtbi.TIM_Prescaler = 0;
timtbi.TIM_ClockDivision = 0;
timtbi.TIM_CounterMode = TIM_CounterMode_Up;
timtbi.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, amp;timtbi);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
GPIO_SetBits(GPIOD,GPIO_Pin_15);


while(1)
    {
    }
}

void TIM2_IRQHandler()
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIO_ToggleBits(GPIOD,GPIO_Pin_15);
}
 

при этом у меня должен быть источник TIM2 с тактовой частотой 20 МГц, но, похоже, он имеет разную частоту (разница примерно в 10-30%). Эта проблема появляется для всех других конфигураций PLL, которые я пробовал, но когда я использую HSE как SYSCLK напрямую, она работает просто отлично. Я делаю что-то не так, или это ФАПЧ, который ненадежен?

Ответ №1:

Не могу со 100% уверенностью сказать, проблема ли это, но после включения использования HSE RCC_HSEConfig() вы должны вызвать RCC_WaitForHSEStartUp() , так как требуется некоторое время, чтобы HSE начал колебаться, и проверьте код возврата, чтобы убедиться, что вызов был успешным и HSE действительно инициализирован.

Кроме того, если вы используете system_stm32f4xx.c файл, который поставляется со стандартной периферийной библиотекой, вы можете отказаться от кода инициализации PLL и просто использовать код, который вызывается SystemInit() . Есть несколько #define s, которые управляют конфигурациями PLL, рядом с началом файла ( #define PLL_M , #define PLL_N и так далее; их назначение должно быть самоочевидным). Я всегда инициализирую свои часы, используя код там, и они всегда точны с точностью до точности кристалла. Обратите внимание, что этот код предполагает генератор с частотой 25 МГц, используя PLL_M значение, равное 25, поэтому вы должны установить его равным 8 для использования с платой STM32F4DISCOVERY — точно так, как вы уже сделали в своем коде. Я предлагаю это не потому, что у меня есть какие-либо предубеждения против вашего кода, но код там был протестирован повсюду, и, по моему опыту, ему можно доверять.