Haberler:

Eposta uyarılarını yanıtlamayınız ( ! ) https://bit.ly/2J7yi0d

Ana Menü

Buton ve PWM

Başlatan Analog, 21 Nisan 2018, 01:02:54

Analog

Merhabalar butona basınca PWM üretmek istiyorum yalnız kesme kısımında biraz kafam karıştı ve danışmak istedim.

Timer kesmesinden mi yola çıkmalıyım yoksa buton için external bir kesmeden mi ?

M.Salim GÜLLÜCE

External kesme olmaz tabiiki timer kullanmalısın.

Analog

Enbaşta şöyle bir kod yazmıştım harıcı kesmeyle ilgili. Burada butona basınca pwm i uretiyoruz ama butondan çekınce pwm durmuyor aynen devam ediyor.

void GPIO(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
 GPIO_PinAFConfig( GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
 GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12 ;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
} 


void Timerconf(uint16_t prescaler, uint16_t period, uint16_t pulse )
{
 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
 TIM_OCInitTypeDef TIM_OCInitStructure;
 
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
 
 TIM_TimeBaseInitStructure.TIM_Prescaler = prescaler;
 TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
 TIM_TimeBaseInitStructure.TIM_Period = period;
 TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
 TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
 TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
 
 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
 TIM_OCInitStructure.TIM_OutputState =TIM_OutputState_Enable;
 TIM_OCInitStructure.TIM_OutputNState =TIM_OutputNState_Disable;
 TIM_OCInitStructure.TIM_Pulse =pulse; //duty cycle
 TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High;
 TIM_OCInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_High; 
 TIM_OCInitStructure.TIM_OCIdleState =TIM_OCIdleState_Reset; 
 TIM_OCInitStructure.TIM_OCNIdleState =TIM_OCNIdleState_Reset;
 TIM_OC1Init(TIM4,&TIM_OCInitStructure);
 
 TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
 
 TIM_Cmd(TIM4,ENABLE);
 
}

void buton(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 EXTI_InitTypeDef EXTI_InitStructure;
 NVIC_InitTypeDef NVIC_InitStructure;
 
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);// BUTON ICIN
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 EXTI_InitStructure.EXTI_Line =EXTI_Line0;
 EXTI_InitStructure.EXTI_Mode =EXTI_Mode_Interrupt;
 EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Rising;
 EXTI_InitStructure.EXTI_LineCmd =ENABLE;
 EXTI_Init(&EXTI_InitStructure);
 
 NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
 NVIC_Init(&NVIC_InitStructure);
 
}

void  EXTI0_IRQHandler(void)
 {
 if(EXTI_GetITStatus(EXTI_Line0) != RESET)
 {
 
 Timerconf(500,9999,7499);
  EXTI_ClearITPendingBit(EXTI_Line0);
  
 }
 
 }
int main()
{
 GPIO();
 buton();
 //kesme();
  //Timerconf(500,9999,7499);
 
 while(1)
 {
 
 }
 
}


Bir diğer yaklaşımımda tımer kesmesiyledi ama burada kesme fonksiyonunun içine ne yazmam gerektiğini tam belirleyemedim.
void kesme(void)
{
 
 NVIC_InitTypeDef NVIC_InitStructure;
 
 NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStructure);
}
void TIM4_IRQHandler(void)
{
 if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
 { 
 
 TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
 
 }
}
void GPIO(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
 GPIO_PinAFConfig( GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
 GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12 ;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
} 


void Timerconf(uint16_t prescaler, uint16_t period, uint16_t pulse )
{
 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
 TIM_OCInitTypeDef TIM_OCInitStructure;
 
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
 
 TIM_TimeBaseInitStructure.TIM_Prescaler = prescaler;
 TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
 TIM_TimeBaseInitStructure.TIM_Period = period;
 TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
 TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
 TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
 
 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
 TIM_OCInitStructure.TIM_OutputState =TIM_OutputState_Enable;
 TIM_OCInitStructure.TIM_OutputNState =TIM_OutputNState_Disable;
 TIM_OCInitStructure.TIM_Pulse =pulse; //duty cycle
 TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High;
 TIM_OCInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_High; 
 TIM_OCInitStructure.TIM_OCIdleState =TIM_OCIdleState_Reset; 
 TIM_OCInitStructure.TIM_OCNIdleState =TIM_OCNIdleState_Reset;
 TIM_OC1Init(TIM4,&TIM_OCInitStructure);
 
 TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
 
 TIM_Cmd(TIM4,ENABLE);
 
}

void buton(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 EXTI_InitTypeDef EXTI_InitStructure;
 NVIC_InitTypeDef NVIC_InitStructure;
 
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);// BUTON ICIN
 
 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}
int main()
{
 GPIO();
 buton();
 kesme();
  Timerconf(500,9999,7499);
 
 while(1)
 {
 
 }
 
}

M.Salim GÜLLÜCE

Doğrusunu istersen ben sadece donanımsal tarafından bakıyorum.
İşlemci ne kullanıyorsun bilmiyorum.
Ama içinde bir PWM aygıtı vardır veya yoktur ve sen onu kontrol ediyorsun. Aygıt varsa Parametrelerini set edip enable ediyosundur. Aygıt yoksa PWM karakteristiklerini timer interrupt ile belirliyorsun. Doğru zamanlama duty ve frekansı interrupt timerına göre ayarlıyorsundur.

Butona basınca PWM i aktive edeceksin. Bırakınca pasif edeceksin.
Yada bir basışta aktif 2. basışta pasif.

Tamamen sana kalmış.

Kod bilen arkadaşlar senin kodları ayrıca yorumlayacaklardır.

crazy

#4
void  EXTI0_IRQHandler(void)
 {
 if(EXTI_GetITStatus(EXTI_Line0) != RESET)
 {
 TIM4->CR1	^= (1<<0);//Timer on --off
 Timerconf(500,9999,7499);
  EXTI_ClearITPendingBit(EXTI_Line0);
  
 }
 
 

Analog

Yorumlarınız için teşekkür ederim. External kesmeyle çözdüm


Alıntı Yapvoid  EXTI0_IRQHandler(void)
 {
    if(EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
       sayici=sayici+1;
       mode= sayici%2;
            if(mode==1)
            {
               Timerconf(500,9999,7499);
       
            }
       else if (mode ==0)
            {
               TIM_Cmd(TIM4,DISABLE);
            
            }
       
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
   
 }