stm32f407 pwm frekansını ayarlayamıyorum

Başlatan ttg, 13 Ekim 2013, 20:05:46

ttg

Merhabalar,
STM32f407 discovery ile servo sürmek istiyorum. Muhittin Hoca'nın http://muhittinkaplan.com/2013/08/rc-servo/ linkindeki kodunu, Peripheral Lib in örneklerindeki kodu birlikte götürerek Prescaler ve ARR değerlerini hesaplamaya çalıştım ama işin içinden çıkamıyorum. Öncelikle,

APB'den Timer3'e apb1 prescaler 1'den farklı olduğu için kendi clock unun 2 katı geliyor ve 84 Mhz ile çalışıyor dedim. Bu durumda, linkteki kodta yer aldığı gibi, prescaler yerine 840-1'den 839 yazarak Timer 3 Counter Clock'u 100 KHz yaptım.

En son da, kodtaki ARR'yi hesaplayayım dedim, 100KHz altında 50 Hz almak istersem ARR'yi 100K/50'den 2000 buluyorum, ancak linkteki örnek kodta 400 olarak kullanılmış.

Linkteki kod sorunsuz çalışıyor, yani benim bir hatam var ama bulamadım. Sizce hangi noktayı atlıyorum?
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm

muhittin_kaplan


ttg

Hocam sitenizdeki kodun aynısı, sadece hesabı yapamıyorum.

Kütüphane kodunu editleyerek de denedim, onda da yazdığım kod şu olmuştu:

#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "misc.h"
#include "stm32f4xx_tim.h"

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
/* 4000 % 5 = 200 ile 4000 % 10 = 4000 arası değer alabilirler */
uint16_t CCR1_Val = 300;
uint16_t CCR2_Val = 320;
uint16_t CCR3_Val = 330;
uint16_t CCR4_Val = 340;

void TIM_Config(void);

int main(void)
{
  TIM_Config();

  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 4000 - 1; // 200000 Hz/4000 = 50 Hz
  TIM_TimeBaseStructure.TIM_Prescaler = 420 - 1; // 84E6/420 = 200000 Hz
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  /* PWM1 Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM3, &TIM_OCInitStructure);

  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

  TIM_OC2Init(TIM3, &TIM_OCInitStructure);

  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel3 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

  TIM_OC3Init(TIM3, &TIM_OCInitStructure);

  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel4 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

  TIM_OC4Init(TIM3, &TIM_OCInitStructure);

  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM3, ENABLE);

  /* TIM3 enable counter */
  TIM_Cmd(TIM3, ENABLE);

  while (1)
  {}
}

void TIM_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  /* GPIOC clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

  /* GPIOC Configuration: TIM3 CH1 (PC6), TIM3 CH2 (PC7), TIM3 CH3 (PC8) and TIM3 CH4 (PC9) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  /* Connect TIM3 pins to AF2 */
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_TIM3);
}
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm

muhittin_kaplan


ttg

Hocam ilk defa linki verdiğinizde baktım, forumda farklı örneklere bakmıştım önceden.

2. mesajdaki formüle göre hesap yapıyorum, beklenen frekans 50 Hz olduğuna göre:
Kesme oluşma süresi = (PSC+1)*(ARR+1) / APB  = 4000*420/84000000 = 0.02 s (50hz)

Ben yine hata bulamadım,
konuda altta belirttiğiniz registerların değer kısıtlamalarına halihazırda dikkat ediyorum, zaten 16 bitten aşağı bir şey kullanmadım, 3999 ve 419 değerleri 0 ile 0xffff arasında olduğu için o konuda bir sıkıntı olmadığı belli zaten.
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm

muhittin_kaplan

#5
void InitTimer3(){
  RCC_APB1ENR.TIM3EN = 1;
  TIM3_CR1.CEN = 0;
  TIM3_PSC = 55;
  TIM3_ARR = 59999;

  NVIC_IntEnable(IVT_INT_TIM3);
  TIM3_DIER.UIE = 1;
  TIM3_CR1.CEN = 1;
}

50Hz dedi program.

mesaj birleştirme:: 13 Ekim 2013, 21:10:40

senin peryodun 0,01sn mi çıkıyor gerçekte

ttg

Evde logic analyzer veya osiloskop yok malesef şu an ölçemiyorum.

Bana da sizinle aynı rakamları vermişti program, onları da denedim sonuç yine hüsran. Şu ana kadar çalıştırabildiğim tek kod sizin blogda yer alandı.

Timer3 ün clock hızını 168mhz alırsak formüle göre 2 ms çıkıyor yazdığınız kodun sonucu. Timer clock unu 84mhz kabul etmiştim, peripheral libde şöyle bir ifade var:
"
    In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),
    since APB1 prescaler is different from 1.
      TIM3CLK = 2 * PCLK1
      PCLK1 = HCLK / 4
      => TIM3CLK = HCLK / 2 = SystemCoreClock /2
"

4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm


ttg

Hocam cevabınız için teşekkür ederim. Linke de baktım yaptığım hesaplardan farklı bir şey göremedim. Ama sonuç olarak benim pwm hala bu hesaplardaki gibi işlemiyor.

Bir de sizin kodu hala anlayamadım.

   TIM_TimeBaseStructure.TIM_Period=400;
    TIM_TimeBaseStructure.TIM_Prescaler=839;


84 mhz de çalışan bir timer için 401*840/84m yapınca 0.00401 geliyor. İşin garibi benim servo sizin kodla çalışıyor, bu hesaplara göre yapınca çalışmıyor. Ben hala neyi atladığımı bulamadım.
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm

muhittin_kaplan

kodları nasıl hesapladım hatırlamıyorum.
ama 400*840/16800000 yapmışım gibi

ttg

hocam dediğiniz hesap tutuyor. En baştaki soruna dönüyorum, neden 168000000? Hangi kaynağa baksam 84mhz de çalışıyor bu arkadaş
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm

Klein

Alıntı YapAPB'den Timer3'e apb1 prescaler 1'den farklı olduğu için kendi clock unun 2 katı geliyor ve 84 Mhz ile çalışıyor dedim. Bu durumda, linkteki kodta yer aldığı gibi, prescaler yerine 840-1'den 839 yazarak Timer 3 Counter Clock'u 100 KHz yaptım.

Timer3 Clock sinyali 42Mhz değil ki iki katı 84MHz olsun. İki katı geliyorsa 168MHz olur.

ttg

Alıntı yapılan: Klein - 14 Ekim 2013, 00:34:30
Timer3 Clock sinyali 42Mhz değil ki iki katı 84MHz olsun. İki katı geliyorsa 168MHz olur.
Hocam apb1 max. 42 mhz, timer3 için şu linkte: http://gunluk.muuzoo.gen.tr/2012/07/29/stm32f4-discovery-maceralari-7-buton-okuma-ve-timer-kullanimi/
şöyle bir alıntı yapılmış:
"The timers connected to APB2 are clocked from TIMxCLK up to 168 MHz, while the timers connected to APB1 are clocked from TIMxCLK up to 84 MHz."

TIM3 apb1 üzerinde olduğu için hesap kitap uğraşıp bir türlü 168 yapamadım onu. Bir de kodu aldığım örnekte şu yazıyor:
"
    In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),
    since APB1 prescaler is different from 1.
      TIM3CLK = 2 * PCLK1
      PCLK1 = HCLK / 4
      => TIM3CLK = HCLK / 2 = SystemCoreClock /2
"

Bu da Core Clock/2 den 84 diyor.
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm

Klein

Programında RCC_CFGR->PPRE1 registerinin değeri nedir?

ttg

4 olarak ayarlanmış:

    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm