CubeMX ile init edilen timer ın ayarlarını değiştirme

Başlatan izturk, 20 Nisan 2018, 12:14:08

izturk

Merhaba Arkadaşlar,

Cube MX den timer ayarlarını yapıyorum. Encoder modda çalıştırıyorum.

static void MX_TIM8_Init(void)
{

  TIM_Encoder_InitTypeDef sConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim8.Instance = TIM8;
  htim8.Init.Prescaler = 3;
  htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim8.Init.Period = 65535;
  htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim8.Init.RepetitionCounter = 0;
  sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC1Filter = 0;
  sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC2Filter = 0;
  if (HAL_TIM_Encoder_Init(&htim8, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

cube mx yukardaki init kodunu üretiyor.
yanlız benim program içerisinde prescaler değerini değiştirmem gerekiyor.

her seferinde bu kodlarla değiştirmektense

TIM8->PSC = 27;

gibi direk prescaler değerini değiştiriyorum ama herhangi bir değişiklik olmuyor.

Bu HAL kütüphanesini kullanarak bu tip ayarları nasıl değiştirebiliriz.
Ya da benim yaptığım gibi direk register değiştirince neden çalışmıyor?

Zoroaster

Encoder modunda timer neden prescalerdan etkilensin? Clk palsleri disaridan gelen sinyalden uretiliyor.
Seytan deliginden kacti.

izturk

Yanlış anlattım galiba hocam. Etkilenme yok.

Ben enkoderden örneğin 5 pals geldiğinde 1 saysın veya 20 pals geldiğinde 1 saysın gibi program döngüsünde değiştirmek istiyorum. Bunun için prescaler değerini değiştiriyorum.


Zoroaster

Prescaler timera systemclk tarafindan gelen clklari bolmek icin. Prescaler encoderdan gelen palaslerin yolu uzerinde olmadifindan dedigini yapamazsin.

Onu ancak okudugun counter degerini matematiksel olarak bolme islemiyle yapabilirsin.
Yani encoderdan gelen palsleri donanim saysin sen counteri oku ve okudugun degeri kaca istiyorsan bol.
Seytan deliginden kacti.

izturk

Hocam ama cubemx te ilk ayarlamayı yaparken prescaler i değiştirdiğimde veya yukardaki kodlarda
htim8.Init.Prescaler = 3;
değerini değiştirdiğimde istediğim oluyor.


foseydon

donanımın detayını bilmiyorum, fakat bir peripheral'i çalıştırdıktan sonra register'ları ile oynarsanız değişiklik olmayabilir, bunun için peripheral'ı tekrar başlatmak gerekebilir. hatta durdurup, değişiklik yaptıktan sonra tekrar başlatmak şeklinde yapılması gerekiyor olabilir. genel olarak donanımı init ettikten sonra elleşmeyin, benim uymaya çalıştığım bir prensip bu.

izturk



prescaler encoder interface den sonra bölüyor. Bence çalışması mantıklı. Ama bu değeri direk registerina yazınca neden değiştiremiyorum.

Zanet bu init kodlarını yeniden çağırıp
htim8.Init.Prescaler = 3;
değerini değiştirince de istediğim gibi sayıyor.

Daha önce cubemx le pwm ayarlayıp program içerisinde direk registerı değiştirerek duty sini oynayabiliyordum.
Prescaleri ben yanlış bir yere mi yazıyorum acaba. Encoder modda başka bi yere mi yazmak gereiyor

Zoroaster

TIM8->PSC = 27; dedinmi system clk tarafindan gelen clklari bolmekten bahsetmis olursun.

Senin bahsettigin prescaler TIM8_CCMR1 registeri icinde.
Seytan deliginden kacti.

izturk

IC1PSC: Input capture 1 prescaler

hocam ccmr1 registeri içindeki prescaler sadece 1 2 4 8 olarak bölüyor. bu benim işimi görmüyor.

htim8.Init.Prescaler = 3;

debug yapıp bakıyorum bu değeri TIM->PSC ye yazıyor.
ben bunun yerine 27 yazdığımda register değişiyor. ama hala 3 müş gibi çalışıyor.

durdurup yazıp tekrar çalıştırıyorum olmuyor.
timer ın clk beslemesini kesiyorum. yazıp tekrar veriyorum nafile.


Zoroaster

Senin dusundugun yapiyi anlamadim.

Cipe A-B sekline 2 kanalli bir artimsal encoder bagladiginda counter icerigi ana prescaler degerinden etkilenmez. Presalera ne yazarsan yaz onemi olmaz. Cunku clock palsleri AB kanalindan gelir.
Seytan deliginden kacti.

izturk



hocam ilk baştaki presaer yanlış bilmiyorsam TIM8->PSC

ben buraya 3 yazıp projeyi oluşturduğumda enkoderime 1 tur attırdığımda 1024 sayıyor.
buraya 27 yazdığımda 7 tur attırdığımda ekranda 1024 sayıyor.

yani TIM->PSC değeri enkoderi bölüyor.bunu bizzat test ettim.

benim tek derdim TIM8->PSC değerini direk yazarak değiştirememem. muhtemelen bunu hal kütüphanesi engelliyor.
Fonksiyonların içini karıştırdığımda lock unlock gibi terimler var ama mevzuya tam hakim olmadığımdan anlayamadım.


Tagli

izturk'un mantığı doğru, prescaler değeri sayacı etkiler, çünkü sinyal TI1FP1 & TI2FP2 -> CK_PSC yolunu izleyerek gelip sayacı arttırıyor. Yani normalde yeni bölme oranı ile çalışması lazım.

Hatayı ben de göremedim. Ancak yeni PSC'nin geçerli olması için bir update event (UE) oluşması gerekiyor dokümandan anladığım kadarıyla. Eğer timer taşma yapmıyorsa belki bu sebeple yeni değer geçerli hale gelmiyor olabilir. UE taşma olmadan elle de oluşturulabilir ancak bu durumda sayacı sıfırlayacaktır. Belki eski değer yedeklenip UE'den sonra yerine yazılabilir. Bu dediklerimi denemedim ama dokümandan anladığım bu.

Alıntı YapPSC contains the value to be loaded in the active prescaler register at each update event.
Gökçe Tağlıoğlu

izturk

@Tagli hocamın dediği gibi çalıştı.
Taşma yapmadığı için yenilenmiyormuş.

Update event elle nasıl oluşturulabilir hocam. Eski değer sıfırlanacak. Sayıcının eski değeri benim için önemli değil.

Tagli

TIM8->EGR'deki UG bitini (bit 0) 1 yaparak UE oluşturabilirsin.
Gökçe Tağlıoğlu

izturk

Tamamdır hocam tam istediğim gibi oldu. ;D

Vakit ayırıp cevap veren herkese teşekkür ederim.