STM32 – HAL KÜTÜPHANELERİ İLE UART INTERRUPT

Blog sitesini açtığımdan bu yana STM32 ile USART üzerinden veri alışverişini anlatmaya değer bir konu olarak düşünmemiştim. Ancak, internet üzerinde problemlerini paylaşan kişilerin yazdıklarına bakınca yaygın bir sorun olduğunu gördüm. Buna karşılık oluşturduğum çözümü paylaşmaya karar verdim.

Sorun şu : UART üzerinden ne zaman veri geleceğini bilmiyoruz. Herhangi bir anda gelebilir, ama biz o zamana kadar USART portu gözleyip beklemek istemiyoruz. Gelecek karakter dizisinin uzunluğunu da bilmiyoruz. Yani herhangi bir zamanda bir miktar karakter gelecek, son karakter hangisi onu da bilmiyoruz. Bu koşullar altında HAL kütüphaneleri ile işimizi halledeceğiz.

Bu yayında HAL kütüphaneleri kullanarak ürettiğim çözümü sunacağım. Yeni bir icat değil, HAL öncesinde alt seviye kodlama ile yaptığımız işin adaptasyonundan ibaret.

Güncelleme : Bu konudaki daha güncel ve gelişmiş bir teknik için yeni yayınıma burayı tıklayarak ulaşabilirsiniz.

UART üzerinden veri almak için iki yöntem olduğunu hatırlatmakta yarar var. 
Bunlardan birincisi portu sürekli olarak gözleyip, gelen veri olduğunda almak. Buna İngilizce olarak "polling" Türkçe karşılığında da "yoklama" yöntemi diyoruz. Bu, CPU nun beklerken başka işlerle meşgul olmasına meydan vermediği için, sistemin çalışmasını bloke eden bir yöntem.
Diğer yöntem ise "kesme"leri, İngilizce karşılığı ile interrupt'ları kullanmak. Bu durumda Uart girişini gözlemek için CPU yu meşgul etmiyoruz. O başka işlerle meşgul olmaya devam ediyor. Veri geldiğinde "kesme" sinyali üreterek haber veriyor, bir nevi kapının zilini çalıyor. Bu yayında bu yöntemi anlatıyorum.

HAL Kütüphaneleri bize sadece uzunluğu önceden bilinen sayıda karakter almaya yarayan fonksiyonlar sunuyor. Sıkıntı bundan kaynaklanıyor.

Verinin ne zaman geleceğini bilmediğimiz için kesme (interrupt) kullanmamız gerektiği açık. Gelecek olan verinin uzunluğunu da bilmiyoruz, o halde her seferinde bir karakter alarak devam edeceğiz. Bu durumda da, gelen dizinin sona erdiğini anlamak için satırbaşı ya da başka bir özel sonlandırma karakterine ihtiyaç var. Ama çoğu uygulamamızda böyle bir işaret de tanımlanmış değil, herhangi bir karakterden sonra akış kesilebilir.

O halde geriye tek seçenek kalıyor; veri akışı belirli bir süre kesilirse alışın sonlandığına karar verip o ana kadar gelen karakter dizisi üzerinden işlem yapmak.

Bu benim GSM tabanlı cihazlar geliştirirken karşıma çıkan bir durumdu. Şebekeden ne zaman ne veri geleceğini, uzunluğunu, sonlandırma karakterinin ne olduğunu bilemezsiniz. Ama gelen şeyi de mutlaka yakalamanız gerekir.

KARAKTERLERİ TEK TEK ALGILAYARAK ÇALIŞMAK

Çözüm şu; USART kesmeyi aktive edip interrupt handler(IRQ) ile her seferinde tek karakter algılıyorum. IRQ handler her gelen karakteri bir alış bufferine yerleştiriyor, ta ki veri akışı belirli bir süre kesilene kadar. Bu süreyi de bir timer ile kontrol ediyorum. Her gelen yeni karakter ile timer’i yeniden başlatıyorum. Eğer bir sonraki karakter gecikir, timer sıfırlanırsa geliş de sonlanmış oluyor.

Her gelen karakter ile “uartReady” bayrağı dikiliyor, böylece timeri sıfırlanmış gördüğümüzde, bir şeyler geldikten sonra mı, yoksa hiç bir şey gelmeden mi sıfırlanmış anlayabiliyoruz. Birşey gelmemiş ise timer’i yeniden başlatıyoruz.

Gerisini kodlar üzerinden görelim.

PROJENİN YAPILANDIRILMASI – USART2 IT

Projede USART2 nin etkinleştirilir kesmelerinin de açılması gerekiyor. USART1’i başka amaçlarla kullandığımdan böyle bir seçim yaptım. Ayrıca verileri görüntülemek için TFT kullanıyorum. Böyle bir projenin cube IDE ile kurulmasını -biraz fazlasıyla- burayı tıklayarak görebilirsiniz.

Burada sadece USART tanımlamalarını anlatacağım. Geliştirme ortamı olarak STM32 CubeIDE kullanıyorum.

PROJENİN KURULUMU

Benim güncel uygulamam şöyle bir ihtiyaca yönelik:

Genelde tüm uygulamalarımda kullanıcı girişlerinin yapılabilmesi için bir tuş takımına ihtiyaç oluyor. Bu 4×4 mekanik bir klavye olabildiği gibi, TFT üzerinde 20-30 hatta daha fazla butondan oluşan dokunmatik bir klavye de olabiliyor.

Bir birine UART TX/RX üzerinden bağlı iki STM32F103 kiti. Tuş takımlı olan gönderen taraf (HMI), diğeri alıcı istasyon. İkisi arasındaki bağlantı sadece GND ve bir Tx/Rx telinden ibaret.

Birkaç butonlu olsun, onlarca tuşu olan karmaşık dokunmatik grafik bir panel olsun, epeyi bir CPU kapasitesi ve GPIO ayağını alıp götürüyorlar. Bu nedenle artık kullanıcı giriş ve görüntüleme işlerini ana işlemciden ayırıp, ayrı bir HMI birimine aktarmaya karar verdim.

Bu durumda HMI birimi, alıcı birime bir mouse ya da bilgisayar klavyesi gibi ASCII kodlar gönderiyor. Aksi yönde de ekranda görüntülenmesi istenen verileri alıyor.

İşte bu yayının konusu alıcı tarafı. Ne zaman ne uzunlukta veri geleceğini bilmiyorsunuz. Sadece 3-5 karakterden sonra bir süre ara verildiğinde gelen diziyi açıp bakmanız yeterli oluyor. Onun dışında alıcı birimin işlemcisi kendi süreçleriyle meşgul olmaya devam ediyor.

Proje geliştirme kurulumumda UART üzerinden birbirine bağlı iki STM32F103C8 kitim var. Bunlardan HMI görevini yürütende bir 4X4 membran klavye var. Basılan tuşun ASCII karşılığını USART üzerinden diğerine gönderiyor. Diğer modül, alıcı tarafında olan da bir STM32F103C8 kiti. USART2 üzerinden diğer modülden gelen karakterleri algılayarak TFT ekranında görüntülüyor.

İki kit arasındaki UART Bağlantısı. Kırmızı tel Rx/Tx sinyal bağlantısı, kahverengi olan ise GND. Alttaki Mapple Leaf kiti tuş takımının bağlı olduğu HMI, üstteki Pico Kiti ise alıcı birim.

İki kit birbirlerine sadece bir GND ve bir de UART sinyal teli ile bağlılar. UART bağlantısı HMI biriminin Tx pini ile alıcı ünitenin Rx pini arasında. Bu uygulamada tek yönlü haberleşme var. Başka projelerde ana üniteden HMI yönüne ekranda görüntülenmek üzere verileri de göndereceğim.

ALIŞ TARAFI STM32F103 PROJE YAPILANDIRMALARI

Burada USART2 yapılandırmasını göstereceğim. TFT ye ait SPI yapılandırmalarını önceki yayında(tıklayınız) anlatmıştım.

USART2 yi aktif duruma getirip baud rate i de 9600 a ayarlıyorum. Diğer parametrelerde değişiklik yok, varsayılanlar uygun.

USART2 yi Interrupt ile çalıştıracağımız için NVIC ayarlarını açarak interruptlarını aktif hale getirmemiz gerekiyor.

Burada önemli bir nokta var : USART interrupt kullanarak çalışıyoruz. Ama aynı zamanda Systick() kesmelerini kullanan timer’lara işimiz düşecek, onların önceliği bu UART IRQ dan yüksek olmalı ki çalışabilsinler. Aksi halde bu IRQ içinde iken Systick çalışmaz, burada çakılıp kalırız. Bununla ilgili bir yayınım vardı, görmek için tıklayınız. IRQ içinde bulunduğumuz süre kısa da olsa Timer’in durmasını istemiyorum.

Bunun için CubeMX System Core ayarları altındaki NVIC penceresini açalım:

Burada USART2 global interrupt önceliğini “0” iken “1” e çeviriyoruz, yani düşürüyoruz. Böylece Usart_IRQ artık Systick kesmelerinin çalışmasını engellemeyecek.

Bundan sonra Project/Generate Code seçeceği tıklanarak proje dosyalarımızın hazırlanmasını sağlıyoruz.

STM32 UART IT ALIŞ FONKSİYONLARI

Fonksiyon kodlarının içine açıklamaları zaten yazdığımdan daha fazlasını anlatmadan listeleri veriyorum. Aşağıdakiler main.c de USER CODE 4 bölgesi içinde yer alıyor.

USART IRQ Handler fonksiyonu. Başlıktaki notları gözardı edelim, eskiden kalma onlar.

Bu IRQ handler her gelen yeni karakteri rxBuffer’e kaydederek, timer’i yeniden başlatıyor. Bir sonraki karakteri almak üzere de HAL_Usart kesme fonksiyonunu yeniden çağırıyor. Sadece buffer dolduğunda kesme’yi yeniden açmayıp duruyor.

Bu durumda alışın yeniden başlaması için readKey() fonksiyonunun tekrar çağrılması gerekiyor.

readKey() Fonksiyonu.

ReadKey fonksiyonu, HMI biriminden UART üzerinden gelen birşey var mı diye sorgulama yapıyor. Önce kesme’nin aktif olup olmadığına bakıp, eğer değil ise aktifleştiriyor.

Bundan sonra timeOut olup olmadığına ve gelmiş karakter olup olmadığına bakarak gereken işlemleri yapıyor. Kod üzerindeki notlar yeterince açıklayıcı sanırım.

Aşağıdaki bölüm de kodların çalışmasını test etmek üzere main.c USER CODE 2 içinden çağırdığım test programı. Buradaki notlarda da yeterince açıklama var.

Bunlar da main.c başlığındaki değişken bildirim ve tanımları.

SONUÇ

Böylece, projelerimde kullanıcı girişleri için esnek bir çözüm geliştirmiş oldum. Giriş aracımın mekanik bir tuş takımı ya da dokunmatik panel olması artık ana işlemci açışından birşey değiştirmeyecek. Hem ileride görüntüleme işlerini de bu birim üzerinden yapabileceğim. Bunun bedeli de fazladan 2-3 dolarlık bir MCU daha kullanıyor olmam. Buna da değer doğrusu.

Bu yayının sonu – Selçuk Özbayraktar Temmuz 2020

24 Replies to “STM32 – HAL KÜTÜPHANELERİ İLE UART INTERRUPT”

  1. Merhabalar ben Mekatronik Mühendisliği 4. sınıf öğrencisiyim ve Batarya Yönetim Sistemi projesi yapıyorum. Master-Slave kartları UART üzerinden haberleştirme şeklinde. Slave kartlar verileri okuyup sıra sıra biriktirerek birbirilerine gönderecekler en sonunda bunlar master kartta birikecek. Master kart işleyip cevap gönderecek. Ama işte bu konuda acemiyim ve bundan sonrasını gidemiyorum bir türlü. Verileri belli olmayan bir zamanda sıra sıra göndermek, almak gibi konularda kafam karışıyor. Bu yüzden yazınızı bulup okudum ama yine de tam olarak aydınlatamadım kendimi. Bana yardımcı olabilir misiniz?

    1. Onurcan Bey merhaba,

      Problemi küçük parçacıklara bölerek ilerlemeniz gerek.
      İlk Adım:
      PC de açacağınız bir terminal programı yardımı ile UART üzerinden gönderdiğiniz üç beş karakteri mikrodenetleyicinizle algılayıp bir diziye yerleştirebiyor musunuz?

      İkinci adım : Hazır bu bağlantı kurulmuşken, mikrodenetleyicinizden PC ye bir kaç kelimelik bir text gönderebiliyor musunuz?

      Üçüncü adım : Bu işlemleri yoklama (polling) ve kesme (Interrupt) yöntemleri ile yapabiliyor musunuz?

      Bu soruların yanıtlarını aldıktan sonra projeniz hakkında başka sorularım da olacak.

      Selamlarımla,

      1. Öncelikle cevap verdiğiniz için çok teşekkür ederim.

        1. Evet bunu yapabiliyorum. Led yakıp söndürme komutu vb basit şeyler için.

        2. Evet bu da aynı şekilde.

        3. Polling yöntemi ile yaptım, Interrupt ile yapmadım.

        1. Onurcan Bey, günaydın.
          Öncelikle Interrupt ile çalışma aşamasını da geçmeniz lazım. Bunun nasıl yapılacağını bu yazışmalar ile anlatmam çok zor. Benden çok daha güzel anlatan kaynaklar da var, örneğin You Tube üzerinden Çoşkun Taşdemir’in bu konudaki yayınını tavsiye edebilirim.
          Interrupt kullanmaktan kaçınamazsınız, projenizi tam olarak bilmiyorum ama, mikrodenetleyicilerinizin seri porttan gelen bir şey var mı diye sürekli yoklama yapmak dışında işleri de vardır herhalde. O nedenle CPU başka işlerle meşgul iken seri porttan veri alma işini çevre birimlerine -bu durumda bu birim UART oluyor- bırakmak zorundasınız.
          Interrupt kullanarak UART alışını sağladıktan sonra, bunun ötesinde yardım edebilmem için projeniz hakkında daha fazla bilgiye ihtiyacım var.
          Çok sayıda slave cihazınız, bir tane de master olduğunu söylemiştiniz. Slave cihazlara S1, S2, S3 … dersek bunlardan S1 kendi verilerini S2 ye, S2 de hem S1 den geleni hemde kendi verilerini S3 e aktarıyor ve bu böyle devem ederek en sondaki master’a mı gidiyor? Bu soruların yanıtını burada vermeyin, [email protected] üzerinden devam ederiz, ama önce interrupt ile çalışma işini halledin.

          Kolay gelsin, selamlarımla.

  2. hocam merhaba bu proje dosyası olarak gönderme sansınız varmıdır timer3 degerleri ne olarak ayarlı bakmak isterim

    1. Emre Bey merhaba,
      Proje dosyalarını paketleyip göndermek benim için epey bir iş anlamına geliyor. Çoğu arkadaşlar da aldıktan sonra teşekkür bile etmeden dönüp gidiyorlar, sonuç ne oldu diye sorduğumda tenezzül edip yanıt bile vermiyorlar. Bu nedenle bu tür yardımlara yönelik motivasyonumu biraz kaybetmiş durumdayım.
      Size yeni bir şey göndermeden önce “uart ring buffer” başlıklı yayınıma baktınız mı? Zira uzun süredir ring buffer ve kesme kullanarak çalışıyorum, daha önceki yayınlarımla ilgili sorular için geri dönüp hatırlamam gerekiyor. Size de o yayınlarda anlattığım yöntemleri kullanmanızı önereceğim.
      Eğer yine de yardıma ihtiyacınız olursa, bir projenizi benim desteğimle sonuna kadar götürmek niyetinde iseniz, sürekli bir iletişim halinde sonuna kadar destek olmaya söz veriyorum.

      Selamlarımla,

    1. Umulmadık yayınların işe yaradığı oluyor, bunu yayınlamaya değer mi diye tereddüt etmiştim. İlginiz ve yorumunuz için teşekkürler Hüseyin Bey. Selamlar.

  3. Hocam merhaba iyi günler , stm32g0 serisi ile rs485 aracılığı ile esp32 ile veri alışverişi yapıyorum . Esp32 sorgu gönderiyor stm sorguyu alıp yanıt gönderiyor. Bu işlemleri yapıyorum sıkıntısız çalışıyor fakat aradan 1 saat veya daha fazla bir süre geçince stm sorguyu alıyor fakat espye yanıt veremiyor . Nedenini bulamadım sizce neden kaynaklanıyor olabilir

    1. Enes Bey merhaba,
      Kart haberleşmesinde bir sorun olduğunda genelde gönderme değil de alma işlemlerinde karşıma çıkıyor. Bu nedenle çemberi biraz daraltarak araştırmak gerekecek. STM32 bin bir süre çalıştıktan sonra sonra gönderemez duruma geldiğinden emin olmalısınız önce. Bunun için de ESP32 yi STM32 den bir yanıt gelmese de sürekli mesaj gönderen bir döngüye sokup, buna STM32 bin verdiği yanıtları bir Lojik analizör, bir osiloskop ya da sadece dinleme yapıp görüntüleyen bir başka STM32 ile gözlemenizi öneririm. Böylece STM32 mi gönderemiyor, yoksa ESP32 mi alamıyor anlayabilirsiniz. Ondan sonra hangi taraf suçlu ise o tarafta araştırmaya devam edebilirsiniz. Bunu STM32 tarafında STlink ile debugging programın işleyişini izleyebiliyoruz – bunu siz de biliyorsunuzdur, ama ESP32 üzerinde aynı şekilde online debugging yapmayı ben bilmiyorum, bunu ancak kod içinde belirli yerlerde ekrana bilgi yazan satırlar ekleyerek yapabilirim.

      İlk elemeyi yapınca sonucu bildirirseniz ilerlemek için biraz daha kafa yorabiliriz.

      Selamlarımla,

      1. Merhaba hocam öncelikle cevabınız için teşekkür ederim. Sorunun esp32 nin okumasında mı yoksa stm32 nin göndermesinde mi olduğunu test ettim hem donanımsal olarak hem yazılımsal olarak .Sorun stm32nin göndermesinde diye düşünüyorum . Bu sorunu önceden daha fazla alıyordum.Baud rate 115200 den 9600 e düşürünce sorun biraz düzeldi ama hala devam etmekte . Sizce hangi adımları izlemeliyim?

        Saygılarımla …

        1. Enes Bey merhaba,

          Madem sorunun STM32 tarafında olduğundan eminsiniz, o tarafta çalışalım.
          ST-Link debug yaptığına göre gönderme yaptığınız kod satırlarına bakmış olmalısınız. Tabi her seferinde değil de bir süre sonra takıldığına göre sürekli olarak programı durdurup devam ettirerek izlemeniz zor. Ama takıldığında debugger ile programı duraklatıp adım adım ilerleterek gönderme komutları geldiğinde programınızın nerelerde dolaştığını, Kart gönderme fonksiyonlarına girip girmediğine bakabilirsiniz. Eğer gönderme için kart kesmelerini kullanıyorsanız bu iş daha da zorlaşıyor, zira debugging işlemleri kesmeler ile pek barışık değil. O nedenle gönderme için kesme kullanmayın en azından şimdilik. Bu şekilde STM32 de bir donanım (Tx ayağında bir süre sonra ortaya çıkan bir arıza) sorunu olup olmadığını anlayabilirsiniz.

          Kodunuza bir test çevrimi yerleştirip ESP32 den gelen bireyleri beklemeden sürekli gönderme yapabilirsiniz. Böylece bu sıkıntıya yol açan başka program bölümleri var ise onları devre dışı bırakarak test etmiş olursunuz. Bu sırada ESOP sadece dinleme konumunda kalarak size Uart’dan veri gelip gelmediğini bildirebilir.

          Selamlarımla,

  4. Merhaba hocam öncelikle cevabınız için teşekkür ederim . Dediğiniz işlemleri önceden de kontrol etmiştim siz dedikten sonra da kontrol ettim . Stm32 aldığı sorgu kodunu stlink debug işlemleri üzerinden kontrol ettim .Stm32 sorgu kodunu sıkıntısız alıyor .Zaten stm32nin içinde olduğu kartta ve esp32nin içinde olduğu kartta rx ve tx durumları için(yani gönderim yapıyor veya yapmıyor durumları ) için ledler mevcut .Stm veri göndermeyi kestiği andada aslında sorgu kodunu alıyor bunu led durumundan donanımsal olarak debug durumundan yazılımsal olarak izleyebiliyorum . Rx doğru sorgu almasına rağmen gönderim sağlamıyor aradan zaman geçince . Bu sorun önceden daha sık kesilme yaratıyordu 115200 baud rate ile çalışıyordu 9600 baud rate e ayarlayınca sorun biraz çözüldü fakat aradan süre geçince yine devam etmekte . Sizce hangi adımları izlemeliyim ?
    Saygılarımla …

  5. Sayın Selçuk Hocam paylaştığınız bilgiler ve bu değerli yazı bloğu için de teşekkür ederim. Yazınızı baştan sona okudum ve tam da şu an sıkıntı yaşadığım konuda sizin yardım edebileceğinizi düşündüm.
    Sayın hocam elimde 2 adet STM32F072RBT6 modeli nucleo kart var. Ve bir de TFT LCD var. Yapmaya çalıştığım şey şu. bir karttan belirlediğim bir byte lik hex değerini ve 4 byte lik CRC ile diğer stm kartına gönderiyorum uart transmit ile. Tabiki bunu Alıcı kartta ayırıp gelen hex değeri gönderdiğim ile aynı mı kontrol edip bir de alıcı tarafında crc hesaplıyorum. Eğer gelen crc ile alıcının hesapladığı crc doğru ise birinci kartta belli uzunlukta text gönderiyorum. Örn. uint8_t text_1[ ] = “Electronic Cards” bunu da aynı şekilde birinci karta başında bir byte lik hex değeri , göndereceğim text ve textin CRC değeri ile gönderiyorum. Birinci kartta da benzer işlemleri yapıp gelen hex değeri gönderdiğimle aynı ise gönderdiğim text in her bir byte sini yeni bir diziye gömüp CRC hesaplıyorum. Gelen verinin en sonundaki CRC(textin CRC si olmuş oluyor) ile birinci kartta hesapladığım CRC aynı ise TFT LCD ye o texti yazdır diyorum. Bunu da TFT için oluşturduğum fonksiyon ile yapıyorum. Benim sorunum şurada. Kodları 2 karta da ayrı ayrı yükleyip bağlantıları yaptıktan sonra bazen otomatik kod yüklendiği an bu anlattığım işlemleri yapıp TFT ekrana yazıyor. Kodları da debug ile değil CUBEIDE de RUN ile yüklüyorum ki enerji kesilip tekrar enerji geldiğinde içindeki kodu çalıştırsın. Fakat ben stm32 kartlarımın yani nucleo ların enerjilerini kesip tekrar enerji verince bekliyor. Hiçbir şekilde direkt çalışmıyor. Ne zaman ki birinci kartımın siyah reset tuşuna basayım o zaman iki kart ve tft haberleşmeye başlıyor ve verileri ekrana sorunsuz yazıyor. Yani kdoları ve bağlantıları kontrol ettim ve hiçbir sorun bulamadım. İki kart tarafında da birer receive var ama ınterrupt lı receive bunlar. Transmitler polling. debug yapıp cubeıde arayüzünden çalıştırıp durdurduğumda bazen çalışıyor bazen de uart ile alakalı timeout error tarzı bir yer açılıyor hal kütüphanelerinde. Transmitlerin sonundaki timeout u HAL_MAX_DELAY yapmama rağmen hala stabilize şekilde çalışmıyor. Bazen enerji kesip takınca direkt başlıyor bazen de başlamıyor ve sanki tetikleme gelsin diye bekliyor ama halbuki while içinde olduğu için ve kodları run ile yüklendiği için direkt çalışması lazım. Sıkıntıyı kontrol için birinci karttan İLK olarak gönderdiğim hex ve onun crc si olan transmit in önüne ne sonuna led koydum. Kodu çalıştırınca yine bazen sorunsuz çalışıyor ve led sürekli yanıp yanıp sönüyor. Fakat çalışmadığında da led sadece yanık bekliyor. Yani transmit kodu aktif etmiyor. Bunun sebei ne olabilir ? eğer sorun time out ise ne yapmam lazım ? Transmit kısmını da interrupt ile mi yapmalıyım ? Yardımcı olursanız çok sevinirim.

    SAYGILARIMLA,

    1. Doğukan bey merhaba,

      Önümüzdeki 8-10 gün torunum sürekli paçamdan çekiştirir durumda olacağından sorularınıza pek odaklanamayacağım, ama ilk anda şunları söyleyebilirim.

      Kesme işlemleri barındıran kodları IDE nin debug modunda izleyip analiz etmek sağliklı bir yöntem değil. Bu nedenle programın akışını belirli noktalarda bir LED yakıp söndürerek izlemek daha iyi. Bunu da zaten yaptığınızı görüyorum.
      Kodunuzu işlemcilere yükledikten sonra PC ye bağlı durumda iken kendiliğinden start almayabilir, debug modunda iken bunu manuel olarak yaptığınızı biliyorsunuz. O nedenle reset tuşuna basarak başlatmanın sıkıntı yaratan bir yönü yok. Reset butonu ile güzel çalışan bir kod zaten büyük ölçüde başarılı olmuş demektir.
      Doğrusunu isterseniz ben her zaman debug modunda çalıştığım için sistemin run modunda nasıl davrandığına hiç bakmadım. Zaten PC den ayırdığımda normal çalışmasını sürdürüyorlar.
      Transmit fonksiyonuna girip bir daha çıkamıyorsa arada gelen bir kesme çevrimine girip orada kalıyordur, time out da çalışmıyordur. Systick kesme önceliği diğer kesmelerden yüksek olmalı ki HAL ın timeout sayaçları diğer kesmelerden etkilenmeden çalışsın. O nedenle receive kesmesini ve varsa başka peripheral kesmelerinin önceliklerini “0” yerine “1” yada daha yüksek olacak şekilde (yani daha düşük öncelikli) sıralamanız gerekir.

      Şimdilik bu kadar, fırsat bulup kafamı toprladıkça aklıma gelen birşey olursa yazarım.

      Selamlarımla,

      1. Hocam cevap verdiğiniz için teşekkür ederim. Evet systick kesme önceliği diğer kesmelerden yüksek olmalı ve ben bunu değiştirmemiştim. Yani uart kesmeleri düşük öncelikli yapmamıştım. Onu değiştirdim ve kodları tekrar düzenledim. Bu seferde de aynı problem oluyor. Yani bazen sorunsuz çalışıyor bazen de çalışmıyor ve benim resete basmamı bekliyor. Ama şunu farkettim nucleo kartlarını aynı anda veya çok kısa süreyle art arda(1 saniye içinde) taktığımda kartların direkt çalıştığını gördüm. Yani proje sorunsuz çalışıyor böyle yaptığımda. Üst üste 25-30 kez aynı anda veya 1 saniye arayla kartlare enerji verdim ve sorunsuz çalışıyor kodlarım. Fakat bir karta enerji verip birkaç saniye sonra diğer karta enerji verdiğimde bazen çalışma bazen çalışmama sorununu hala yaşıyorum. bu bir sorun mu onu da bilmiyorum ama ben kod olarak ve konfirüsyon ayarları olarak yapmam gereken her şeyi yaptığımı düşünüyorum.

    2. Doğukan bey
      sorunun nedenini bilmiyorum ama buna benzer bir sorunu stm32f103c8t6 da yaşadım. Sistem, stlink ve RUN komutu ile çalışırken stlink ile bilgisayara bağlı değilken çalışmamıştı. Ben de hex dosyasını STM32CubeProgrammer ile yükledim, sonra böyle bir sorunla karşılaşmadım. Eğer kodunuzda bir sorun yoksa isterseniz bir de STM32CubeProgrammer ile yüklemeyi deneyin.

      1. Bülent Bey,Doğukan Bey,
        Sistemin ST Link bağlı değil iken start alamaması sorununu ben de yaşadım ama bunun kod yüklemesinin run ya da debug modunda iken yapılması ile ilgili olmadığını düşünüyorum. Benim karşılaştığım durumlarda da mikrodenetleyici bir başka cihaza daha bağlı oluyordu, sanırım iki sistem arasında paylaşılan sinyallerin zamanlamasından kaynaklanan bir sorun oluyordu. Doğukan Bey’in kurulumunda da iki Nucleo Board var, enerji verildiğinde birinin diğerinden önce başlıyor olması buna neden olabilir. Programın açılış esnasında UART’dan sadece bir parçası gelen kodları kotaracak şekilde geliştirilmesi önemli. CRC kontrolundan sonra başarısız olan, bir bölümü eksik gelen mesajlar olması durumunda takılıp kalıyor olması olasılığı var. Doğukan bey’in kodlarını bilmediğimden, CRC kontrol sonucu başarısız olduğunda ne yaptığını, bu kontrolu yaparken arada gelen yeni bir mesajın eskisinin üzerine yazılıp yazılmadığına da bakmak gerekiyor.

        MAC OS ile çalıştığımdan STM32CubeProgrammer’i çalıştıramadım, ihtiyacım da olmadı aslında.

        Selamlarımla,

      2. Merhaba Bülent Bey,

        Evet söylediğiniz şey sonradan benim de aklıma geldi ve denedim. Fakat herhangi bir çözümü olmadı. Yani enerji verince bazen çalışma bazen çalışmama sorunu çözülmedi.

    3. Doğukan Bey,

      – alış tarafında eksik gelen, örneğin ilk byte’ı gelmeyen bir mesaj olduğunda sisteminiz nasıl davranıyor? başa alıp yeni mesaj mı bekliyor? karşı tarafa alışın hatalı olduğunu bildirip tekrar göndermesini istiyor mu?

      – “1 hex byte + CRC” mesajını gönderen taraf tekrar tekrar sürekli olarak mı gönderiyor? Karşı tarafın mesajı konytrol edip yanıtlamasını mı bekliyor?

      – gönderen taraf karşıdan yanıt gelmezse ne yapıyor? beklemeye devam mı ediyor?

      – alış tarafında (sırası ile her iki cihazınızın da alış tarafı olduğunu dikkate alarak) CRC kontrolu yaparken karşıdan yeni mesajlar gelmesi olasılığı var mı? Böyle bir durumda gelen yeni mesajı nereye nasıl kaydediyorsunuz?

      – sözünü ettiğiniz “reset düğmesine basınca” çalışan Nucleo hep aynısı mı, ikisini de mi resetlemeniz gerekiyor?

      Selamlarımla,

      1. Merhaba Selçuk hocam ,
        İlk byte gelmezse eğer başa alıp yeni mesaj bekliyor.

        Karşı tarafa alış hatalı tekrar gönder gibi bir fonksiyon belirlemedim. Belirlemeli miyim ?

        “1 hex byte + CRC” karşı tarafa gidiyor. Karşı taraf da diyor ki gelen verinin ilk byte i şu ise ekrana yazacak yazıyı gönder diyor. Yani şöyle düşünebiliriz. İlk nucleo 0x0C ile bunun CRC sini karşıya yani ikinci nucleoya gönderiyor paket olarak dizi halinde. Karşı taraf if(gelendata[0] == 0X0C) diyip sonra yapması gereken işlemleri yapıyor. Yanıt bekliyor çünkü ardından başka bir hex ve onun crc sini gönderiyorum. İlk dizi gitmeden ikinci üçüncü gitmiyor. E doğal olarak onlardan yanıt gelmeden de sonrakine geçmiyor. Tüm kodlar while içinde ama GİDEN birinci ikinci üçüncü dördüncü veriler birbirlerine koşul ile bağlı. İki taraf da birbirleriyle sorunsuz haberleştiği an iki nucleonun kodları da while içinde sonsuza kadar dönüyor. İşte o zaman sürekli gönderme alma gönderme alma yapmış oluyor. Bir de şunu ekleyeyim. Birinci nucleo birinci veriyi karşı tarafa gönderdikten sonra ve karşı taraf da gelen veriyi alıp cevap verdikten sonra 50 milisaniye bekleme süresi oluyor. Daha sonra ikinci veri gönderiliyor.

        Gönderen taraf yanıt gelmezse bekliyor evet.

        Crc kontrolü yaparken yeni veri gelme olasılığını düşük görüyorum hocam çünkü her iki nucleo için yazdığım kodda da if yani koşul ile süreç işliyor. Birinci veri karşıya gitmeden , karşı veriyi alıp cevap olan veriyi göndermeden ikinci ve sonraki verilere geçmiyor.

        Her iki nucleonun reset tuşuna basınca değil de bazen birinci nucleo bazen ikinci nucleoya basınca çalışıyor. Yani çalışmadığı zaman bazen birinci nucleo nun reset tuşuna bazen de ikincisine basıyorum ve direkt çalışıyor. Çalışınca da iki kart arasında sorunsuz iletişim başlıyor ve takılmadan devam ediyor ta ki enerji kesilene kadar.

        Saygılarımla,

  6. Hocam yorumumu neden sildiniz ? Sizden yardım isteyen ve soru soran diğer insanlar gibi ben de yardım istemiştim oysaki…

    1. Doğukan Bey merhaba,

      Hiç siler miyim yorumunuzu, sadece şimdi görüp onayladım. Sanırım ben onaylayana kadar sitede yayınlanmadığı için göremeyip silindi sandınız. Epeyi uzun bir yorummuş. Okuyup size dönüş yapacağım.

      Serlamlarımla,

      1. Merhaba Hocam,

        Kusura bakmayın mesajlarımı yayınlamadan sildiniz ve cevap vermediniz sandım ve birkaç gün de cevap gelmeyince siteye girmemiştim. Şimdi gördüm cevaplarınızı ve geri dönüş yaptım.

        Saygılarımla,

Comments are closed.