stm32f407 Timer1(PWM) çalışmıyor.

Başlatan Gökhan BEKEN, 07 Haziran 2015, 11:04:49

Gökhan BEKEN

timer3 kullanarak PC6-PC9 arasındaki 4 kanalı pwm ile kontrol edebiliyorum
ve timer4 kullanarak PD12-PD15 arasındaki 4 kanalı pwm ile kontrol edebiliyorum
bunun dışında hiç bir timer ile hiç bir pwm kanalını kontrol edemiyorum. Şimdilik timer1 ile PE9,PE11,PE13,PE14 pinlerine pwm yapmak istiyorum. Osiloskop ile baktığımda pinler HIGH'da kalıyor.
MCU 168mhz ile çalışıyor.
stm32f4 discovery üzerinde deneme yapıyorum, pinleri şemasından kontrol ettim, bir yere bağlı değil.
void Pin1_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // Enable clock for TIM1

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); // GPIOE clock enable


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14 ; // GPIOE Configuration: TIM1 CH1 (PE9), TIM1 CH2 (PE11) TIM1 CH4 (PE13), TIM1 CH4 (PE14)
    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(GPIOE, &GPIO_InitStructure);



    GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_TIM1); // Connect TIM1 pins to AF1
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_TIM1);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_TIM1);

    /******************************************************************/
}


void Timer1_PWM_Output_Config(uint32_t PeriodValue, uint16_t PrescalerValue)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;


    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = PeriodValue - 1;
    TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);


    /* PWM1 Mode configuration */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;




    /* PWM1 Mode configuration: Channel1 */
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = PulseValue1;

    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

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

    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);

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

    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);

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

    TIM_OC4Init(TIM1, &TIM_OCInitStructure);
    TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM1, ENABLE);
    /* TIM1 enable counter */
    TIM_Cmd(TIM1, ENABLE);
}


bu da main.c kodum:
/* For 50 Hz PWM signal Prescaler and Period Values */
uint16_t Prescaler = 84;
uint32_t Period = 20000;

/* Pulse Values for Channel 1,2,3,4 */
uint32_t PulseValue1 = 0;     // Channel1 Duty Cycle %0  = (0/20000)*100
uint32_t PulseValue2 = 50000; // Channel2 Duty Cycle %25 = (5000/20000)*100
uint32_t PulseValue3 = 10000; // Channel1 Duty Cycle %50 = (10000/20000)*100
uint32_t PulseValue4 = 15000; // Channel1 Duty Cycle %75 = (15000/20000)*100

void Pin3_Config(void);
void Timer3_PWM_Output_Config(uint32_t PeriodValue, uint16_t PrescalerValue); //timer3 pwm cikislari: c6,c7,c8,c9

void Pin4_Config(void);
void Timer4_PWM_Output_Config(uint32_t PeriodValue, uint16_t PrescalerValue); //timer4 pwm cikislari: d12,d13,d14,d15

void Pin1_Config(void);
void Timer1_PWM_Output_Config(uint32_t PeriodValue, uint16_t PrescalerValue); //timer1 pwm cikislari: e9,e11,e13,e14


int main(void)
{
    SystemInit();
    SysTick_Config(SystemCoreClock / 1000); //1milisaniyelik system clock elde edelim

    Pin3_Config();
    Timer3_PWM_Output_Config(Period, Prescaler);

    Pin4_Config();
    Timer4_PWM_Output_Config(Period, Prescaler);

    Pin1_Config();
    Timer1_PWM_Output_Config(Period, Prescaler);

    TIM_SetCompare1(TIM4,900);
    TIM_SetCompare2(TIM4,1100);
    TIM_SetCompare3(TIM4,1200);
    TIM_SetCompare4(TIM4,1300);

    TIM_SetCompare1(TIM3,5000);
    TIM_SetCompare2(TIM3,10000);
    TIM_SetCompare3(TIM3,15000);
    TIM_SetCompare4(TIM3,20000);

    TIM_SetCompare1(TIM1,5000);
    TIM_SetCompare2(TIM1,10000);
    TIM_SetCompare3(TIM1,15000);
    TIM_SetCompare4(TIM1,20000);

    while(1);

}
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

#1
Hocam pc baaina gecince reference manuel i okuyarak yardimci olmaya calisacagim. Yalniz register seviyesinde yardimci olabilirim. Bu st kutuphanelerini bilmiyorum   :-\

mesaj birleştirme:: 07 Haziran 2015, 12:42:16

hocam simdi pc basina oturabildim. reference manual i actim. timX ve pwm konusu biraz derin bir konuymus. vakit problemim var ama soz verdik bir kere. hizlica anladiklarimi anlatmaya calisacagim.

mesaj birleştirme:: 07 Haziran 2015, 12:43:47

hocam simdi timer lar yukari veya asagi seklinde kurulabiliyormus. bu kisimlara sadece goz gezdirdim. konumuz ile iliskili oldugunu dusunuyorum ve bu kisimlari zaten cozdugunuzu var sayiyorum. konuya 13.3.10 pwm mode dan giriyorum.

mesaj birleştirme:: 07 Haziran 2015, 12:57:29

pwm in frequency si su TIMx_ARR register ile belirleniyor.

pwm in duty degeri ise bu TIMx_CCRx register ile belirleniyor.

The PWM mode can be selected independently on each channel (one PWM per OCx
output) by writing '110' (PWM mode 1) or '111' (PWM mode 2) in the OCxM bits in the
TIMx_CCMRx register. You must enable the corresponding preload register by setting the
OCxPE bit in the TIMx_CCMRx register, and eventually the auto-reload preload register (in
upcounting or center-aligned modes) by setting the ARPE bit in the TIMx_CR1 register.


pwm mode TIMx_CCMRx icindeki OCxM registerina 110 yada 111 yaziliarak, her bir kanaldan bagimsiz olarak secilebilir.

uyumlu olan preload registerini suradan OCxPE ve suradan TIMx_CCMRx enable etmeliyiz. bunlar pwm i automatical bir sekilde preload edecek.


bu kismi microcontroller i bilmedigim icin anlamadim. yukarida  cevirisini yapmaya calistim. siz microcontroller ile ilgilendiginizden anlamaniz muhtemel hocam.

As the preload registers are transferred to the shadow registers only when an update event
occurs, before starting the counter, you have to initialize all the registers by setting the UG
bit in the TIMx_EGR register.

update olayi cereyan ettiginde reload register i transfer ediliyormus(golgeden kasti sanirim bizim value muz)
counter i baslatmadan once TIMx_EGR registerinin UG bitinden bu durumu initialize etmek zorundaymisiz! (zorunda oldugumuzun altini cizemedim. o yuzden unlem koydum)

OCx polarity is software programmable using the CCxP bit in the TIMx_CCER register. It
can be programmed as active high or active low. OCx output is enabled by a combination of
the CCxE, CCxNE, MOE, OSSI and OSSR bits (TIMx_CCER and TIMx_BDTR registers).
Refer to the TIMx_CCER register description for more details.


TIMx_CCER registerinin CCxP biti polarity yi belirliyormus. low yada high ta active gibi.

In PWM mode (1 or 2), TIMx_CNT and TIMx_CCRx are always compared to determine
whether TIMx_CCRx ≤ TIMx_CNT or TIMx_CNT ≤ TIMx_CCRx (depending on the direction
of the counter).

pwm modunda durum soyle iken TIMx_CCRx ≤ TIMx_CNT or TIMx_CNT ≤ TIMx_CCRx bu iki register daima karsilastiriliyormus.



mesaj birleştirme:: 07 Haziran 2015, 13:13:12

The timer is able to generate PWM in edge-aligned mode or center-aligned mode
depending on the CMS bits in the TIMx_CR1 register.

edge-aligned modunda yada center-aligned TIMx_CR1 registerinin CMS bitine bagimli olarak pwm uretebilir.

bundan sonra pwm edge-aligned mode ve center-aligned mode diye bir kisim geliyor sanirim bunlarlada isimiz yok? pwm in baslangic kisminin nereden olacagini belirliyoruz. biz oncelikle ilgili pinden pwm cikartmaliyiz.




mesaj birleştirme:: 07 Haziran 2015, 13:23:47

hocam konu gercekten cok derinmis. hizlica 13.4.1 TIM1&TIM8 control register 1 (TIMx_CR1) e kadar gectim. aralarda muhakkak okumamiz gereken yerler vardi.... neyse.


tim1 i CEN biti ile enable edelim.

OPM bitini 1 yada 0 yapip deneyelim. one pulse mode u nedir okumamiz gerekliydi.

DIR: ile up yada down counter oldugunu secelim. 0 da up.

ARPE: bu biti 1 yapalim. auto preload ile ilgili olmali.

TIMx_CNT registerina value degerimizi girelim

TIMx_ARR bunada reload value degerimizi girelim.



mesaj birleştirme:: 07 Haziran 2015, 13:25:49

bunu pwm modunda nasil kullanacagiz. hangi register ile bunu sececegiz anlayamadim. ara kisimlari okumamiz gerekliydi. hocam en iyisi reference manuel dan anlamadiginiz yerleri buraya yapistirin. bende cevireyim. kisa zamanda anlayip size aktarma isini beceremedim.  :-X zaten arm microcontroller lar ile daha hic calisamadim. yazin ilk olacak insallah.

Gökhan BEKEN

İlgilendiğin için çok teşekkür ederim, @karamel, biraz daha uğraşayım ben, durumu yazarım.
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

#3
hocam rica ederim. keske becerebilseydim...

hocam bu arada bende biraz arastirdim. http://stm32f4-discovery.com/2014/05/stm32f4-stm32f429-discovery-pwm-tutorial/ burada portd ve tim4 kullanilmis. tabloda tim1 icin advenced yaziyor. digerleri general purpose.

mesaj birleştirme:: 07 Haziran 2015, 19:35:50

hocam ayni sorun buradada var. https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy.st.com%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fPWM%20Output%20on%20STM32F2XX&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=8867


logic 1 de kaliyormus.

mesaj birleştirme:: 07 Haziran 2015, 19:41:47

hocam sanirim anladim.

TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);


su code eksikmis. anladigim kadari ile counter reload olmuyor. bu yuzden ilk calistiginde 1 kere pwm uretiyor ve sonucunda pin high ta kaliyor. programa bunu ekleyip denermisiniz hocam?

mesaj birleştirme:: 07 Haziran 2015, 19:46:37

hocam sizin yaziliminizda ayni code soyle yazilmis TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);

mesaj birleştirme:: 07 Haziran 2015, 20:03:14

hocam simdi tekrar inceledimde sizin yazilimda

TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);

hepsi var. yani tezim yanlis. yazin acilen arm microcontroller ogrenmem gerekli....  :-\

Gökhan BEKEN

Linkdeki kodu olduğu gibi yüklememe ramen yine pwm alamadım.
Cubemx ile hazır oluşturdum yine çıkış alamadım. Benim discovery'den şüphelenmeye başladım artık.
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

Hocam yarin gun icinde musait olursam sizin icin deney yapabilirim. Bendede discovery pcb si var ::)

Gökhan BEKEN

Başka bir stm32f4 discovery ile denedim ama yine pwm alamadım.
Özel mesaj okumuyorum, lütfen göndermeyin.

muhittin_kaplan


justice_for_all

Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

Gökhan BEKEN

timer1'i GPIOA'ya aldım yine çalışmadı.
Özel mesaj okumuyorum, lütfen göndermeyin.

justice_for_all

#10
TIM_Cmd(TIM1, ENABLE);
den sonra

TIM_CtrlPWMOutputs(TIM1, ENABLE);


eklermisiniz

mesaj birleştirme:: 08 Haziran 2015, 14:54:00

stm32f4xx_tim.c alıntı.

Alıntı Yap===============================================================================
      ##### Advanced-control timers (TIM1 and TIM8) specific features #####
=============================================================================== 
       
             ##### TIM Driver: how to use the Break feature #####
===============================================================================
    [..]
    After configuring the Timer channel(s) in the appropriate Output Compare mode:
                         
      (#) Fill the TIM_BDTRInitStruct with the desired parameters for the Timer
          Break Polarity, dead time, Lock level, the OSSI/OSSR State and the
          AOE(automatic output enable).
               
      (#) Call TIM_BDTRConfig(TIMx, &TIM_BDTRInitStruct) to configure the Timer
         
      (#) Enable the Main Output using TIM_CtrlPWMOutputs(TIM1, ENABLE)
         
      (#) Once the break even occurs, the Timer's output signals are put in reset
          state or in a known state (according to the configuration made in
          TIM_BDTRConfig() function).

@endverbatim
  * @{
  */

acaba çalışması için yukarıdaki registerlerdemi ayarlanması gerekiyor.
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

Gökhan BEKEN

Özel mesaj okumuyorum, lütfen göndermeyin.

justice_for_all

Direkt örnekten alıntı yapıyorum hocam

  /* Time Base configuration */
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_Period = 4095;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

  /* Channel 1, 2,3 and 4 Configuration in PWM mode */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 2047;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;

  TIM_OC1Init(TIM1, &TIM_OCInitStructure);

  TIM_OCInitStructure.TIM_Pulse = 1023;
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);

  TIM_OCInitStructure.TIM_Pulse = 511;
  TIM_OC3Init(TIM1, &TIM_OCInitStructure);

//////////////////////////////////////////////////////////////////////////////////////////////////////bu kısım sizde yok

 /* Automatic Output enable, Break, dead time and lock configuration*/
  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
  TIM_BDTRInitStructure.TIM_DeadTime = 1;
  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;

  TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

  TIM_CCPreloadControl(TIM1, ENABLE);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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

  /* Main Output Enable */
  TIM_CtrlPWMOutputs(TIM1, ENABLE);


renkli kısımlar sizde mevcut değil bikaç örneğe baktım hepsinde var.
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

Karamel

Hocam cubemx tende cikis gelmiyorsa demekki birseyler cok ters gidiyor. Durum bende memleket meselesi gibi bir haldi.... Oncelikle sunu belirleyelim. Sorun tim1 demi. Yoksa pinlerdemi? Baska bir tim ile ayni pinden pwm cikartma sansimiz varmi? Yada tim1 ile baska pinden?

Gökhan BEKEN

@justice_for_all o kodu yarın deneyeceğim.
@karamel Timer1'in pwm modunda 2 farklı GPIO seçeneği var, GPIOE 9,11,13,14 ya da GPIOA 8,9,10,11
tim1'i kesme alarak kullansam eminim sorunsuz çalışır, pwm modunda bilmediğim bir ayar felan var sanırım, ben cubemx'de de bir sürü değişik varyasyon ile denedim ama sonuç alamadım. Tabi bir ton seçeneği olduğu için herbirini deneyemedim. İşin aslı bu işler deneme ile değil okuma ile olmalı ama bu aralar zaman sıkıntım var.
Özel mesaj okumuyorum, lütfen göndermeyin.