STM32F103 Sorularım

Başlatan yldzelektronik, 08 Aralık 2016, 16:43:46

yldzelektronik

Merhaba,

Bu mcuyu kullanmak istiyorum. Bilmediğim taraflarıyla ilgili sorularımı buradan sormak istiyorum.

İlk sorum mcu kristali kurmak ile ilgili. Stm32f0 da clock config tool ile dosyayı oluşturabiliyordum.Bu seri için böyle bir dosya yok. Yada ben bulamadım. @muhittin_kaplan sizin sayfanızda
SystemInit()
çağrısı var.Ancak fonksiyonu bulamadım. Clock ayarlarını nasıl yapıyorsunuz?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Tagli

#1
STM32CubeMX diye yeni bir program var. Bunun üzerinden işlemci seçip clock ayarlarını yapmak mümkün. Gerçi bu program STM32Cube sistemi kullanan bir proje üretiyor doğrudan ama içinden sadece system_device.c dosyası alınabilir sanırım. Tahminimce içindeki SystemInit() fonksiyonu senin yaptığı ayarlara göre oluşturuluyor.
Gökçe Tağlıoğlu

muhittin_kaplan

@yldzelektronik Hocam System init i çağırmanıza gerek yok aslında .
system init fonksiyonu system_stm32f10x.c doyasının içeriğindedir. Biz çağırmasak dahi startup_stm32f10x_MD.s dosyası tarafından çağrılıyor.

burada dikkat edilmesi gereken konu HSE kullanılıyorsa bunub define edilmesidir.


yldzelektronik

Merhaba,

@Tagli hocam standard lib kullanmak istiyorum.
@muhittin_kaplan hocam cevap yazamadım.Fakat fark ettim gösterdikten sonra.

Teşekkürler.Başka bir sorum var.

HAL lib kullanılarak yapılmış bir pwm örneği var. Burada yapılmaya çalışılan tam olarak nedir?Standart lib kullanarak nasıl yapabilirim?

void Board_StepClockInit(void)
{
  TIM_OC_InitTypeDef sConfigOC;
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_ClockConfigTypeDef sClockSourceConfig;
  
  hTimStepClock.Instance = BOARD_TIMER_CLOCK;
  hTimStepClock.Init.Prescaler = TIMER_PRESCALER -1;
  hTimStepClock.Init.CounterMode = TIM_COUNTERMODE_UP;
  hTimStepClock.Init.Period = 0;
  hTimStepClock.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_PWM_Init(&hTimStepClock);

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  HAL_TIM_ConfigClockSource(&hTimStepClock, &sClockSourceConfig);
  
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(&hTimStepClock, &sConfigOC, BOARD_CHAN_TIMER_CLOCK);
  
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&hTimStepClock, &sMasterConfig);
}

void Board_StartStepClock(uint16_t newFreq)
{
  uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
  uint32_t period = (sysFreq/ (TIMER_PRESCALER * newFreq)) - 1;
  
  __HAL_TIM_SetAutoreload(&hTimStepClock, period);
  __HAL_TIM_SetCompare(&hTimStepClock, BOARD_CHAN_TIMER_CLOCK, period >> 1);
  HAL_TIM_PWM_Start_IT(&hTimStepClock,BOARD_CHAN_TIMER_CLOCK);  
}

void Board_StopStepClock(void)
{
  HAL_TIM_PWM_Stop_IT(&hTimStepClock,BOARD_CHAN_TIMER_CLOCK);
}
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

Merhaba,

Bir önceki mesajda sorduğum sorunun cevabı, pwm için timer ayarı yapmakmış. Şu sıralar bu mcu ile pwm olayını kavramaya çalışıyorum.

Şu fonksiyon ile pwm frekansını 1 Hz den 10 MHz'e kadar sorunsuz değiştirebiliyorum.Ancak pwm mhz lere çıkınca, frekansta hafif kaymalar oluyor.Bunun içinde ARR değerini bir azaltmak çözüm oluyor.Benim ihtiyacım maksimum 65khz olduğundan ilgilenmedim.Duty Cycle %50
void StartStepClock(uint16_t newFreq)
{
	if(newFreq){
		uint32_t period_cycles = SystemCoreClock / newFreq;
		uint16_t prescaler = (uint16_t)(period_cycles / 0xFFFF) + 1;
		uint16_t overflow = (uint16_t)((period_cycles + (prescaler / 2)) / prescaler);
		
		TIM_SetAutoreload(TIMER3, overflow);
		TIM_SetCompare3(TIMER3, overflow >> 1);           //overflow / 2
		TIM_PrescalerConfig(TIMER3, prescaler - 1, TIM_PSCReloadMode_Immediate);
		TIM_CCxCmd(TIMER3, TIM_Channel_3, ENABLE);
	}
}


Belki birinin işine yarar.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

Selamlar.

Uart ve Rs485 ile ilgili denemeler yapmak istiyorum.Ancak veri almayla ilgili bir şey merak ediyorum.

Rs485 ile haberleştiğimizi düşünelim. Boyutu değişen paketler gönderip aldığımızı düşünelim.Bunu nasıl halledebiliriz (Veri kaçırmadan, doğru paket kontrolü ile)?

Ring Buffer konusu bu işi çözer sanırım?Ancak kullanımı nasıl yapılabilir?Sizler nasıl yapıyorsunuz?

Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Zoroaster

USART haberleşme yazdım gitti, geldi okudum mantıgına indirgenecek kadar basitleştirilmemeli.

Uzunca bir data bloğunu yollarken/alırken rx tx hattını kısadevre edin yada açın yada toprağa kısa devre edip haberleşmeyi sekteye uğratın.

Yazılımınız hata oldu mesajı vermek yerine hiç insan müdahalesine gerek kalmadan durumu algılayıp veri iletişimini hatasız olacak şekilde kendi kendine devam ettirebilmesi lazım.

Bunun için sonsuz döngüye neden olacak flag beklemelerinden vs muhakkak timeout süreleri tanımlayarak çıkabilmelisiniz.

Sonuçta bir protokol oluşturmalısınız. Bu sizin hayal gücünüzle alakalı.

Seytan deliginden kacti.

yldzelektronik

O zaman kaçarı yok gelen giden paketler için bir standart belirleyeceksin diyorsunuz.Doğru mu anlıyorum?

Ama ben aslında daha ziyade gelen bütün paketleri bildiğimiz ama farklı uzunluklarda olan paketler için soruyorum.Yani mesela 5 farklı mesaj paketi olsun.

Paket 1 8 byte
Paket 2 3 byte
Paket 3 15 byte
Paket 4 5 byte
Paket 5 9 byte

Olan bir durum için düşünelim.x zamanda bu paketlerden herhangi biri gelebilir.Bu durumda ring buffer nasıl kontrol edilir?

Benim aklıma gelen modbusta olduğu gibi karakterler arası zaman boşluğu koymak.Farklı olarak ne yapılabilir?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

muhittin_kaplan

header koyarsın. mesajın Boyutu başında yazar.

yldzelektronik

 STx | Packet Len | Address | Address | Command | Payload | CRC | ETx

şeklinde kullansak nasıl olur?STx ve ETx transmit start ve end için sabit karakterler diğerleri zaten belli.Farklı öneriniz var mı?

Profosyonel anlamda haberleşme bu şekilde mi yapılıyor?İnsanlar genelde nasıl yapıyor öğrenmek istiyorum.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

Selamlar,

Sormak istediğim soru timer ile ilgili. Elimde led olsun. 4 adet ledi, bir timerin OutputCompare registerini kullanarak farklı zamanlarda blink edebileyim istiyorum.

Bunun için timeri 1 ms ye ye kurdum (doğru mu ifade ediyorum emin değilim). Şöyle ki;

SystemCoreClock = 71 MHz

        uint32_t period_cycles = SystemCoreClock / 1000;
        uint16_t prescaler = (uint16_t)(period_cycles / 0xFFFF) + 1;
        uint16_t overflow = (uint16_t)((period_cycles + (prescaler / 2)) / prescaler);
        
        TIM_Base.TIM_Period           = overflow;
        TIM_Base.TIM_Prescaler        = prescaler;
        TIM_Base.TIM_CounterMode      = TIM_CounterMode_Up;
        TIM_Base.TIM_ClockDivision    = 0;
        TIM_TimeBaseInit(TIMER, &TIM_Base);


Şimdi benim bundan anladığım, timer her 1 msde bir kendi sayacını bir arttırır. Yanlış mı anlıyorum?Aslı nedir?

Diğer taraftan, CCR1, CCR2, CCR3 ve CCR4 registerine her bir led için high low sürelerini eklesem, CCRx_Update irq açsam, servis rutini içinde ilgili CCR irq oluştuğunda, ledin high ve low sürelerine göre tekrar ccr_value hesaplayıp registere yazsam diye düşünüyorum.

Ancak değerleri nasıl hesaplayabileceğimi anlamadım. Bir de repitetion counter var.Bu ne iş yapar?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Klein

Kısmen yanlış anlama var.
sayıcının artışı
TimerClk / (Prescaler+1)

Timer Saat kaynağı = 72MHz ,  Prescaler = 71 ise

72000000 / (71 + 1) = 1000000 = 1MHz.

counter her mikrosaniyede bir artar.

ne zaman update kesmesi üretir?
counter  ARR+1 kadar arttığında.

ARR = 999 ise   her 1 milisaniyede bir sayıcı taşar ve aktifse kesme üretilir.

bu konfigürasyonda  CCP  kullanıyorsan

ccp periyodun = kesme periyodun olur. yani 1kHz.

CCR1 =  500  ise  çıkışın 500ms aktif 500ms pasif olur.
CCR1 = 100 ise çıkışın 100ms aktif 900ms pasif olur.

yldzelektronik

Peki ama CCR yi pwm modda kullanmak istemezsem ne olacak?CCRx  interrupt içinde ccrx değerini güncellemem mi gerekecek?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Klein

Alıntı yapılan: yldzelektronik - 20 Ocak 2017, 13:39:16
Peki ama CCR yi pwm modda kullanmak istemezsem ne olacak?CCRx  interrupt içinde ccrx değerini güncellemem mi gerekecek?

Eğer ledlerin yanma süreleri sürekli değişecekse update  kesmesinde değeri değiştirip güncellemen gerek.
Ledleri farklı zamanlarda blink etmekten kasıt tam olarak nedir?
4 led için de aynı timer kullanacaksan, ledler  aynı anda yanıp farklı zamanda söner ya da farklı zamanlarda yanıp aynı anda sönerler.

Not: repetition counter geri sayan bir sayıcı.   Repetition counteri 10'a ayarladıysan, zamanlayıcının her taşmasında değeri 1 azalır ve 0 olduğunda update olayı üretilir.
       Ama RPC için ayrı uev mi yoksa timer uev mi üretiliyordu hatırlamıyorum

yldzelektronik

Yapmak istediğim şöyle birşey.Ancak bir türlü çalıştıramadım.Linkteki elemanın yaptığı şekilde değil kendi yöntemimle timeri 1 ms irq oluşturacak şekilde ayarladım.

Ancak ocrx registerini nasıl ayarlarım anlamadm.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.