Herkese iyi günler,
STM32F4 discovery ile ADC çalışması yapiyorum aşağıdaki kod sorunsuz çalışıyor ancak eğer STM32F4'e reset atarsam yada gücünü kesersem tekrar güç verdiğimde ADC den gerekli değerler gelmiyor bu yüzden örnek olarak H köprüsü ile kurduğum DC motoru döndürmüyor.
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
void Init_TIM()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //Structure
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //Enable clock for bus
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0; //no need for divide clock
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //count upwards
TIM_TimeBaseInitStructure.TIM_Period = 3359;
TIM_TimeBaseInitStructure.TIM_Prescaler = 0;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//init tim2 configuration above
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//output enable
TIM_OCInitStructure.TIM_Pulse = 0;//start from pulse 0
TIM_OC1Init(TIM2,&TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable);
TIM_OC2Init(TIM2,&TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM2,ENABLE);
TIM_Cmd(TIM2,ENABLE); //finally enable TIM2
}
void Delay (int time)
{
while(time--);
}
void Init_GPIO()
{
GPIO_InitTypeDef GPIO_InitStructure; //Structure
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //Enable bus clock
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //Alternate function means I will do something else with this pin
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //Push Pull
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //Pin numbers
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //Pull Up safety for init
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure); //init above configuration for GPIOA
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM2); //Declaring that you will use this pin for timer/PWM
GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM2);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //analog input for ADC
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void Init_ADC()
{
ADC_InitTypeDef ADC_Initstructure; //Structure for ADC
ADC_CommonInitTypeDef ADC_CommonInitstructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); //Enable clock for ADC1 bus
ADC_CommonInitstructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitstructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInit(&ADC_CommonInitstructure);
ADC_Initstructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_Initstructure.ADC_Resolution = ADC_Resolution_12b; //12b data means 2^12=4095 high accuracy.
ADC_Init(ADC1,&ADC_Initstructure);
ADC_Cmd(ADC1,ENABLE); //enable ADC1
}
uint16_t READ_ADC()
{
ADC_RegularChannelConfig(ADC1,ADC_Channel_7,1,ADC_SampleTime_56Cycles);
ADC_SoftwareStartConv(ADC1);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
return ADC_GetConversionValue(ADC1);
}
uint16_t AccurateADC()
{
uint16_t ADC_Data[8];
uint16_t NewData=0,FinalData=0;
for(int i=0;i<8;i++)
{
ADC_Data[i]= READ_ADC();
Delay(100);
NewData = NewData +ADC_Data[i];
}
FinalData= NewData/8;
return FinalData;
}
int main(void)
{
Init_GPIO();
Init_TIM();
Init_ADC();
GPIO_SetBits(GPIOA,GPIO_Pin_3);//For SD pins of IR2104
while(1)
{
uint16_t OutputdataADC=0;
OutputdataADC = (uint16_t) (((AccurateADC())*0.5)); //<--- Bu satır
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==RESET)
{
TIM2->CCR1 = OutputdataADC;
TIM2->CCR2 = 0;
}
else
{
TIM2->CCR1 = 0;
TIM2->CCR2 = OutputdataADC;
}
}
}
ADC nin tekrar çalışması için kodda gösterdiğim satırı comment'leyip tekrar işlemciye attıktan sonra commet'i silip tekrar atarsam ADC sorunsuz çalışıyor. İnternette araştırdığım kadarıyla çoğu kod içinde ADC için kalibrasyon yapiyor
kendi kütüphanesinde böyle birşey bulamadım sorun en baştaki kalibrasyon eksikliğindemi yada başka birşey mi? Gücü kestikten sonra tekrar güç verince ADC sorunsuz çalışmalı diye düşünüyorum daha önce bu tarz bir sorunla karşılaşmış
arkadaşlar bilgilerini paylaşırsa sevinirim.
Herkese yorumları için şimdiden teşekkürler.
NOT: Sorun benim ADC nin her konfigürasyonunu yapmamış olmam. ExternalTriggerConvEdge_None ayarı yapıldıktan sonra sorun ortadan kalktı.