Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => Konuyu başlatan: Analog - 21 Nisan 2018, 01:02:54

Başlık: Buton ve PWM
Gönderen: Analog - 21 Nisan 2018, 01:02:54
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 ?
Başlık: Ynt: Buton ve PWM
Gönderen: M.Salim GÜLLÜCE - 21 Nisan 2018, 16:37:08
External kesme olmaz tabiiki timer kullanmalısın.
Başlık: Ynt: Buton ve PWM
Gönderen: Analog - 21 Nisan 2018, 19:03:56
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)
 {
 
 }
 
}
Başlık: Ynt: Buton ve PWM
Gönderen: M.Salim GÜLLÜCE - 21 Nisan 2018, 19:23:45
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.
Başlık: Ynt: Buton ve PWM
Gönderen: crazy - 21 Nisan 2018, 21:16:53
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);
 
 }
 
 
Başlık: Ynt: Buton ve PWM
Gönderen: Analog - 22 Nisan 2018, 15:01:47
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);
    }
   
 }