PWM kontrollü Led

Başlatan sytax333, 01 Ağustos 2017, 13:37:01

sytax333

İyi günler,
Ben STM32 ve ARM programlamada daha cok baslardayım oradan buradan aldığım kodları çözmeye çalışarak ilerliyorum ve kendi amaçlarıma uygun bir şekle getirmeye çalışıyorum.
Şuan takıldığım konuda bana yardımcı olabilicek varsa cok sevinirim.

Yazdığım kod aşağıdaki gibidir;

#include "stm32f4xx.h"
#include "stm32f4_discovery.h"

void Delay (int time)
{
	while(time--);
}


void PWM_Config()
{
	GPIO_InitTypeDef 			GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef 	TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef 			TIM_OCInitStructure;
	ADC_InitTypeDef 			ADC_InitStructure;
	ADC_CommonInitTypeDef		ADC_CommonInitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA,&GPIO_InitStructure);


	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType 	= GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_12;
	GPIO_InitStructure.GPIO_PuPd 	= GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Speed 	= GPIO_Speed_100MHz;
	GPIO_Init(GPIOD,&GPIO_InitStructure);

	GPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_TIM4);

	uint16_t PrescalerValue = (uint16_t) 84;
	TIM_TimeBaseInitStructure.TIM_ClockDivision	= 0;
	TIM_TimeBaseInitStructure.TIM_CounterMode 	= TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period 		= 19999;//20ms period max
	TIM_TimeBaseInitStructure.TIM_Prescaler		= PrescalerValue;
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);

	TIM_OCInitStructure.TIM_OCMode 		= TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity 	= TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse 		= 0;

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

	TIM_ARRPreloadConfig(TIM4,ENABLE);
	TIM_Cmd(TIM4,ENABLE);

	ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
	ADC_CommonInit(&ADC_CommonInitStructure);

		//ADC_Initstructure.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
	ADC_Init(ADC1,&ADC_InitStructure);

	ADC_Cmd(ADC1,ENABLE);

}


uint16_t READ_ADC()
{
	ADC_RegularChannelConfig(ADC1,ADC_Channel_3,1,ADC_SampleTime_56Cycles);
	ADC_SoftwareStartConv(ADC1);
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
	return ADC_GetConversionValue(ADC1);

}

int main(void)
{
	uint16_t ADC_Data;
	PWM_Config();

	while(1)
	{
		ADC_Data= READ_ADC();

		TIM4 ->CCR1 = (uint16_t)((ADC_Data+600)*0.439);
	}
}


Asıl amacım PA3 pinine bağladığım potansiyometreden aldığım 10b lik datayı aralığını 1ms-2ms aralığına çevirmek ve bunu pwm çıkışını PD12 led üzerinde gözlemlemek.
Potansiyometreden aldığım analog bilgi ile pwm kontrolü kısacası. Kod kararsız çalışıyor gürültüden cok etkileniyor potansiyometreyi sabit tutsamda kendi küçük hareketler yapmaya devam ediyor nereyi yanlış yaptığımı yada eksik yaptığımı söyliyecek biri varsa şimdiden
teşekkür ederim.

mehmet

Mesajlarınıza kod eklerken"KOD"
butonunu kullanınız ve yeniden düzenleyiniz.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

baran123

Basit bir ortalama alma işini görür sanırım.

#define LEN_OF_ADC_VALUES   (32) // bu değer arttırılabilir.

int main(void)
{
    uint8_t i;
    uint16_t ADC_Data;
    uint16_t ADC_Values[LEN_OF_ADC_VALUES];
    uint32_t ADC_ValuesSum;

    PWM_Config();

    while(1)
    {
        for (i = 0; i < LEN_OF_ADC_VALUES; i++)
            ADC_Values[i] = READ_ADC();

        for (i = 0; i < LEN_OF_ADC_VALUES; i++)
            ADC_ValuesSum += ADC_Values[i];

        ADC_Data = ADC_ValuesSum / LEN_OF_ADC_VALUES;

        TIM4 ->CCR1 = (uint16_t)((ADC_Data+600)*0.439);
    }
}

sytax333

#3
Hocam yazdığınız kod bilmediğim nedenlerden ötürü çalışmadı ama söylediğiniz mantıkta kendim yazdım çalıştı teşekkür ederim ancak stm32 cıkarıp takınca 2 dakika önce calışan kod çalışmıyor sanırım adc nin kapanırken en son aldığı veri açıldığı zamanki ile eşleşmiyorsa sorun çıkarıyor eger reset atıp tekrar güç verilirse kod sorunsuz çalışıyor  sizin bildiğiniz özel bir nedeni varmı bu durumun? Birde PWM ve STM32 için internette güzel kaynak bulamıyorum genellikle baktımklarım cubeMX ile hazır çıktı alıp üzerinde oynuyor kod yazılan bir kaynak önerebilirmisiniz?