STM32F334 HRTIM yapısı hakkında.

Başlatan Logan, 26 Eylül 2016, 16:58:39

Logan

Merhaba arkadaşlar.

Uzun bir süredir STM32F334 ve CubeMx ile yüksek çözünürlüklü PWM ve 5 kanal ADC'nin (DMA ile) kullanıldığı bir proje üzerinde çalışıyorum. Sistem genel olarak H-Bridge bağlı bir IGBT modülü sürüyor. A ve B olmak üzere 2 adet PWM kullanıyorum. PWM-A, H-Bridge'in çapraz şekilde High Side ve Low Side gatelerine bağlı. Aynı şekilde B kanalı da bağlı.

Yapısal olarak bu PWM kanallarını kontrol eden 3 adet Compare registeri var ve olaylar aşağıdaki gibi gerçekleşiyor;

Timer Period = 0                ==> PWM-A Set
Compare 1 = Timer Period ==> PWM-A Reset
Compare 2 = Timer Period ==> PWM-B Set
Compare 3 = Timer Period ==> PWM-B Reset

Aynı zamanda PWM-A'nın yükselen kenarında ADC kanalları tetikleniyor ve çevrime başlıyor. Çevrim sonucunu DMA'dan ilgili değişkenlere yazıp kesme oluşturuyor. Bu kesme içerisinde de PID hesaplarını yapıyorum ve çıkan PWM değerini Compare 1 ve 3'e yazıyorum.

Ancak şöyle bir problem ile karşılaştım. Bir önceki duty değerine 2500 diyelim. PID hesaplamaları bitip yeni değer compare değişkenlerine yazıldığı zaman eğer yeni duty o esnada arka planda sürekli artan timer period değerinden daha küçük ise PWM-A için reset olayı gerçekleşmemiş oluyor ve bir sonraki adıma kadar bu kanal sürekli aktif kalıyor. PWM-B aktif olduğu anda ise patlıyor.

Masa üstünde yaptığım denemelerde osilaskop ile bu çakışmayı yakaladım ve bu duruma şöyle bir çözüm getirdim. PID hesabı sonucu çıkan yeni duty değerini, DMA kesmesi içinde değil PWM-B kanalının reset olayına bağlı bir kesme içinde yazdım. Şimdilik sorunsuz çalışıyor. Fakat bu kadar güzel özellikleri olan ve güç uygulamaları için geliştirilmiş bir MCU'nun böyle basit bir yapısı olması bana saçma geliyor.

Gözümden kaçan bir şeyler olma ihtimali de yüksek.

Konu hakkında bilgi ya da fikir sahibi olan varsa dinlemek isterim.

İyi çalışmalar.
İmza.

Klein

periyot değiştiğinde değişikliğin hemen mi geçerli olacağı yoksa ilk resetten sonra mı geçerli olacağını belirleyen bir bit vardı hatırladığım kadarıyla. "ARR preload config" ile ilgili ayarlara bir göz at.

kralsam

Alıntı yapılan: Logan - 26 Eylül 2016, 16:58:39
Merhaba arkadaşlar.

Uzun bir süredir STM32F334 ve CubeMx ile yüksek çözünürlüklü PWM ve 5 kanal ADC'nin (DMA ile) kullanıldığı bir proje üzerinde çalışıyorum. Sistem genel olarak H-Bridge bağlı bir IGBT modülü sürüyor. A ve B olmak üzere 2 adet PWM kullanıyorum. PWM-A, H-Bridge'in çapraz şekilde High Side ve Low Side gatelerine bağlı. Aynı şekilde B kanalı da bağlı.

Yapısal olarak bu PWM kanallarını kontrol eden 3 adet Compare registeri var ve olaylar aşağıdaki gibi gerçekleşiyor;

Timer Period = 0                ==> PWM-A Set
Compare 1 = Timer Period ==> PWM-A Reset
Compare 2 = Timer Period ==> PWM-B Set
Compare 3 = Timer Period ==> PWM-B Reset

Aynı zamanda PWM-A'nın yükselen kenarında ADC kanalları tetikleniyor ve çevrime başlıyor. Çevrim sonucunu DMA'dan ilgili değişkenlere yazıp kesme oluşturuyor. Bu kesme içerisinde de PID hesaplarını yapıyorum ve çıkan PWM değerini Compare 1 ve 3'e yazıyorum.

Ancak şöyle bir problem ile karşılaştım. Bir önceki duty değerine 2500 diyelim. PID hesaplamaları bitip yeni değer compare değişkenlerine yazıldığı zaman eğer yeni duty o esnada arka planda sürekli artan timer period değerinden daha küçük ise PWM-A için reset olayı gerçekleşmemiş oluyor ve bir sonraki adıma kadar bu kanal sürekli aktif kalıyor. PWM-B aktif olduğu anda ise patlıyor.

Masa üstünde yaptığım denemelerde osilaskop ile bu çakışmayı yakaladım ve bu duruma şöyle bir çözüm getirdim. PID hesabı sonucu çıkan yeni duty değerini, DMA kesmesi içinde değil PWM-B kanalının reset olayına bağlı bir kesme içinde yazdım. Şimdilik sorunsuz çalışıyor. Fakat bu kadar güzel özellikleri olan ve güç uygulamaları için geliştirilmiş bir MCU'nun böyle basit bir yapısı olması bana saçma geliyor.

Gözümden kaçan bir şeyler olma ihtimali de yüksek.

Konu hakkında bilgi ya da fikir sahibi olan varsa dinlemek isterim.

İyi çalışmalar.
Hocam PID algoritması için doğru olan değer güncelleme işlemi de aslında PWM peryodunun bittiği an değil mi?

Klein

Her zaman değil.
Motor sürme gibi uygulamalarda, eğer frekansınız düşük ise hassas pozisyonlama yaparken bir periyodun bitmesini beklemek, pozisyonun kaçmasına neden olabiliyor.

z

Alıntı YapTimer Period = 0                ==> PWM-A Set
Compare 1 = Timer Period ==> PWM-A Reset
Compare 2 = Timer Period ==> PWM-B Set
Compare 3 = Timer Period ==> PWM-B Reset

Aynı zamanda PWM-A'nın yükselen kenarında ADC kanalları tetikleniyor ve çevrime başlıyor. Çevrim sonucunu DMA'dan ilgili değişkenlere yazıp kesme oluşturuyor. Bu kesme içerisinde de PID hesaplarını yapıyorum ve çıkan PWM değerini Compare 1 ve 3'e yazıyorum.

Compare registerlerde shadow özelliği kaldırılabiliyorsa bunları iptal edin.
Bu PWM yapılındırması yanlış kurgulanmış.

Shadow register kullanmasanız dahi Timer, CMP1 değerine ulaşmadan önce ADC dönüşümü yapılmış ve PID hesaplamaları tamamlanmış olmalı.

Çok zor heleki küçük CMPR değerleri için imkansız.

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

kralsam

Alıntı yapılan: Klein - 26 Eylül 2016, 21:18:45
Her zaman değil.
Motor sürme gibi uygulamalarda, eğer frekansınız düşük ise hassas pozisyonlama yaparken bir periyodun bitmesini beklemek, pozisyonun kaçmasına neden olabiliyor.
Bilgi için teşekkürler. Hiç ihtiyacım olmamıştı. Demek ki bu tür kullanımda ihtiyaç oluyor.

Logan

Günaydın.

Klein, bahsettiğin bite bakacağım, problemi çözebilir.

kralsam, Klein zaten cevabı vermiş. Ben motor değil kaynak makinesi uygulaması yapıyorum. PWM periyodunun bittiği anda gücelleme ve hesaplama yaparsam bir sonraki periyodu da kaçırabilirim.

@z, shadow özelliği hiç dikkatimi çekmedi yeniden göz atacağım. Bu kurguya göre CMP1 değişkeni değerini tamamlamadan ADC çevrimi ve PID hesabı yapmak imkansız. Çünkü en düşük görev süresi %1 ve bu da CMP için 36 saykıl demek oluyor ki 40 khz'de çalışan bu sistemde saniye bazında hesaplama yapacak olursak;

1/40.000 = 25uSn
25uSn/2 = 12.5uSn
Max Compare değeri bir kanal için %50 dutyde 3600.
12.5 / 3600 = 3.4nSn bir saykıl.
36 x 3.4nSn = 123 nSn çıkar ki bu sürede 5 kanal ADC okuyup PID hesaplamak sizin de dediğiniz gibi imkansız.

Şimdilik yapı bu şekilde çalışıyor. Gittiğimiz güç uygulamaları eğitimlerinde bize genelde PWM'in yükselen kenarında okuma yapmamızı ve hemen arkasından hesaba sokmamız gerektiğini gösterdiler. Ancak bir noktadan sonra işler içinden çıkılmaz bir hale geliyor. Eğer benim frekansım 100khz ve üstü olsaydı bu yapı tamamen çöp olacaktı.

Varsa başka bir kurgu denemek isterim.

İyi çalışmalar.
İmza.

Klein

#7
Böyle bir işte benim yaklaşımım PID kısmını işlemciden ayırıp analog yapmak olurdu. İşlemci sadece referans gerilimi üretir, analog pid işlemciden gelen referansa göre çıkışı tutturmaya çalışır.  Kaynak makineleri konusunda pek bilgim yok ama, belki PID yapmanıza bile gerek kalmayabilir. Sadece P veya PI bile işinizi görebilir.

nonstradam

Klein eski sistemlerimiz analog ve PI kullanıyoruz D yok. senin dediğin gibi eski sistemlerimizde işlemci referans veriyor gerisiniz akım sensörü, opamp ve PWM controller hallediyor. şimdi uğraştığımız sistemde PI ı değişken yapabileceğiz. farklı kaynak formlarında farklı PI parametreleri uygulamak gerekiyor. dijital e geçirmemizin birinci nedeni bu. değişken PI elde edebilmek. analog olarakta bu mümkün fakat. işi sadeleştirip basitleştirmek. logan ın bahsettiği sorunumuz olmasa sistemi çalıştırdık zaten çokta iyi çalışıyor. texas kullansaydık bu sorunlar olmayacaktı. texas ta PWM kontrol ve PI kısımlarını CLA ya yüklüyorduk, o rutinler orada kendi kendine koşuyordu. Texas ın maliyeti stm in neredeyse 5-6 katı. projede maliyet te çok önemli olduğunadan stm i deneyelim dedik.  stm de de muhtemelen bunun önlemi alınmıştır ama bulamadık henüz. istediğimiz compare değerlerini timer reset olduktan sonra donanımsal olarak yazması, arada kabul etmesini istemiyoruz. bu işlemci dijital power için tasarlanmış bir işlemci, gerçekten çok iyi özellikleri var ama şu sorunu bir türlü aşamadık.

Klein

#9
http://www.cnblogs.com/shangdawei/p/4761966.html

Ekleme:
Değeri arada kabul etmesin, Update olayından sonra etsin istiyorsanız, ARPE = 1 olacak.  Standart kütüphanede  preload_config ya da benzeri isimli bir fonksiyonu olacaktı.

nonstradam

hocam bu bit tim1 için geçerli sanırım. HRTIM içerisinde bulamadım. HRTIM içinde preload diye bir seçenek var ama bununda register ını bulamadık, kurcalıyoruz bakalım. haberdar ederim.

Klein

#11
F3 çalıştığım bir işlemci değil. Kabaca göz gezdirdim  PREEN  biti ile ilgili gibi duruyor. Ama zamanlayıcı çok kompleks olduğu için kesin bir hükme varamıyorum.


Edit:
HRTIM_MCR -> PREEN
HRTIM_TIMxCR -> PREEN


Logan

Merhaba.

Sorunu çözdük. İlk mesajımda bahsettiğim gibi gözümüzden kaçan bir nokta olmuş. Preload ile periyod sonunda güncelleme yapabiliyorsunuz.

İyi çalışmalar.
İmza.