Помогите разобраться с таймером в STM32F2xx

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Родился
Сообщения: 6
Зарегистрирован: Пт дек 17, 2010 12:39:55

Сообщение Vittok07 »

Привет всем. Подскажите как с помощью таймера в stm32 менять состояние вывода микроконтроллера на противоположное с достаточно высокой частотой(порядка 10 МГц)??? Делал вот так:

Код: Выделить всё

#define TIM8_OUT_FREQ 1000000
//Настраивем таймер
void TIM8_Config(void)
{
  uint16_t PrescalerValue;  
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  //Enable the TIM8 gloabal Interrupt 
  NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  //Вычисляем значение предделителя
  PrescalerValue = (uint16_t)((SystemCoreClock / TIM8_OUT_FREQ) - 1);
  //Настраиваем таймер
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); 
  TIM_TimeBaseStructure.TIM_Period = 1;		             
  TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;   
  TIM_TimeBaseStructure.TIM_ClockDivision = 0; 	  
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
  TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);              
  //Prescaler configuration
//  TIM_PrescalerConfig(TIM8, PrescalerValue, TIM_PSCReloadMode_Immediate);     
  //Разрешаем прерывание по обновлению
  TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);
  //Врубаем таймер
  TIM_Cmd(TIM8, ENABLE);  
  //Разрешаем обработку прерывания по переполнению счетчика TIM8
  NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);    
}
//Обработчик прерывания
void TIM8_UP_TIM13_IRQHandler()
{
   if (TIM_GetITStatus(TIM8, TIM_IT_Update) != RESET) 
   { //Очищаем бит обрабатываемого прерывания
    TIM_ClearITPendingBit(TIM8, TIM_IT_Update);	     
    //Инвертируем сомтояние порта
	GPIO_Write(GPIOC, GPIO_ReadOutputData(GPIOC) ^ (GPIO_Pin_6));

   }
} 
Работает, но выходная частота не поднимается выше 428,5кГц(???), даже если задаю 1мегагерц, например. А если задаю более низкую частоту(например, 200кГц), то частота на выходе в 4 раза меньше(50кГц). В чем причина?
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

Во-первых, убедись, что осциллятор (если он внешний) завелся на нужной частоте. Проверь умножители и делители PLL и убедись, что на выходе нужная частота (если используется PLL). Проверь умножители/делители шин AHB и APB. Убедись, что ты устанавливаешь правильные значения предделителя и счетчика таймера. Убедись, что скорость GPIO установлена правильно и соответствует твоим требованиям. Если все верно, то прерывания должны генерироваться с правильной частотой.

Но все это бессмысленно. Давай прикинем. Какая частота МК? Где-то 120 МГц, да? Значит в лучшем случае на такт будет тратиться порядка 8.3 нс. Прерывания ты хочешь генерировать с частотой 10 МГц, то есть каждые 100 нс. Одна только подготовка к вызову обработчика прерывания в Cortex-M требуют 12 тактов, или 99.6 нс. Я уже не говорю про вызов всяких дурацких функций в прерывании, которые займут намного больше тактов. Так что забудь о программном решении, я уверен, что дергать ножкой можно и аппаратно, почитай внимательно Reference Manual.

Ну и как совет. Люди, перестаньте использовать эти дурацкие библиотеки и драйвера, где простейшие процедуры представляют собой непонятную кашу из кода, занимающую пару экранов. Ну потратьте же немного сил и разберитесь с периферией. Ибо для инвертирования ножки вызывать три функции с несколькими параметрами - это мозг головного рака в чистом виде.
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Режим PWM вам в помощь.
Ответить

Вернуться в «ARM»