STM32F103C8T6 delay_us fonksiyonu

Başlatan e-design, 16 Ekim 2016, 14:00:32

e-design

merhabalar hal kütüphanelerini kullanarak delay_us fonksiyonu yapmaya çalışıyom. bir çok örnek buldum ama yeterli olmuyor. bu konuda yardımlarınızı bekliyorum.. nereyi eksik yapıyorum acaba ??

void delay_us(uint32_t micros)
 {
    micros *= (SystemCoreClock / 1000000) / 6;
		micros=micros-10; // fazla sayilan clocklar (deneme yanilma ile)
    while (micros--);
 }


1000 us bekleme için 750ns bi hata payı oluşuyor.


Elektroemre

Hocam çok hassas zamanlamaya ihtiyacın varsa bunu timer'lar ile yapacaksın. STM32F103'te timer bol.
Diğer türlü pipeline yapıdan dolayı illaki 3-5 cycle fark olur arm işlemilerde işlemi software ile yapmak istediğinde.

z

Bu rutini çalıştırken interruptların devre dışı bırakman lazım.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Cemre.

#3
Ben SysTick'i 1uS'de oluşacak şekilde set ederek  HAL_Delay fonksiyonunu mikroSaniye cinsinden gecikme yapacak şekilde kullanmıştım. Ama doğru bir yaklaşım mı dersen bilemiyorum.

Klein

SysTick 1us'de çalışmaz.  Sistem saatini 16Mhz'e düşürmek gerekir.

skara1214

#5
En iyi ihtimal interruptlari devre dışı bırakıp 1  timeri oneshot moda ayarlayip başlatıp bitmesini beklemek

mesaj birleştirme:: 16 Ekim 2016, 19:30:00

@z hocam asm de nop komutu tam 1 cycle damı biter?
Herkes ölür ama herkes gerçekten yaşamaz

z

#6
Evet NOP tek cycle ama mecburen döngü oluşturacaksın ve rutindeki tüm komutları ele almak lazım. (bir eksiltme, sıfırmı değilmi karşılaştırması, jmp etme)

Nop komutundan önceki komutlar pipeline bufferı boşalttı mı boşaltmadı mı  da önemli.

En önemlisi de interruptın delayi kesmemesi lazım. Çok kritik bir delay değilse zamanın şaşması zaten hiç önemli değil.

Zamanlama çok kritikse zaten timer kullanırken de sıkıntı var. Int latency, timer int önceliği her şey kritik oluyor.

Kafaya takmamak lazım.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Burak B

"... a healthy dose of paranoia leads to better systems." Jack Ganssle

skara1214

Herkes ölür ama herkes gerçekten yaşamaz


e-design

@Cemre. söylediğin düzenlemeyi yaptım, hemen hemen aynı sonucu veriyor. fakat bunun hassasiyeti biraz daha düşük.
@z NOP ile döngü yapmak, döngüyü boşta çalıştırmaktan daha fazla zaman alıyor. (ilginç :))
@baran123 paylaşmış olduğu https://kbiva.wordpress.com/2013/03/25/microsecond-delay-function-for-stm32/ link
ilk denediğim link oldu fakat başarılı bir şekide çalştıramadım, o yüzden böyle bir arayış içine girdim.

Alıntı yapılan: Cemre. - 16 Ekim 2016, 18:37:19
Ben SysTick'i 1uS'de oluşacak şekilde set ederek  HAL_Delay fonksiyonunu mikroSaniye cinsinden gecikme yapacak şekilde kullanmıştım. Ama doğru bir yaklaşım mı dersen bilemiyorum.


Tagli

Eski sayılabilecek bir başlık ama bu noktada ben de takıldım. Aslında çok hassas bir zamanlamaya ihtiyacım yok, amacım bazı sinyallerdeki minimum zaman gereksinimlerini sağlamak. Örneğin HD44780 LCD sürerken E hattının en az 450 ns yüksek kalması gibi. Yani 450 ns yerine 3 us olsa da sorun olmaz. Yani ben delayUs(5) yazsam ama gerçekte 8 us gecikme olsa bu sorun olmayacaktır.

DWT tabanlı çözümler var ancak bu özellik Cortex M0'larda yok, bu sebeple daha genel bir çözüm arıyorum. Sadece bu iş için bir timer harcamak da istemiyorum, SysTick hariç tabi. Onunla bir deneme yaptım ama sonuç hüsran oldu. Bu işi çözmenin temiz bir yolu var mıdır?
Gökçe Tağlıoğlu

Yuunus

@Tagli while ile kurdugum delay func asagi yukari 15 ns kayiyor, dwt de asagi yukari ayni yani cok hassas bir timer gerekliyse external clk kullanmak projeyi ona gore dizayn etmek bence daha mantikli.

Zoroaster

LCD rutini ile tuş okuma rutinlerini birleştir. Delay gereken yerlerde işi bırak tuş rutinini işlet. LCD rutinine geri döndüğünde hem delay ihtiyacın görülmüş hem de tuş okuma işlemi gerçekleşmiş olur.

LCD ve tuş okuma rutinine iyi kafa yorup yazabilirsin.
Seytan deliginden kacti.