https://www.picproje.org/index.php/topic,35721.0.html (https://www.picproje.org/index.php/topic,35721.0.html) başlığında STM32F407 çipi ve bu çiple yapılmış deneme kartı konusunun ders anlatımları başladı ve zaman içinde dersler ilerleyecek.
Bu başlıkta ise bu konulardaki sorularınız ve cevapları tartışılacak.
Buradan bir kez daha hatirlatayim. Hard deyince bu dokumani (http://www.st.com/internet/mcu/common_images/pdf_icon.gif) (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/DM00037051.pdf). (DocID 022152 Rev1), Rehber deyince de bu dokumani (http://www.st.com/internet/mcu/common_images/pdf_icon.gif) (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/DM00031020.pdf) (Doc ID 018909 Rev1) anlayacagiz.
Hard'in 16.sayfasini, Rehberin de 85. sayfasini print edin. Onumuzdeki gunlerde bu iki sayfa uzerinde biraz konusacagiz.
Zamaniniz oldukca bu iki sayfaya bol bol bakin.
Hard 16 da, AHB, AHB1, AHB2, APB1, APB2 olarak adlandirilmis Buslar (iletim yollari) nerelere gidiyor, ARM islemci nerede, Timer nerede vs vs goz atin iste.
Rehber 85 de 48Mhz Usb clock, 168Mhz CPU clock, AHB clock, APB clock vs yazan yerlere biraz goz atin.
AHB ve APB dokumanlarda sikca karsilasilacak terimler.
Bir de Hard 39. sayfa elinizin altinda kagit baski olarak dursun.
(Bu dokumanlari bastan sona print etmenizi onermem.)
Şimdi de bugüne kadar işlemcilerle uğraşmış fakat hiç ARM çiple uğraşmamış arkadaşların https://www.picproje.org/index.php/topic,35721.msg255347.html#msg255347 (https://www.picproje.org/index.php/topic,35721.msg255347.html#msg255347) adresindeki ARM işlemcimiz resetlendiğinde neler olur? başlığını okumasını ve burada anlatılan olayları anlayıp anlamadıklarını söylemelerini ve yazım şeklimi eleştirmelerini bekliyorum.
İşin başındayken ayağımı denk almam açısından bana muhakkak bir kaç kişi fikrini yazsın.
https://www.picproje.org/index.php/topic,35813.0.html (https://www.picproje.org/index.php/topic,35813.0.html) adresindeki açıklamalara da paralel olarak muhakkak bakın.
Hocam ilk eşeltrişi ameliyattan önce benden olsun..gecenin bu saatinde bunlarla meşgul olmanız mutluluk verici.Ama sanki daha basitten alınabilir diye düşünüyorum.Tercih sizin....Birde "boot" yükleme anlamına mı geliyor?
Hocam benim için sorun yok, ancak okulda intel 8080 mikroişlemci dersi aldım daha geçen yıl o nedenle Stack pointer ve boot gibi bazı terimlere oradan aşinalığım var. Derste 0 dan sistem dizaynı yapmayı gördük ama sadece teoride tabi.
Ayrıca terimler bölümüne Stack Pointer, Program Counter terimlerinide eklerseniz ilk defa duyan arkadaşlar için iyi olacaktır. Teşekkürler.
Alıntı yapılan: eistain_54 - 18 Ekim 2011, 02:18:32
Hocam ilk eleştriyi ameliyattan önce benden olsun..gecenin bu saatinde bunlarla meşgul olmanız mutluluk verici.Ama sanki daha basitten alınabilir diye düşünüyorum.Tercih sizin....Birde "boot" yükleme anlamına mı geliyor?
Daha da basitleştirip anlatırım ama o zaman bu kursu sonuçlandırmamız çok uzun zaman alır.
Mesela neresini anlamadın?
Boot terimi ile ilgili olarak https://www.picproje.org/index.php/topic,35813.0.html (https://www.picproje.org/index.php/topic,35813.0.html) deki açıklama yeterli olmadımı?
Alıntı yapılan: mozkan87 - 18 Ekim 2011, 02:39:58
Hocam benim için sorun yok, ancak okulda intel 8080 mikroişlemci dersi aldım daha geçen yıl o nedenle Stack pointer ve boot gibi bazı terimlere oradan aşinalığım var. Derste 0 dan sistem dizaynı yapmayı gördük ama sadece teoride tabi.
Ayrıca terimler bölümüne Stack Pointer, Program Counter terimlerinide eklerseniz ilk defa duyan arkadaşlar için iyi olacaktır. Teşekkürler.
Stack Pointer ve Program Counter terimlerini o sayfaya eklerim eklemesine de;
Bu terimleri daha önce mikroişlemci ile proje yapmış herkesin zaten biliyor olması lazım.
Stack Pointer;yığın işaretçisi gibi bişeydi galiba.Program Counter ise program sayıcı diye hatırlıyorum.Programın değerini bir arttıran şey değilmiydi.
Benzetimler yaparak şamata yapacağım.
PC yani Program Counter
Bir ışınlama odasına girip klavyeden PC=Ankara yazarsanız kendinizi Ankara'da bulursunuz.
PC=Amerika yazarsanız kendinizi Amerika'da bulursunuz.
İşlemcide aynen böyle bir register var. Bu registere 0x80001234 yüklenirse, işlemci kendini bir anda Flashın 0x80001234 adresindeki kodu işletirken bulur.
Goto Label1 yada jmp Label1 gibi komutların yaptığı, Label1 adresinin sayısal değerini PC registerine yazmaktan ibarettir.
Stack Pointer
Bir labirente girdiniz ve kayboldunuz. Labirent duvarlarında sokak numarası gibi numaralar var.
Bir türlü labirentten çıkamıyorsunuz ve en sonunda stratejı geliştirmek zorunda kaldınız ve bir kagıt parçasına geçtiğiniz sokakların numalarını alt alta yazmaya başladınız.
Kağıda yazdığınız numaralar, aynı yerlerden tekrar tekrar geçmenizi engelleyecek ip uçları olacaktır.
Burada kullandığımız kağıt parçacığına stack memory diyebiliriz.
Kağıtta en son yazdığınız rakamın bulunduğu satır numarası sizin stack pointerinizdir. Bunu bir eksiltirseniz yani kağıttaki bir üst satıra çıkarsanız bir geride hangi sokak var bilgisine erişirsiniz.
Güzel bir örnek oldumu bilmiyorum ama fikir vermiş ve konuyu hatırlamışsınızdır.
Mikroişlemci de aynen yukarıdaki sokak örneğinde olduğu gibi bir fonksiyondan bir diğer fonksiyona giderken nasıl geri döneceğini aynı şekilde belirler.
Bunun için bilmediği bir sokağa girmeden önce bulunduğu sokak numarasını (PC yani program Counter değerini) Stack memorye yazar.
Daha sonra Stack memoryden nereye geri gideceğini kolayca öğrenir. Bunun için Stack Memoryde Stack Pointer de saklı adresdeki bilgiyi okuması yeterlidir.
Arkadaşlar bu temel konuları bilmeniz çok önemli. Bilmediğiniz şeyler olursa burada şamata yapın ve öğrenin yoksa ARMın üstesinden gelemem.
Stack pointerin ilk değer alması önemli. Bu Arm işlemcilerde reset aşamasında otomatiğe bağlanmış ve donanımsal olarak oluyor. Fakat daha sonra istersek yazılımsal olarak değiştirebiliyoruz.
Neden böyle: Bu ARM mimarisinin bir özelliği. Şu anda tam hatırlamıyorum ama eğer reset ardından Stack pointer donanımsal olarak sıfır değeri alıyorsa yani (Flash kodlarınızın ilk 4 byte'ı sıfırsa) CPU bir şeyi anlıyordu ama neyi? Bootload işlemini otomatik bir başka kaynağa yönlendiriyordu galiba.
Hocam deminden beri rehberde memory map bölümünü okuyorum ama anlamadığım kısımlar var.Rehberde 49-50-51-52 . sayfalarda yazanları kısaca anlatabilme şansınız var mı?Bir de daha önceden başıma şöyle bi hadise gelmişti.Stellariste de lpc1768'de de program fazla yer kapladığı için start-up dosyasından stack ve heap boyutlarını artırmıştım.Şimdi burada stack heap boyutunu artırdığımızda ram'den mi yer tahsis etmiş oluyoruz yoksa flash memoryden mi?Bir de 49. sayfada memory organization başlığı altında 4gb lık adress space diye adlandırdığı kısım peripharellara ait registerların saklandığı yer mi oluyo?
Sırayla gitmemiz lazım. Bahsettiğiniz konuya cok yakında değineceğiım. Kısaca bazı sorularınıza değineyim.
ARM 32 bitlik bir işlemci. Adres Bus'ı da 32 Bit.
Bu da 2^32 yani 4GB demek.
Flash + Ram + Cevrebirimleri tüm adresleri en fazla 4GB içinde olabilir.
Stack ve Heap, Ram dışına taşamaz.
Kısa bir soru, konuyu baştan sona incelemeye üşenen tembelin ve ARM cahilinin sorusu,
Elimde şu kart var,
http://www.futurlec.com/STM32_Development_Board.shtml
Sizin kartınız ile yapılacak çalışmalara bu kart ile katılınabilinir mi?
Kursun Keil ve C kısmından yararlanabilirsiniz.
Bizim kartla ilgili olarak felsefeyi kaparsanız kendi kartınızın çipinin dokumanlarını da takip ederseniz olabilir. Fakat kart sahibi olursanız işiniz daha kolay olur.
hocam baslik ne oldu silindimi dekontu gönderecem maili bilmiyorum basligida bulamiyorum dekontu gönderecegim arkadasin mailini yazabilirmisiniz rica etsem tesekkürler
Bilmiyorum. Ben de bugun yatiracaktim eger silindi ise bana da lazim olacak.
https://www.picproje.org/index.php/topic,35740.0.html
Alıntı yapılan: teknikelektronikci - 18 Ekim 2011, 10:15:15
hocam baslik ne oldu silindimi dekontu gönderecem maili bilmiyorum basligida bulamiyorum dekontu gönderecegim arkadasin mailini yazabilirmisiniz rica etsem tesekkürler
Alıntı yapılan: bunalmis - 18 Ekim 2011, 02:42:51
Daha da basitleştirip anlatırım ama o zaman bu kursu sonuçlandırmamız çok uzun zaman alır.
Mesela neresini anlamadın?
Boot terimi ile ilgili olarak https://www.picproje.org/index.php/topic,35813.0.html (https://www.picproje.org/index.php/topic,35813.0.html) deki açıklama yeterli olmadımı?
Hocam gece bir kaç kez daha üzerinden geçince sorun kalmadı olayı ucundan ucundan kavrıyorum.Daha evvel mikroişlemci ile değilde mikrodenetleyiciyle çalıştım.bazı şeyleri ordan hatırlıyorum.birde o şema varya hani şu soruları sayıciları bekçi köpek merkezi işlem birini falan blok dıyağram idi galiba onu kısaca açıklayabilecek biri çıkarmı acaba.
Alıntı yapılan: bunalmis - 18 Ekim 2011, 02:05:06
İşin başındayken ayağımı denk almam açısından bana muhakkak bir kaç kişi fikrini yazsın.
İşin incik cincik detaylarına kadar girmeniz ve detay istemeyenler için en altta "Bunları anlamadıysanız şunları bilin yeter" tarzındaki anlatım güzel olmuş. Böylece derslerden herkes yararlanabilir. Labirent,ışınlanma şeklinde benzetimler de anlamayı müthiş seviyede kolaylaştırıyor, ayrıca işi eğlenceli kılıyor. Bence şu an oluşturduğunuz tarz gayet iyi hocam.
Alıntı yapılan: bunalmis - 18 Ekim 2011, 10:23:19
Bilmiyorum. Ben de bugun yatiracaktim eger silindi ise bana da lazim olacak.
TÜRKİYE İŞ BANKASI
Sakarya Merkez Şubesi
Erol YILMAZ
2000-1949145
IBAN : TR340006400000120001949145
Dekont Buraya :
nrkaan@gmail.com
Alıntı YapSırayla gitmemiz lazım. Bahsettiğiniz konuya cok yakında değineceğiım. Kısaca bazı sorularınıza değineyim.
ARM 32 bitlik bir işlemci. Adres Bus'ı da 32 Bit.
Bu da 2^32 yani 4GB demek.
Flash + Ram + Cevrebirimleri tüm adresleri en fazla 4GB içinde olabilir.
Stack ve Heap, Ram dışına taşamaz
Hocam eğer soruları erken soruyosam kusura bakmayın isterseniz sormayabilirim.Bir iki sorum daha olacak aklıma takıldı.Şimdi hocam mcu nun çevrebirimlerine ait registerlar mesela bizim mcu için konuşursak o bahsedilen 1 mb lık flash memory de mi yer kaplıyo.Yoksa registerlar için ayrı bir romu mu var?Yani bizim yazdığımız programın boyutu 1mb olabilir mi?O flash memory nin tamamını biz kullanabilir miyiz?
Bunalmıs hocam
dersleri anlatım tarzınız bence güzel. yani boyle bazı kısımları hikayeleştırerek anlatıyor olusunuz, terimler içinde kaybolmamızı engelleyecek ve konuyu kavramamızı kolaylaştıracaktır.
Flash memory 1Mbyte. Tamamı senin. Tamamına kendi programını yükleyebilirsin. 1Mbyte alanın dışında Ram alanı var + Çevre birimlerinin registerleri var.
4Gbyte alanda 1 Mbyte alan nedir ki?
Eğer 1Mbyte Flash alanı yetmiyorsa external Rom bağlayabilirsin. Çünkü STM32F407 external bus'a sahip.
Yakında Memory MAP için güzel bir tablo vereceğim.
Hocam söylediğiniz hard ın 16.sayfasındaki mcu nun blok diyagramında ötnek verecek olursak timer 2 apb1 e bağlı ve apb1 in de hızı 42 mhz şimdi biz işlemcimizin hızı 168 mhz olmasına rağmen 1/42000000 sn den daha düşük bir hızda timer2 ile kesme oluşturamıyoruz di mi?
Alıntı yapılan: OG - 18 Ekim 2011, 04:51:18
Kısa bir soru, konuyu baştan sona incelemeye üşenen tembelin ve ARM cahilinin sorusu,
Elimde şu kart var,
http://www.futurlec.com/STM32_Development_Board.shtml
Sizin kartınız ile yapılacak çalışmalara bu kart ile katılınabilinir mi?
maddi durumu iyi olmayan arkadaşlara ücretsiz verilmesinden bahsediliyordu
talepte bulunursan yardımcı olurlar
kursu daha iyi takip edersin
Maddi durum meselesi değil de, yeni bir çalışma, yeni bir dil falan bu yoğunlukta başlangıçta katılmayı gözüm kesmedi, sonra bu kart elime geçti 5-6 ay önce almıştım, atmışım bir kenara. Bir gayret edeyim mi diye danıştım.
Alıntı yapılan: OG - 18 Ekim 2011, 17:51:56
Maddi durum meselesi değil de, yeni bir çalışma, yeni bir dil falan bu yoğunlukta başlangıçta katılmayı gözüm kesmedi, sonra bu kart elime geçti 5-6 ay önce almıştım, atmışım bir kenara. Bir gayret edeyim mi diye danıştım.
ST işlemcilerini kullananların %95'i ST kütüphanelerini kullanır, bu kütüphanelerde mümkün olduğunca aynı isimle yazılır dolayısıyla çok az bir farklılık olacaktır. Rahatlıkla boardunu kullanırsın.
STM32F407 için DSP vs.. özelliklerden bahsedilmişti.
Peki Keil matematik kütüphanesi nasıl ? Hazır fonksiyonlar içeriyor mu? Yoksa tamamen kullanıcıya mı bırakılmış?
Asıl merak ettiğim şey şu complex sayılar için desteği var mı ? Örneğin bir fft hesabında çok lazım olacak.
not:Keil 'i kuramadım , aktif olarak kullananlar vardır muhtemelen.
dsp kütüphanesi ile doğrudan fast fourier dönüşümü FFT yapabilirsiniz ilgili fimware leri st.com den inceleyebilirsiniz.
bunalmış hocam
kendimi biraz aptal hissediyorum bunu sorarken ama anlattıgınız bişeyi anlamadan bi sonraki satıra geçmemek için herşeyi yaparım bu işi oğrenicez dedik
öğrenmek içinde takıldıgımız yerleri anlamamız lazım
hard 39 da boot0 ve boot1 i bulun demişsiniz
BOOT-0 94.pin tamam
BOOT-1 pinini 39 sayfada bulamadım:( LQFP100 doğru değilmi?
Evet boot1 olarak geçmiyor ama arattığımız zaman PB2 olduğunu yani 37. pin olduğunu görüyoruz.
Not:44. sayfada
çok teşekkür ederim bilgi için
sormak istedigim
aslında anladıgımı sandığım emin olmak istedigim 4 şey var
1. 0x0000.0000 2^32 =4gb alanımız var yani programla ilgili herşeyimiz bu değerlerin içinde saklı. ve bunlara istedigimiz zaman ulaşabiliyoruz doğrumu?
2. StackPoint registeri bizim labirentte dolaşırken son girdigimiz sokakları aklında tutuyor. peki bir sonraki sokaga girdiğimizde bu stack point değişiyormu yoksa stackpoint1 stackpoint2 diye kendimi kaydediyor
yani her sokağa girdigimizde stackpointe bakıp bunu biyere not etmemizmi gerekiyor?
3. PC=program counter = programın nerede çalıştığını gösteriyor istediğimiz degeri oraya yazıp oraya ışınlanıyoruz ve çalışmaya devam ediyoruz..
peki porgram counter sadece değer girilen bi registermi yoksa şuan nerede oldugumuz bilgiside PC de saklanıyormu ve her yeni komuta yada fonksiyona geçtiğimizde bu değerde değişiyormu(aynı şekilde bu register da bir adetmi bulunmakta)
4.PC bizi ışınlıyor ve oraya gidiyoruz bu biraz ileri seviye bir soru olabilir ama.. bizim cortexM4 ümüz 2 işlemi aynı anda yapabiliyor diye hatırlıyorum
dual core gibi..
ozaman bu program counterin 1 tane olması yetersiz değilmidir?(eğer 1 tane ise)
Pic ile ilgili ccs c de program yazdım fakat hep örneklere bakarak(amatörce) bugüne kadar hiç debug yapıp registerlerin nasıl değiştiğini tecrübe edememiştim anlatımınız cok güzel hocam benim gibi bir amatör bile anlıyorsa sorun yoktur diye umuyorum dediğiniz gibi temelden girmek çok mantıklı
bu 4 soru dışındaki herşeyi anladım kafama takılanlar bunlardı
sadece bunalmış hocam değil bilen arkadaşlarımda bildiklerini paylaşırsa çok sevinirim böylece bunalmış hocamda sizin yanlış bildiginiz biyeri görürse sizi uyarabilir.
Teşekkürler..
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Alıntı YapStack Pointer ve Program Counter terimlerini o sayfaya eklerim eklemesine de;
Bu terimleri daha önce mikroişlemci ile proje yapmış herkesin zaten biliyor olması lazım.
bunalmış hocam ccs c sağolsun inanın hiç bu registerlarla işimiz olmamıştı keşke zamanında ccs c den hitec e geçiş yapsaydım
ccs boyle şeylerle kafanızı yormanızı hiç istemiyor buyüzden satıyor.
herşeyi sonuna kadar anlatmanızı istemek gibi bi hakkımız yok
internetten türkçe rahatlıkla bulabilecegimiz terimlerin açıklamalarını yazmanıza gerek yok(tabi siz bilirsiniz). böylece ogrenciler(başta ben) araştırarak öğrenme kabiliyetlerini geliştirirler
ama eminimki kimselerin bilmediği şeylerle karşılaşacağız siz kafanızı(ve değerli vaktinizi) bunları anlatmaya verirseniz daha verimli olur diye düşünüyorum
saygılar
1. sorunun cevabı evet. İşlemciler için herşey adreslerden ibarettir. Yani bütün giriş çıkış birimleri ve diğer birimlerin hepsinin bir adresi vardır. Bu adresin belirli bir bölümü FLASH, belirli bir bölümü RAM ve diğer bölümlerden ibarettir. Bizim işlemcimiz 0x00000000 2^32=4 gb adresleme yapabilmektedir. Bu adreslerden her biri giriş çıkış olabilir, yada FLASH olabilir, RAM olabilir... Bizim işlemcimiz için 0x08000000 adresinden itibaren FLASH hafıza başlamaktadır.
3. soru Program Counter(PC) aslında adrestir ancak değeri her clock pulsunda 1 artar. Bu da bir sonraki çalıştırılacak olan komutun bulunduğu adrese denk gelir.(her clock pulsunda olmayabilir, 2 veya 4 te olabilir işlemciye göre değişmekte.)
2. soru Stack Pointer, program dallandıkça programın kaldığı yeri not eden bir yapıdır. Yani program yeni bir yere giderken kaldığı adresi Stack Pointer'in içine kaydeder. Aslında burada kaydettiği Program Counter'ın değeridir. Mesala program bir yere dallandı ve PC'nin değerini SP'ye kaydetti, bu esnada işlemci SP'nin adresinide 1 arttırır. Yani artık ikinci boş bir SP'miz oldu, tekrar programın dallanması gerekirse PC'nin değeri ikinci SP'ye kaydedilir. Geri dönerkende ilk önce ikinci SP'den PC değerini alır işlemi tamamlar. Tamaladıktan sonra birinci SP den değeri alır ve normal işleyişine devam eder. Biraz karışık oldu ama anlamadığınız yerleri sorabilirsiniz.
4. soru aslında en basit soru bu hiç bir işlemci çift çekirdek olmadığı sürece aynı anda iki işlem yapamaz. Önce birini yapar diğerine geçer. Yada RTOS'ta olduğu gibi biraz birinden biraz birinden yapar.
Not: Cevapları düzenledikçe dilim döndükçe yazmaya çalışacağım.
Taneryilmaz ve Dombilik ders basliginda ayni sorulari sormuslar. Evet yazmayi unutmusum 44. sayfada boot1 pini yaziyor.
Alıntı Yaphocam hard 38-39-40-41 sayfalarına bir göz attım ama boot1 pinine rastlayamadım yanlışmı bakıyorum aceba? GPIO pinlerinde herhangi biri BOOT1 yerine kullanılabiliyormuş.Sadece BOOT0 var pin olarak.
Boot1 pini resette bir kereligine okunan bir pin. Bu aslinda portun I/O pini. SystemInit rutininde bu pini konfiure edip sahiplenebilirsiniz. Bizim cipimizde tek core var. Dolayisi ile ayni zamanda sadece tek komut isleyebilir. (Isin icine FPU komutlari girerse durum ne olur bilmiyorum)
arkadaşlarla eş zamanlı sormuşuz heralde tamamdır hocam teşekkürler
ben ders başlığını kilitli sanıyordum oyüzden orayı nadiren takip ediyordum artık daha dikkatli olacagım
rtos ile core duo yu karıştırmışım şimdi rtos nedir inceledim öğrendim teşekkürler..
mözkan87 hocam çok teşekkür ederim şu bolümde bir sorum olucaktı
Alıntı YapMesala program bir yere dallandı ve PC'nin değerini SP'ye kaydetti,
sadece program dallandığı zamanmı SP nin değerini bir arttırıp kaydediyor
zaten mantıklısıda bu sanırım zaten alt alta devam ettiğini bildigimiz birşeyi (eski PC nin bir fazlasını oldugunu bildigimiz halde neden hafızada yer kaplatalım değilmi?)
doğrumu anlamışım mantığını
sanırım öyle olmasaydı, yazdığımız program hafızası kadar bir hafızada neyin nerden sonra nereye gittiğini kaydetmek için yer kaplardı
anlatabildimmi acaba
Alıntı yapılan: bunalmis - 19 Ekim 2011, 00:05:42
Taneryilmaz ve Dombilik ders basliginda ayni sorulari sormuslar. Evet yazmayi unutmusum 44. sayfada boot1 pini yaziyor. Boot1 pini resette bir kereligine okunan bir pin. Bu aslinda portun I/O pini. SystemInit rutininde bu pini konfiure edip sahiplenebilirsiniz. Bizim cipimizde tek core var. Dolayisi ile ayni zamanda sadece tek komut isleyebilir. (Isin icine FPU komutlari girerse durum ne olur bilmiyorum)
Sayın @bunalmış hocam bilğileriniz için teşekkür ederim. şimdi biz bu boot1 pinini yani PB2 yi SystemInit ile giriş çıkışları belirlemeden önce mi kullanabiliyoruz yoksa SystemInit ile tanımlayıncamı kullanabiliyoruz ?
"Hiç bir işlemci çift çekirdek olmadığı sürece aynı anda iki işlem yapamaz" demişsiniz.
FPGA lar paralel işlem yapabiliyor diye duymuştum. Onlar da mı çift çekirdek ?
FPGA 'ler farklı bir yapıya sahip adı üzerinde Field Programmable Gate Array (Alanda Programlanabilir Kapı Dizileri) Linki (http://tr.wikipedia.org/wiki/FPGA)okumanızı önreririm.
Alıntı yapılan: gambit1244 - 19 Ekim 2011, 00:13:06
arkadaşlarla eş zamanlı sormuşuz heralde tamamdır hocam teşekkürler
ben ders başlığını kilitli sanıyordum oyüzden orayı nadiren takip ediyordum artık daha dikkatli olacagım
rtos ile core duo yu karıştırmışım şimdi rtos nedir inceledim öğrendim teşekkürler..
mözkan87 hocam çok teşekkür ederim şu bolümde bir sorum olucaktı
sadece program dallandığı zamanmı SP nin değerini bir arttırıp kaydediyor
zaten mantıklısıda bu sanırım zaten alt alta devam ettiğini bildigimiz birşeyi (eski PC nin bir fazlasını oldugunu bildigimiz halde neden hafızada yer kaplatalım değilmi?)
doğrumu anlamışım mantığını
sanırım öyle olmasaydı, yazdığımız program hafızası kadar bir hafızada neyin nerden sonra nereye gittiğini kaydetmek için yer kaplardı
anlatabildimmi acaba
evet doğru anlamışsınız.
teşekkür ederim mozkan87
bu arada arkadaşlar PDF ler artık bizim herşeyimiz kabul etmemiz lazım..
ve hepsi ingilizce..
ingilizce bilen bilmeyen herkezin ihtiyacı olan bir ilacım var!!
lingoes sözlük!!
bikaç ayar yaptıktan sonra pdf üzerinde çift tıklayıp ctrl+V yaptığınız kelimenin ingilizcesi kücük bir kutu halinde ekrana geliyor..
bircok sozlük pdf te yetersiz.. bu program bu konuda cok iyi geldi bana..
kesinlikle tavsiye ediyorum..
tamamen ücretsiz bir yazılım babylon'dan eksiği yok..
Alıntı yapılan: taneryilmaz - 19 Ekim 2011, 00:18:11
...şimdi biz bu boot1 pinini yani PB2 yi SystemInit ile giriş çıkışları belirlemeden önce mi kullanabiliyoruz yoksa SystemInit ile tanımlayıncamı kullanabiliyoruz ?
Şu anda bunları konuşmaya gerek yok fakat madem sordunuz;
Boot1 pininin konumunu ARM donanımı bilmek istiyor. Reset anında bunu okuyor ve bir daha bu pine bakmıyor. Dolayısı ile biz SystemInit de Boot1 pinini (PB2) yi I/O ayarlayarak gerekiyorsa kullanabiliriz.
Tabiki bu pin resette konumu anlaşılabilsin diye L yada H'a en azından bir dirençle çekileceğinden bunun bizim amacımızla ters düşmemesi lazım. Eğer doğrudan jumper ile H yada L yapılır bir şema üzerinde çalışırsak bu pini daha sonra kendi amacımıza uygun kullanmamız mümkün olmaz.
Yani bu pinin kullanımında dikkatli olmak gerekiyor.
Hocam şöyle bi deneme yaptım bendeki lpc1768 kitine ledleri 05 sn de bir söndüren bir program yazdım ve normal debug yaptım yani sümulatör değil sonrada adım adım sp nin değerini inceledim hiçbir değişiklik göremedim.hatta tam emin olmak için araya küçük bi toplama fonksiyonu ekledim.topla(x,y) gibi hani program başka bi fonksiyona dallandığında stack pointer ın artması gerektiğini düşündüğüm için. ama yine bi değişiklik olmadı.Hatta start up dosyasından stack hafızasını 0 a düşürdüm yine de program düzgün çalıştı.Daha sonra sd karta veri yazan bi program yazmıştım onu debeg edip denedim bu programda sp de program dallanırken artıp azalmalar izledim.Hatta programın düzgün çalışması için lpc1768 in start-up dosyasındaki stack hafızasının default değeri 0x200 byte ı 0x400 yapamam gerekti.Şimdi hocam programın boyutu çok küçük olduğunda ya da programda fazla dallanma olmadığında stack e ihtiyaç duyulmuyo mu?
Alıntı yapılan: yamak - 19 Ekim 2011, 02:49:20
Hocam şöyle bi deneme yaptım bendeki lpc1768 kitine ledleri 05 sn de bir söndüren bir program yazdım ve normal debug yaptım yani sümulatör değil sonrada adım adım sp nin değerini inceledim hiçbir değişiklik göremedim.hatta tam emin olmak için araya küçük bi toplama fonksiyonu ekledim.topla(x,y) gibi hani program başka bi fonksiyona dallandığında stack pointer ın artması gerektiğini düşündüğüm için. ama yine bi değişiklik olmadı.Hatta start up dosyasından stack hafızasını 0 a düşürdüm yine de program düzgün çalıştı.Daha sonra sd karta veri yazan bi program yazmıştım onu debeg edip denedim bu programda sp de program dallanırken artıp azalmalar izledim.Hatta programın düzgün çalışması için lpc1768 in start-up dosyasındaki stack hafızasının default değeri 0x200 byte ı 0x400 yapamam gerekti.Şimdi hocam programın boyutu çok küçük olduğunda ya da programda fazla dallanma olmadığında stack e ihtiyaç duyulmuyo mu?
Bu olay biraz da derleyici ile alakalı. Compiler ne derse o oluyor genelde. Compiler'ın optimizasyon seviyesi gibi değişkenlerinede bağlı. Ama assembly ile yazıyorsanız iki satırlık program için bile SP'de değişiklik yapabilirsiniz.
Alıntı yapılan: yamak - 19 Ekim 2011, 02:49:20
Hocam şöyle bi deneme yaptım bendeki lpc1768 kitine ledleri 05 sn de bir söndüren bir program yazdım ve normal debug yaptım yani sümulatör değil sonrada adım adım sp nin değerini inceledim hiçbir değişiklik göremedim.hatta tam emin olmak için araya küçük bi toplama fonksiyonu ekledim.topla(x,y) gibi hani program başka bi fonksiyona dallandığında stack pointer ın artması gerektiğini düşündüğüm için. ama yine bi değişiklik olmadı.Hatta start up dosyasından stack hafızasını 0 a düşürdüm yine de program düzgün çalıştı.Daha sonra sd karta veri yazan bi program yazmıştım onu debeg edip denedim bu programda sp de program dallanırken artıp azalmalar izledim.Hatta programın düzgün çalışması için lpc1768 in start-up dosyasındaki stack hafızasının default değeri 0x200 byte ı 0x400 yapamam gerekti.Şimdi hocam programın boyutu çok küçük olduğunda ya da programda fazla dallanma olmadığında stack e ihtiyaç duyulmuyo mu?
SP işlemciye göre değişen boyuta sahiptir. bazı işlemciler aynı anda 8 adresi saklarken bazıları 32 adresi saklar. (bizim işlemcimizde bu rakamın kaç olduğunu bilmiyorum henüz)
şöyle düşünelim
program çalımaya başladı ve bir dallanma komutu ile karşılaştı. o anki adresi 1256. sokak olsun. SP 1. satıra 1256 yazıldı, dallanma komutu işledi
dallanılan adresten işlemeye devam etti ve bir dallanma komutu daha var. SP 2. satıra o anki adres yazıldı ve ikinci dallanma komutu işlendi. örnek 2008. sokak
şimdi SP.1 de 1256, SP.2 de 2008 yazıyor.
mevcut dallanma ile gittiğimiz yerdeki işlemler bitti, önceki adreste işlememiz gereken komutlar var hala (aslında önceki ve bir daha önceki).
SP.2 ye baktık ve gitmemiz gereken yerin 2008 olduğunu gördük ve bu adrese gidip işlemlere devam ettik. buradaki fonksiyon da bitti, SP.1 e baktık adres nedir diye.
adres 1256 okuduk ve ilk bıraktığımız adrese geri dönüp buradan program koşturmaya devam ettik ....
iç içe SP boyutu kadar dallanmayı sıkıntısız (otomatik) yapabiliriz. bunu aşan kısımlarda yazılımda bizim (programcının) hafızaları takip etmemiz gerekiyor.
diye biliyorum.
edit: yazını tam okumamışım. bunu takip etmenin en garanti yolu basic teki GOSUB komutu olduğunu düşünüyorum. yani normal fonksiyonlar ile değil de sanki senin dallanma komutu vermen gerek. yazdığın kod kısa olduğu için editör hex oluştururken dallandırmamış olabilir.
Alıntı yapılan: yamak - 19 Ekim 2011, 02:49:20
Hocam şöyle bi deneme yaptım bendeki lpc1768 kitine ledleri 05 sn de bir söndüren bir program yazdım ve normal debug yaptım yani sümulatör değil sonrada adım adım sp nin değerini inceledim hiçbir değişiklik göremedim.hatta tam emin olmak için araya küçük bi toplama fonksiyonu ekledim.topla(x,y) gibi hani program başka bi fonksiyona dallandığında stack pointer ın artması gerektiğini düşündüğüm için. ama yine bi değişiklik olmadı.Hatta start up dosyasından stack hafızasını 0 a düşürdüm yine de program düzgün çalıştı.Daha sonra sd karta veri yazan bi program yazmıştım onu debeg edip denedim bu programda sp de program dallanırken artıp azalmalar izledim.Hatta programın düzgün çalışması için lpc1768 in start-up dosyasındaki stack hafızasının default değeri 0x200 byte ı 0x400 yapamam gerekti.Şimdi hocam programın boyutu çok küçük olduğunda ya da programda fazla dallanma olmadığında stack e ihtiyaç duyulmuyo mu?
ARM işlemcilerde fonksiyon çağrılırken stack kullanımı diğer işlemcilerden bayağı bir farklı.
Fonksiyon çağrıldığında geri dönüş adresi stağa atılmaz. LR registerine atılır. Eğer Fonksiyon içinde fonksiyon çağrımı olacaksa LR değeri bizim inisiyatifimizle stağa atılır. Sen tek fonksiyon call ettiğin için Stack registerde değişim görmüyorsundur.
Alıntı YapARM işlemcilerde fonksiyon çağrılırken stack kullanımı diğer işlemcilerden bayağı bir farklı.
Fonksiyon çağrıldığında geri dönüş adresi stağa atılmaz. LR registerine atılır. Eğer Fonksiyon içinde fonksiyon çağrımı olacaksa LR değeri bizim inisiyatifimizle stağa atılır. Sen tek fonksiyon call ettiğin için Stack registerde değişim görmüyorsundur.
Hocam ben de tam LR register ı ne işe yarıyo diye soracaktım.Evet söylediğiniz gibi oluyo kısa programlardaki dallanmalarda Sadece LR register ında değişim oluyo.Ama uzun programlar da SP'de de değişim oluyo.Ama merak ettiğim şey neden böyle bişey yapılmaya ihtiyaç duyulmuş Sadece sp kullanılsa da olmuyo muydu?
Register erişimi memory erişiminden daha hızlıdır. Dönüş adresleri stak a atılsaydı call ve ret komutlarının ihtiyacı olan clock sayısı artacaktı.
Alıntı yapılan: yamak - 20 Ekim 2011, 15:26:42
Hocam ben de tam LR register ı ne işe yarıyo diye soracaktım.Evet söylediğiniz gibi oluyo kısa programlardaki dallanmalarda Sadece LR register ında değişim oluyo.Ama uzun programlar da SP'de de değişim oluyo.Ama merak ettiğim şey neden böyle bişey yapılmaya ihtiyaç duyulmuş Sadece sp kullanılsa da olmuyo muydu?
SP'de değişim programın uzun ya da kısa olmasına bağlı değildir. Hangi yazmaçların kulanıldığı ile alakalıdır. ARM mikroişlemcilerde programcılar r0-r3 yazmaçlarını dilediğince kullanabilirler. Sadece bu yazmaçları kullanarak oldukça uzun bir program yazabilirsin SP'de herhangi bir değişime gerek duymaksızın. Basit bir fonksiyunumuz olsun: int topla(int a,int b, int c, int d){ return a+b+c+d;} gibi. Bu fonksiyonun parametleri ATPCS'e (ARM-Thumb Procedure Call Standard) göre r0-r3 yazmaçlarında geçer. Derleyici sonucu r0 üzerinden döner ve diğer yazmaçları kullanmaz. Bu durumda SP'de herhangi bir değişikliğe gerek yoktur. Sen bu fonksiyonun parametre sayısını artırırsan diğer argümanlar için ilave yazmaçlar gerekecek; kullanılacak yazmaçların fonksiyon öncesindeki değerleri stacka kaydedilecektir. Bu yüzden programa girişte ve çıkışta SP güncellenecektir.
arkadaşlar kitten nerden baksanız 100 150 kişi sipariş verdi
bu arkadaşlar denemeleri yapmıyormu acaba
yoksa kitin gelmesinimi bekliyorlar
sanki 10 15 kişi ugraşıyormuş gibi geldi bana nedir durumlar
yada herkez problemsiz debug işlemlerini clock ayarlarını yaptı oyüzden yeni konularımı bekliyor anlamadım
yada ben sınıfın en inek öğrencisiyim heralde :-[
bunalmis hocam, çalışmalar için çok teşekkürler. Yoğun olduğum için forumu ancak akşamları yarım saat kadar bakabiliyorum. Doğal olarakta bazı şeyleri kaçırmaktan korkuyorum. Bu yazdıklarınızı bir ara pdf olarak toplarsanız çok güzel olur.
Birde ARM konusunda mutlaka okuyun dediğiniz kitaplar hangileridir? Ebook olması tercihimdir. İngilizce Türkçe farketmez.
Yeni işe başladığımdan bir yoğunluktur gidiyor. Fırsat bulunca ve kartlar gelince bende az çok elimden geldiğince foruma birşey eklemek isterim.
Alıntı yapılan: gambit1244 - 20 Ekim 2011, 17:58:27
arkadaşlar kitten nerden baksanız 100 150 kişi sipariş verdi
bu arkadaşlar denemeleri yapmıyormu acaba
yoksa kitin gelmesinimi bekliyorlar
sanki 10 15 kişi ugraşıyormuş gibi geldi bana nedir durumlar
yada herkez problemsiz debug işlemlerini clock ayarlarını yaptı oyüzden yeni konularımı bekliyor anlamadım
yada ben sınıfın en inek öğrencisiyim heralde :-[
Daha onceden 8051 ve keil kullandigimdan benim acimdan problem yok.
ben kitin gelmesini beklyiorumn
birde bende daha önce 8051 ile calistigim icin debug vs bir problem yok kit gelsin uygulamali hallederiz
benimde pc su koyverdi ilk kurdum bütün örnekleri uyguladım ertesi gün keil hata verdi ne yaptıysam çalışmıyor yazılanları mümkün olduğunca sessiz takip edip geri kalmamak için çalışıyorum bayram üstü yeni pc içinde bütçe yok pc beni bıraktı ben onu bırakamadım kitler gelmeden program yazmaya yetecek kadar hesaplı bir laptop almaya çalışacağım iyi bir ortam oluştu ne kadar öğrene bilirim zaman gösterecek ama ben anlayabildiğim kadarına kafa yoracağım gözüme batan bir konu var genel olarak analog elektroniimizde çok zayıf konular açıp bunlarıda gidermek lazım
birde bu armyi ve c yi öğrenenimiz çok olursa bilgi konusunda geri ödeme olarak hakim olduğumuz konularda kendi fonksiyon kütüphanelrimizi yazıp paylaşsak
mesela klein hocam pid konusunda kitap yazacak seviyede gibi geldi bana klein hocam gibi birçok konuda uzmanlaşış arkadaşlar var
çinden logic analyzer almıştım
fakat şmdi 2 tane logic analyzerim oldu
nasılmı?
keil sayesinde:D
bunalmış hocamın verdigi bilgilerle
daha onceden alıp çekmecede çürümeye terkettigim
cortex m3 kitimi debug ettim ve içine program attım
programı nasıl attım bilmiyorum f7 ye bastım direk gitti program :D
Hangi programı derleyipte yüklediniz merak ettim. Biraz açabilir misiniz?
cortexm3 için konuşuyorum kafanız karışmasın..
mözkan87 hocam şimdi program çalışıyor ledler yanıp sonuyor fakat
main e breakpoint koyunca çalıştır diyorum sonra f10 yada f11 ile satır satır yada fonksiyon fonksiyon atlatıyorum
fakat hiç ledler yanmıyor
ayrıca blinky projesinin maininden watch1 e ekledigim led_out, ledOn, ledVal ledBlink ve BTN_Pressed
değişkenleri hiç değişmiyor
ama her f11 e bastıgımda kitin stlink bölümündeki ışıklar yanıyor yani bağlantı var
run deyince aynı menüden program düzgün calısıyor..
mesela delayı değiştiriyorum yanıp sonme süreside degişiyor fakat degişkenleri izleyemedim :S
neden olur boyle bişey watch 1 aktif deil sanki boyle bişey bi ayar varmı
edit:blinky projesini yükledim led3 yanıp sonuyor
butona basarsam led4 yanıp sonüyor
bidaha basarsam 2 si yanıp sonuyor
Anlaşıldı. Bende program yazdınız yada buldunuz zanettim. Yanlış alarm ;D
hehe bismillah :D
çok temiz kalplisin hocam bigün oda olucak ama inan bana :DD
sorunu daralttım sanırım
neden hala bilmiyorum fakat
programı çalıştırıyorum stop yapıyorum.
led sönük.
ledOn değişkeninde 0x00000000 var
sonra programı calıstırıyorum
aniden led yanarken stop yapıyorum
stopa basınca en son deger (led yanık oldugu için)
ledOn 0x00000001 oldu.
demekki değişkenler değişiyor ama ben satır satır yapınca yine değişmiyor :S
Cipimizin ART modulunde prefetch ile ilgili BUG var. Bu BUG'in islemcinin performansini nasil etkileyecegi konusunda arastirma yapan varmi?
Asagidaki linkeleri de bir ziyaret edin.
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00039457.pdf (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00039457.pdf)
http://www.st.com/stonline/stappl/resourceSelector/app?page=resourceSelectorPage&doctype=st_software_rsrc&SubClassID=1521 (http://www.st.com/stonline/stappl/resourceSelector/app?page=resourceSelectorPage&doctype=st_software_rsrc&SubClassID=1521)
Ben böyle bir BUG olduğunu farketmemiştim. ERRATA (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/ERRATA_SHEET/DM00037591.pdf)'yı incelediğimde (Doc ID 022183 Rev 1) sayfa 8 den anladıklarım;
Bu durumda bizim chip için ART accelerator'ın bir anlamı kalmıyor galiba. Yani demek istediğim sıraya alma işlemi kullanılamaz olduğu için her okuma için chipin 6 clock cyle beklemesi gerekecek. Benim anladığım bu. Acaba doğru mu anladım? incelemelerim sürüyor. Teşekkürler
Dökümanlardan net bilgi bulamadım ama ART 'ın bu şekilde tam verimde çalıştığını düşünmüyorum. Yeni uyarlamada (revision) bu sınırlama düzeltilecek yazıyor.
Yazılımla bir pini 80 Mhz de toggle ettim. ART daki sorun kendini nasıl gösteriyor anlamadım.
Alıntı yapılan: gambit1244 - 20 Ekim 2011, 17:58:27
arkadaşlar kitten nerden baksanız 100 150 kişi sipariş verdi
bu arkadaşlar denemeleri yapmıyormu acaba
yoksa kitin gelmesinimi bekliyorlar
sanki 10 15 kişi ugraşıyormuş gibi geldi bana nedir durumlar
yada herkez problemsiz debug işlemlerini clock ayarlarını yaptı oyüzden yeni konularımı bekliyor anlamadım
yada ben sınıfın en inek öğrencisiyim heralde :-[
simule denemelerini yapmaya çalışıyorum, uygulama için kitin gelmesini bekliyorum bende, akşamları 1 saat kadar bakabiliyorum sabahları da malum çalışıyoruz, pek zamanımız da kalmıyor açıkçası, ama inatla öğrenmeyi istiyorum, allahım tamamına erdirir inşallah.
@bunalmış hocamızın yadıklarını sürekli okuyor ve anlamaya çalışıyorum, anlamadanda saçmasorular sormak istemiyorum. mikroişlemci hakkında yüzeysel bilgim var, arm ile başlamak bayaa kasıntılı bir süreç olacak.
Alıntı yapılan: sigmoid - 20 Ekim 2011, 18:49:43
bunalmis hocam, çalışmalar için çok teşekkürler. Yoğun olduğum için forumu ancak akşamları yarım saat kadar bakabiliyorum. Doğal olarakta bazı şeyleri kaçırmaktan korkuyorum. Bu yazdıklarınızı bir ara pdf olarak toplarsanız çok güzel olur.
Birde ARM konusunda mutlaka okuyun dediğiniz kitaplar hangileridir? Ebook olması tercihimdir. İngilizce Türkçe farketmez.
Yeni işe başladığımdan bir yoğunluktur gidiyor. Fırsat bulunca ve kartlar gelince bende az çok elimden geldiğince foruma birşey eklemek isterim.
@sigmoid arkadaşım seninle aynı durumdayız, yeni işe girdim yoğunve zamanım yok :)
dediğin gibi dersleri pdf olarak ouşturup yayınlamak daha güzel olur.
ART 'ın çalışmasını yada yapısını detaylıca anlatan bir dökümana rastlayan var mı?
Şu ana kadar ratlamadım.
Fakat bazı ipuçları var bunları yorumlayınca şöyle çalışıyor olabilir.
CPU en büyük hızda çalışırken (168Mhz) flash roma ancak 6 clkda bir erişebiliyor. Daha açık ifadeyle 6wait state var ve her flash okumadan sonra 6 clk bekleme var.
Adamlar Flashı 32bit değil 128 bit yapmışlar. Yani bir çıpıda 4 tane 32 bit okuyor. Böyle olunca CPU ikinci okumayı 6 clk sonra yapsa bile
Elinde zaten daha sonra ihityaç duyacağı kodlar hazırda bekliyor oluyor.
Dediğim gibi şimdilik bu bir yorum. Detaylı bilgi bulursak aslını öğreniriz.
Aşağıdaki örnek programı Keil ders başlığında son konuda vermiştim.
#include "STM32F4xx.h"
void SystemInit()
{
RCC->AHB1ENR |= 0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislarinı en yuksek hizda kullanacagiz
}
int main()
{
while(1)
{
GPIOD->ODR= 0x0000F000; // Ledler yansin
GPIOD->ODR= 0x00000000; // Ledler sonsun
}
}
C dersleri başladığında göreceğiz fakat şimdiden RCC->AHB1ENR şeklinde satır görürsek bunun, RCC register grubunun bir üyesi olan AHB1ENR registeri anlamına geleceğini bilelim. Yanı sonuçta bu bir register. Bu registeri Rehberde RCC_AHB1ENR olarak bulabilirsiniz.
Deneme kitindeki ledler D portunun 15, 14, 13 ve 12 nolu bitleriyle kontrol ediliyor.
GPIOD->ODR= 0x0000F000; // Ledler yansin
GPIOD->ODR= 0x00000000; // Ledler sonsun
Yukarıdaki kodlar 32 bitlik D portuna 0x0000F000 ardından da 0x00000000 yazıyor.
Yani ilk satır 4 ledin hepsini birden yakıyor, sonraki satırda hepsini birden söndürüyor.
Şimdi SystemInit fonksiyonundaki
RCC->AHB1ENR |= 0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislarinı en yuksek hizda kullanacagiz
satırlarına bakın.
Rehber dokumanda RCC_AHB1ENR, GPIOD_MODER ve GPIOD_OSPEEDR registerlerin anlatıldıkları sayfaları bulun.
Neden bu registerlerin içine yukarıdaki sayıları yüklediğimin cevabını bulmaya çalışın.
Bu çok önemli bir çalışma. Muhakkak uğraşın.
Alıntı yapılan: Prof.EleCTroN - 21 Ekim 2011, 14:34:09
ART 'ın çalışmasını yada yapısını detaylıca anlatan bir dökümana rastlayan var mı?
Ben bu sabah bu dökümanın(Doc ID 15687 Rev 4) (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00233952.pdf) 9 sayfasını inceledim bulduğum en ayrıntılı döküman bu.
Dersi boşverin şamata daha güzel olmuş. ne lazımsa pat diye sorulabilir. Umarım ben de bir şeyler sorup öğrenebilirim. kit mit de almadık ama daha iyi bir kit çıksın şöyle yapacağım işlere uygun olsun istiyorum. ne iş yapacağım da belli değil ondan
elimde st32f100 kiti vardı. keil i kurup üzerinde stlink ile led yakıp söndürdüm. ama port atamalarını felan anlamadım.
ST MCU larda registerlere değeri direk yazıyoruz değilmi. NXP LPC MCUlarda olduğu gibi bit işlemi yapmıyoruz.
ustalar dma ünitelerimiz kaç adet bu işlemcide
dma1 ve dma2 var ama 8stream yazıyor 2x8 mi yani
yoksa 2mi :S
Alıntı YapAşağıdaki örnek programı Keil ders başlığında son konuda vermiştim.
#include "STM32F4xx.h"
void SystemInit()
{
RCC->AHB1ENR |= 0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislarinı en yuksek hizda kullanacagiz
}
int main()
{
while(1)
{
GPIOD->ODR= 0x0000F000; // Ledler yansin
GPIOD->ODR= 0x00000000; // Ledler sonsun
}
}
Hocam burada SystemInit() main fonksiyonunu içinde çağırılması gerekmiyo mu?
Alıntı yapılan: MC_Skywalker - 21 Ekim 2011, 20:14:30
ST MCU larda registerlere değeri direk yazıyoruz değilmi. NXP LPC MCUlarda olduğu gibi bit işlemi yapmıyoruz.
Bit işleminden kastın oku modifiye et yaz ise STM de de aynı şeyleri yapabilirsin.
Şu anda en basit kodla başladık. İşlemci reset rutininden çıkar çıkmaz registerleri modifiye etmeye başladı.
Eğer modifiye edilmiş registerlerde tekrar bazı değişiklikler yapılacaksa o zaman zaten oku modifiye et ve yaz tercih edilir.
Bunu mu demek istedin?
@Yamak
Hayır SystemInit fonksiyonu Startup dosyasından çağrılıyor.
Eğer mainden sen çağırmak istiyorsan, SystemInit fonksiyonuna bir şey yazma ve örneğin Init() diye bir fonksiyon oluştur ve içine yukarıdaki SystemInit kodlarını yaz ve main fonksiyonundan sen Init() i çağır.
bir IO yu seçeceğimiz zaman onu and or gibi bir işle tabi tutup değeri registere yazıyordu.
tam emin değilim mbed ile uğraşınca bunları unuttum.
mbed de herşey tanımlı
Tamam işte ayni şeyden bahsediyoruz.
İlk programı olabildiğince sade şeçtim. Sanırım bundan daha basit örnek kod da yazılamaz.
2 DMA ünitesi var.
Her bir üniterye 8 veri akışı aynı andda FIFO olarak erişebilir.
benim anladığım bu.
MBED de ne nasıl hazır?
Alıntı yapılan: bunalmis - 21 Ekim 2011, 21:40:18
MBED de ne nasıl hazır?
#include "mbed.h"
DigitalOut myled(LED1);
int main() {
while(1) {
myled = 1;
wait(0.2);
myled = 0;
wait(0.2);
}
}
hocam fifo dediğiniz şey first in first out
ilk giren ilk çıkar değilmi :D maliyet muhasebesi stok yönetimi dersinde görmüştüm işe bak :DD
bu konuda biraz bahsettmiştim https://www.picproje.org/index.php/topic,31501.0.html
PwmOut LEDRPWM(p22); // PWM çıkış pinlerinin tanımlan
şeklinde yazıyorsunuz modülün p22 ayağı dırek PWM çıkış oluyor. Keil derleyicisini kullanıyorlar ama herşyi *.h ve *.lib dosyalarına tanımlamışlar hiç uğraşmıyorsunuz.
ST nin de hazır fonksiyonları var. Hatta ARM için evrensel fonksiyonlar var. İleride onlara da değiniriz. Ben bu tip hazır fonksiyonlarla hiç uğraşmadım. Uğraşan arkadaşlar anlatırlar artık.
Yalnız bu aşamada registerler üzerinden çevre birimleri nasıl ayarlanır konusunu pek çok örnekle işleyeceğiz.
Çünkü bu konularda fikir edinilmeden ARM hakkında fikir edinilmez.
Alıntı yapılan: MC_Skywalker - 21 Ekim 2011, 21:51:06
bu konuda biraz bahsettmiştim https://www.picproje.org/index.php/topic,31501.0.html (https://www.picproje.org/index.php/topic,31501.0.html)
PwmOut LEDRPWM(p22); // PWM çıkış pinlerinin tanımlan
şeklinde yazıyorsunuz modülün p22 ayağı dırek PWM çıkış oluyor. Keil derleyicisini kullanıyorlar ama herşyi *.h ve *.lib dosyalarına tanımlamışlar hiç uğraşmıyorsunuz.
Peki bahsettiğiniz bu yöntem hoşunuza gidiyormu? Bu şekilde ARM işlemciyi ne kadar iyi tanıyabiliyorsunuz?
Kursun ilerleyen dönemlerinde bahsettiğiniz tip kolaylıkları kullanmamızı mı istersiniz?
Alıntı yapılan: bunalmis - 21 Ekim 2011, 21:54:27
Peki bahsettiğiniz bu yöntem hoşunuza gidiyormu? Bu şekilde ARM işlemciyi ne kadar iyi tanıyabiliyorsunuz?
Kursun ilerleyen dönemlerinde bahsettiğiniz tip kolaylıkları kullanmamızı mı istersiniz?
böyle hazir kütüphanelerle baslamak yeni baslayanalr icin ideal ollabilir ama o zamanda pic programlamakdan baska fark kalmaz
bana kalsa arm dan korkmamak icin önce hazir kütüphane kullanmak mantikli gibi hocam sonra isteyen kendini gelistirmek isteyen zaten o kütüphaneyi acar bu amcam bunu nasil yazmi$ diye bir kurcalar
Verdiğim register yükleme yoluyla yapılan programdan korkan varmı peki?
Mesela PLL konusunda M,N,P,Q değerlerinin hesaplanması konusuna baktınızmı? https://www.picproje.org/index.php/topic,35721.0.html (https://www.picproje.org/index.php/topic,35721.0.html)
Hocam bence temelden gitmekte fayda var.. Hazır kütüphane mantığında değilde sizin yaptığınız gibi harcı biz karalım neyin nasıl olduğu daha net anlaşılır
ben pic ile bugüne kadar hiç ogrenmedigim şeyleri oğreniyorum 3 ay da pici ogrendim
hazır fonksiyonlarla başlayınca
hiç geri dönüp register olaylarına giresiniz kalmıyor oyüzden başında oğrenmekte fayda var
eminimki herkez kendi fonksiyonlarını yazmak ister buda anca boyle olabilir bence
hem boylece hazır fonksiyonlara baktığımızda bu fonksiyonun neler yaptıgınıda ancak bu şekilde kavrayabiliriz
*******************************************
ek:
konuyu dagıtmadan bişey sorabilirmiyim.?,
GPIO main features
● Up to 16 I/Os under control
● Output states: push-pull or open drain + pull-up/down
open drain nedemektir ne faydası vardır bilen varmı?
mbed de ki hazır kütüpaneler sayesinde hiç birşet öğrenemedim.
5 dakikada SD karta veri yazan program oluşturuyorsunuz ama nasıl çalıştığını bilmiyorsunuz.
LPCXpresso ile uğraştım ama code red IDE si kafamı çok karıştırıdı işin içinden çıkmadım. c/c++ aşına olmam rağmen.
Kütüpane ve başlık dosyalarımı kendim oluşturmak isterim. neyin ne olduğunu bilmeliyim ve işlemciye hükmetmeliyim. bence bu eğitimde amacımız bu işlemciye (Cortex M) hükmetmeyi öğrenmek olmalı.
Alıntı yapılan: gambit1244 - 21 Ekim 2011, 22:13:51
ben pic ile bugüne kadar hiç ogrenmedigim şeyleri oğreniyorum 3 ay da pici ogrendim
hazır fonksiyonlarla başlayınca
hiç geri dönüp register olaylarına giresiniz kalmıyor oyüzden başında oğrenmekte fayda var
eminimki herkez kendi fonksiyonlarını yazmak ister buda anca boyle olabilir bence
hem boylece hazır fonksiyonlara baktığımızda bu fonksiyonun neler yaptıgınıda ancak bu şekilde kavrayabiliriz
*******************************************
ek:
konuyu dagıtmadan bişey sorabilirmiyim.?,
GPIO main features
● Up to 16 I/Os under control
● Output states: push-pull or open drain + pull-up/down
open drain nedemektir ne faydası vardır bilen varmı?
Örneğin 16F84 de PA4 open collector tarzı bir çıkışa sahiptir.
Yani PIC içerisindeki Çıkış transistorunun emiteri GND ye bağlıdır fakat
collector ü direk port bacağına gelir yani boştadır.Dolayısı ile bu uç tan "1"
seviyesi almanız için uygun bir direnç ile pull up yapmanız gerekir.
Open drain ise aynı işlemin FET transistorlerdeki halidir.
RCC->AHB1ENR |= 0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
Benim buradan anladığım aşağıda. doğrumu anladım?
hatamı buldum
Evet. Bu registerler.
Şimdi bu registerlere yüklediğimiz sayısal değerlerin, bu registerlerde hangi bitleri 1 yaptığına dikkat kesilin.
Hatta yükleme sonucunda değeri 1 olan bitlerin kutucuklarını sarıya boyayıp bizlerin de görmesini sağlarsan çok süper olur.
Düzeltemeyi yaptım tekrar yükledim.
[IMG]http://img8.imageshack.us/img8/3558/reister.jpg[/img]
Az önce mantıksız bir soru sormuşum.
RCC->AHB1ENR |= 0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
zanten burda bit işlemi yapılmış mevcut register içeri OR (bit)işlemine tabi tutulmuş.
Bir önceki sayfada hazır kütüphanelerden bahsedilmiş.Bence hazır kütüphane ile yol alınmasa dahi bu konuyada değinilirse çok iyi olur.En azından bir fikir sahibi olmuş oluruz ve bir sd kart uygulaması yapmak istedigimizde nereden başlayacagımız biliriz.
mc_skywalker
örnek süper olmuş bende tam aynı orneklerin cortexm3 olanını bulmuştum onların üzerine bu tam cuk oldu
hem m3 ile m4 arasındaki farklarıda kavradım bügün cok verimli bi gün oldu sayenizde :))
1. porta clock ver (var yada yok)
2.portun modunu seç (input*general purpose output*alternate function*analog)
3. portun hızını seç (2-25-50-100)mhz burdaki bilgiyi anlamadım eğer kondansatorunuz 15pf ise max80 veririm mi demek istiyor?
RCC->AHB1ENR |= 0x00000008; yazdık çünkü portd yi kullanabilmemiz için clock sinyalinii portdye vermemiz gerekiyormuş AHB1ENR cloğu portla tatıştıracak çöpçatan reg burası oluyor pekiya neden 0x00000008 yazdık
çünkü portd RCC->AHB1ENR registerinin 4 bitine denk geliyor ikilik yazılımda şöyle oluyor 00001000
hex olarakta 8 e tekabül eder
0x00000008 buradan geldi diye yorumladım
çok yanlış yorumlamış olabilirim ama ben bu satırdan bunu anladım
???
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
burada her pin için 4 farklı tip var eğer yanlış anlamadıysam.
0101010100000000000000000000000
00 reset(giriş varsayılan)
01 çıkış
10 alternatif kullanım 'artık farklı amaçlar için '
11 analog mod
biz çıkış olarak tanımladık. yani 01 olarak kullandık. kalanlar ise giriş olarak tanımlanmış oldu öyle mi?
GPIOD_MODER için:
Alıntı Yap00: Input (reset state)
01: General purpose output mode
10: Alternate function mode
11: Analog mod
Pic'lerde TRIS'ler ya output(0) ya da input(1) olurdu. Buradaki diğer seçenekler (10 ve 11) ne anlama geliyor ? Hem analog hem input olmuyor mu yani :P
Bir de kullanmadığımız pinleri neden output'a çekmedik ?
GPIOD->MODER = 0x55000000 yazdık çünkü GPIOx_MODER port tanımlamalarının yapıldığı reg 0x55000000 neden yazdık?
Bits 2y:2y+1 MODERy[1:0]: Port x configuration bits (y = 0..15)
These bits are written by software to configure the I/O direction mode.
00: Input (reset state)
01: General purpose output mode
10: Alternate function mode
11: Analog mode
pdf'nin ilgili bölümünden bir bölüm pin yönlenlendirmesi iki bit tarafından sağlanıyor görünüyor
ilgili pdf'nin tablo18'inden anladığım kadarıyla GPIOD->MODER registerinin 31,30=pin15,29,28=pin14,27,26=pin13,25,24=pin12
şeklinde ayar seçeneği sunuyor
55000000 i ikilik olarak ele alırsak 010101010000000000000000000000000
01: General purpose output mode notuna göre çıkış
ben daha ilemciyi incelemedim ama anladığım kadarıyla portlar 16bit
arm belki öğrenemeyeceğim ama pdf okumaya alışacağım kesin
ilk önce yanlış yapmışım düzelttim hesap makinasıyla çevirince en yüksek biti 0 olursa göstermiyor 31 bit oluncada saymadım 10 diye algıladım aynı haaya düşmeyin die yazmak istedim
NecroCapo senin yanıtı okuyunca bitleri saydım ;D
Alıntı yapılan: ilhan_mkp - 22 Ekim 2011, 00:31:47
RCC->AHB1ENR |= 0x00000008; yazdık çünkü portd yi kullanabilmemiz için clock sinyalinii portdye vermemiz gerekiyormuş AHB1ENR cloğu portla tatıştıracak çöpçatan reg burası oluyor pekiya neden 0x00000008 yazdık
çünkü portd RCC->AHB1ENR registerinin 4 bitine denk geliyor ikilik yazılımda şöyle oluyor 00001000
hex olarakta 8 e tekabül eder
0x00000008 buradan geldi diye yorumladım
çok yanlış yorumlamış olabilirim ama ben bu satırdan bunu anladım
???
Aynen dedigin gibi.
Yalniz 4. bit demek yerine 3. bit de. Cunku en dusuk bit, B0 bitidir ve buna 0. bit deriz.
Kurs notlarinda bitlerden bahsederken en dusuk bite 0. bit diyecegiz.
Alıntı yapılan: NecroCapo - 22 Ekim 2011, 01:00:05
GPIOD_MODER için:
Pic'lerde TRIS'ler ya output(0) ya da input(1) olurdu. Buradaki diğer seçenekler (10 ve 11) ne anlama geliyor ? Hem analog hem input olmuyor mu yani :P
Bir de kullanmadığımız pinleri neden output'a çekmedik ?
00: Input (reset state)
01: General purpose output mode
10: Alternate function mode
11: Analog mode
Ledlerin bagli oldugu pinlere denk gelen port bitlerini moder registerinde 01 ile tanimlayarak o pini output yaptik.
Diger pinleri input yaptik. Output da yapabilirdiniz. Ancak;
Deneme kartinin semasini acip pinlerin bir baska cipin outputuna bagli olmadigindan emin olmaniz gerekir. Aksi halde ciplerin cikislari birbirine baglanirsa birisi 1 digeri 0 ise
port pinlerinden yuksek akim akarak ciplerin o pinleri hasar gorebilir. Bu nedenle boyle bir durumla karsilasmamak adina diger pinleri input tanimladik.
10: Alternate function mode
Bu, portun ilgili pininin farkli amacla kullanilacagini tanimlar. Mesela atiyorum bu pin pwm cikisi olabilir. Timer clk girisi olabilir vs. (Alternatif amaclar)
11: Analog mode
Eger bir pin hem port hemde Analog inp yada output ozelligine sahipse ve biz bu pini analog amacli kullanacaksak bu durumda bu pini 11 ile tanimlariz.
MODER = MODE Register
Yani pinin modunu belirleyen register demek.
Yalniz 4. bit demek yerine 3. bit de. Cunku en dusuk bit, B0 bitidir ve buna 0. bit deriz.
Kurs notlarinda bitlerden bahsederken en dusuk bite 0. bit diyecegiz.
[/quote]
o konuda tereddütte kalmıştım dediğiniz gibi kullanarım
not:bu alışkanık otomasyom panolarından kalan bir durum plc çıkışları x0 dan başlar bağlı röleler r1 diye numara almaya başlar cad programlarından kalan alışkanlıklar nasıl beceriyorum bilmiyorum ama alakasız şeyleri baz alabiliyorum
GPIOD->OSPEEDR= 0xFFFFFFFF
Evet bunu yorumlayacak varmi?
GPIOx_OSPEEDR portların çıkış hızını ayarlayan register ffffffff değeri ikilik olarak 11111111111111111111111111111111 olur
Bits 2y:2y+1 OSPEEDRy[1:0]: Port x configuration bits (y = 0..15)
These bits are written by software to configure the I/O output speed.
00: 2 MHz Low speed
01: 25 MHz Medium speed
10: 50 MHz Fast speed
11: 100 MHz High speed on 30 pF (80 MHz Output max speed on 15 pF)
GPIOx_MODER registerindeki gibi bir pini iki bit etkiliyor
hızımız bitler 11 olduğundan 100 MHz High speed on 30 pF (80 MHz Output max speed on 15 pF) burada yazanı olmayan ingilizcemle anladığım kadarıyla bir kondansatör değeriyle belirleniyor
örneği çok incelemedim oscdenmi nereden geliyor onada yarin bakayım
tam hızı bilmek için nereden geldiğini bulmam lazım
bu arada benim keil ne yaptıysam hata veriyor sanırım benim pcnin komaya girişiyle alakalıbir durum :'(
00: 2 MHz Low speed
01: 25 MHz Medium speed
10: 50 MHz Fast speed
11: 100 MHz High speed on 30 pF (80 MHz Output max speed on 15 pF)
OSPEEDR a birseyler yazinca ne oluyor da oluyor portun pinlerinin calisacagi frekans degisiyor?
Bu bilgi hic bir yerde yok. Son derece ilginc bir soru.
Adamlar sirf bu is icin register koymuslar.
Ledlerin bagli oldugu Pinleri toggle etme frekansim 4Mhz iken scopla yaptigim gozlemlerde, bu registerin bitlerinin 00 yada 11 olmasinin hic bir farkini goremedim.
Bu 30pF ve 15pF olayını anlamadım.
Eğer pine bağlı kapasitif yükten bahsediliyorsa tersi olması gerekmez mi?. Yani 30pF lık yükte daha yavaş çalışması..
Yada 30pF, 15pF ile ne kasdediliyor.
Bende iyildirim'in yazdığını yazacaktım fakat olayın ters olduğunu fark edince vaz geçtim.
Belki yanlış yazılmıştır.
Çıkış hattının Kapasitesi olması gerekli. 100MHz'de 15pF 80MHz'de ise 30pF. Diğer türlü çok mantıksız olur...
Şöyle bir gözlemde bulundum;
STM32F407 kontrolcüsününün D portunu saat darbesini alcak şekilde ilgili kaydedici kurarak aktif ettik ve diğer portlara saat darbesi uygulamadık. Dijital dünyada saat darbesi yoksa işlem yoktur, yani bekleme konumunda olup o anki durumunu korur.
Burdan yola çıkarsak diğer portlar uyukuda buda bu mcu'nun güç tüketimin düşürür.
Bence bu frekans olayida guc tuketimiyle alakali
Alıntı yapılan: muhittin_kaplan - 22 Ekim 2011, 11:01:48
Bence bu frekans olayida guc tuketimiyle alakali
peki arkadaslar pic de budurum nasıldı boyle bi ozellik varmıydı yoksa
her bacakta sürekli clock varmıydı
mesela picinde low power modelleri var
o piclerde clocku kapatan registerlarmı vardı arm gibi
Bir portun cikisindaki yukun kapasitif degeri yuksekse;
porttan cikan sinyalin frekansi arttikca yuk uclarindaki sinyalimizin dalga sekli kare dalga sinyal seklinden uzaklasir ve genligi dusmeye baslar.
Ilk basta ST nin TI da oldugu gibi pinleri surme kapasitesini (akim degerini) ayarladigini dusundum.
Bunun boyle oldugunu sinamak icin ledleri surekli yaktim ve OSPEEDR registerini bir 00 bir 11 degistirdim. Bu esnada led parlakligini gozledim ve degisen hic bir sey olmadi.
Demekki pin akimi yazilimla kontrol edilmiyordu.
Pinlerden 4Mhz sinyal cikacak sekilde bir kod yazdim. OSPEEDR ye once 00 yazarak katalogdaki aciklamaya aykiri durum olusturdum.
Cunku 00 durumu max 2Mhz icin gecerli. Scopla led uclarindaki sinyale baktim.
Ardindan 11 yazarak portu 100Mhz moduna gecirdim ve gene led sinyaline baktim.
Arada hic fark yoktu.
Bu registerin amacini cok merak ediyorum.
Not: Biraz once ledler porta dogrudan bagli olduklari icin, portun cok fazla yuklendigini bu nedenle OSPEED registerine yapilan yuklemenin, led bagli pindeki dalga seklini gozleyemedigimi dusunup tamamen bos olan pinlerde bu registerin iceriginin etkisini gozledim.
PD11 pininden 4Mhz kare dalga cikarken
SPEED registerinin her bir iki bitine
00 yazinca 9ns rise ve fall time
01 yazinca 4ns rise ve fall time
10 yazinca 3.5ns rise ve fall time
11 yazinca 3.5ns rise ve fall time
degerlerini olctum.
Bu kez frekansi 18Mhz'e cikarttim ve
00 yazinca no sinyal !!!!!
01 yazinca 4 ns rise ve 3 ns fall time 2.8v !!!!
10 yazinca 4 ns rise ve 3 ns fall time 3.3v
11 yazinca 4 ns rise ve 3 ns fall time 3.3v
Frekansi 33Mhz yaptigimda
Gene 00 da hic sinyal yokken
diger modlarda sorun yok genlikler ve sureler hemen hemen ayniydi.
Bu durumda OSPEED registerinin etkisi tam olarak gozlenmis ve anlasilmis oldu.
Portun akim kapasitesini degistiriyor. Ancak bu etki ledde gozlemlenecek kadar etkili degil yada led portun bu ozelliginin duzgun calismasini engelleyecek derecede yukluyor.
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf)
Linkinde kartimizin semasi mevcut.
Bir arkadas CPU portlarinin hangileri bos hangileri kart uzerindeki diger ciplere baglanmis (kullanmamiz sakincali) bunun bir tablosunu cikartabilirmi?
Mesela
PB9 Audio_SDA
PB6 Audio_SCL
PC7 I2S3_MCK
PC10 I2S3_SCK
PC12 I2S3_SD
PA4 I2S3_WS
Pinleri kartta CS43L22 Audio cipi icin kullanilmis. Bunun gibi....
STM32F4 Clock Configuration Tool
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00039457.pdf
http://www.st.com/internet/com/SOFTWARE_RESOURCES/TOOL/CONFIGURATION_UTILITY/stm32f4_clockconfig.zip
How to achieve the lowest current consumption with STM32F
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00033348.pdf
Verdiğim linklerdeki 2. pdf de yazan açıklamaya göre (sf:19) OSPEEDR pinin akım tüketimini arttırıyormuş,
orada yazdığından anladığım kadarıyla pinden çıkan akım değilde, pinin sürülürken ihtiyaç duyduğu akım değerini arttırıyor
(yani bir mosfet sürücü ile çalışıyormuş gibi düşünürsek, mosfete basılan akımı değilde sürücüye girdiğimiz akım değeri arttırılıyor)
Eğer yanlış anlamadıysam...
Kartın üzerinde beslemeyi kesen jumpera bir ampermetre bağlayarak belki gözlemleyebiliriz.
Karttaki pinlerin kullanıldığı yerler sayfa 19daki tabloda belirtilmiş zaten hocam, bunu çiplere göre mi düzenleyelim?
mozkan87 ın verdiği pdf yararlı oldu.
Alıntı yapılan: bunalmis - 21 Ekim 2011, 03:24:30
Cipimizin ART modulunde prefetch ile ilgili BUG var. Bu BUG'in islemcinin performansini nasil etkileyecegi konusunda arastirma yapan varmi? ...
Wait state süresi < okunan 128 bit içindeki kodların icra süresi olduğu zaman prefetch özelliği yararlı oluyor. Mesela 4 adet 32 bit komut işleniyor ve WS=3 ise 3. komut işlenirken tekrar okuma yapılıyor ve sıraya ekleniyor böylece hafızadan okuma yapmak için süre harcanmıyor.
168 MHz de WS=6 ve komutlar 32 bit ise, o zaman prefetch kullanmanın anlamı kalmıyor (eğer her komut 1 cycle da icra ediliyorsa)
Alıntı YapYazılımla bir pini 80 Mhz de toggle ettim. ART daki sorun kendini nasıl gösteriyor anlamadım.
prefetch özelliği pasif olsada muhtemelen "Instruction cache memory" aktif olduğu için burada hiçbir gecikme oluşmuyor.
Not: Tekrar belirtelim prefetch şuanda kullanılamıyor. İlerdeki uyarlamada (revision) bu sınırlama çözülecek.
Alıntı yapılan: bunalmis - 22 Ekim 2011, 12:05:00
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf)
Linkinde kartimizin semasi mevcut.
Bir arkadas CPU portlarinin hangileri bos hangileri kart uzerindeki diger ciplere baglanmis (kullanmamiz sakincali) bunun bir tablosunu cikartabilirmi?
Mesela
PB9 Audio_SDA
PB6 Audio_SCL
PC7 I2S3_MCK
PC10 I2S3_SCK
PC12 I2S3_SD
PA4 I2S3_WS
Pinleri kartta CS43L22 Audio cipi icin kullanilmis. Bunun gibi....
şimdi çizimleri print alayım, akşam eve dönünce bir gözden geçirir tablo yaparım.
Evet OSPEED deki degisim pinden cikan akimin surekli akimini değil de sadece inis ve cikislardaki andaki akim degerini degistirdiginden bu degisimi ledde parlaklik olarak goremiyoruz da olabilir.
Intel 8051 ailesinde her ne kadar cikis akım kapasitesi ayarlanamıyorsada, portlardan çıkan sinyallerin yükselen ve inen kenarlarında son derece belirgin akım basma emme yeteneği var. Scopla bu etki son derece açık gözlemlenebiliyor.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Kullanmamizda risk olusturacak pinleri alt alta basit bir tabloda siralarsak her an gozumuzun onunde kalir ve ileride ornek program yazarken yanlislikla bu pinleri secmeyiz.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Kartımız gelene kadar bendeki m3 kartını denemeye çalışıyorum, Derleyici ile alakalı anlamadım bir nokta main.c ye herhangi bişey yazmayıp derlersem hata veriyor,zaten içinde hiç birşey yokki neden system init de bilmemne bulunamadı tarzında hatalar veriyor? Ayrıca projeye system_stm32f10x.c dosyasını eklersem hiç bir hata kalmadan boş main() derleniyor.Anlamadım diğer nokta ise ben hiçbir #include şeklinde dosyayı main.c içinde tanımlamadım ,system_stm32f10x.c dosyasını sadece projeye ekleyip kalasöründe içine attım,bu dosyayı kullanacağımızı nerden biliyor?
Alıntı yapılan: mcan - 22 Ekim 2011, 13:49:04
Kartımız gelene kadar bendeki m3 kartını denemeye çalışıyorum, Derleyici ile alakalı anlamadım bir nokta main.c ye herhangi bişey yazmayıp derlersem hata veriyor,zaten içinde hiç birşey yokki neden system init de bilmemne bulunamadı tarzında hatalar veriyor? Ayrıca projeye system_stm32f10x.c dosyasını eklersem hiç bir hata kalmadan boş main() derleniyor.Anlamadım diğer nokta ise ben hiçbir #include şeklinde dosyayı main.c içinde tanımlamadım ,system_stm32f10x.c dosyasını sadece projeye ekleyip kalasöründe içine attım,bu dosyayı kullanacağımızı nerden biliyor?
Startup.s dosyasına bakarsan
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
satırlarını goreceksin.
Bu kod, SystemInit kodlarını kendine dahil ediyor ve çağırıyor.
Aynı şekilde main fonksiyonu da istiyor.
En basit örnekle ilgili soru kalmadığına göre aşağıdaki kod üzerinde tartışalım.
Fakat şu sorunun gelmiş olması lazımdı.
Tamam bu kodları çok iyi anladık da ledleri yakıp söndürmek için yüzlerce register içinden sadece bu registerleri seçip kullanarak kod yazılacağını nasıl bildin?
Örnek verdiğim kısa programda satırların yerlerini değiştirirsek o program çalışmaz.
Peki bu registerlere hangi sıra ile değer yükleneceğini nasıl bildin?
Bu iki sorunun cevabını aşağıdaki kodu da anlaşıldıktan sonra vereceğim.
Aşağıdaki program kendi halinde yanıp sönen led projesi. http://www.youtube.com/watch?v=g88ILHmWE98 (http://www.youtube.com/watch?v=g88ILHmWE98) Kodun SysInit rutinleri, registerleri düzenleyerek 8Mhz Xtal Osc ile CPU ve BUSları en yüksek hızda çalışmasını sağlar. LEDlerin bağlı olduğu pinleri (PD15,14,13,12) çıkış moduna ayarlar. ve 4 led yanıp sönmeye başlar.
#include "STM32F4xx.h"
void SystemInit()
{
volatile int i, DBG;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000)); // Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=4 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislarinı en yuksek hizda çalışacak moda geçirelim
}
void Delay()
{
unsigned int i;
for(i=0;i<0x800000;i++);
}
int main()
{
while(1)
{
GPIOD->ODR= 0x0000F000; // Ledler yansin
Delay();
GPIOD->ODR= 0x00000000; // Ledler sonsun
Delay();
}
}
Not: Hiç C bilmeseniz dahi bu tartışmaya katılın. Hiç bir satır anlaşılmaz kalmasın.
Muhakkak sorun. Fakat soru sormadan önce ilgili registeri Rehberden bulup o registerde ne olup bitiyor bakın fikriniz olsun.
system_stm32f10x.c gibi dosyaların içinde hazır system_init bölümü vede bazı default ayarlamalar var sanırım. Ayrıca stm32f10x_RCC.H gibi dosyalar da var bunlar bizim ayarladığımız yazmaşları otomatik ayarlayan fonksiyonları mı barındırıyor? Forumda bahsedilen st nin hazır driverları bunlarmı?
mcan sanki icimden bir his bu register olaylarini sevemedigini soyluyor. Dogrumu? Hazir kutuphaneler kullanip isin bu kismindan kacmak gibi bir niyetin mi var?
elimde 32f100 kit mevcut
üzerinde kendim anlayarak bir bilinky yapmaya çalışıyorum. zor, anlayamıyorum.
Kitiniz gelipte verilen ornekleri derleyip kite yukleyip calistiklarini gorunce ve burda anlatilanlari anladikca isler cok kolaylasacak.
(Bu arada kitimizde STM32F407 den baska bir de STM32F103 var ve bunu SWD islemleri icin kullaniyor.)
ARM islemciyle projemiz sayesinde tanisan ozellikle de daha onceleri kullandiklari cipin registerlerinin anlatildigi dokumanlari okuma aliskanliklari olmayan arkadaslarin su anda
inanilmaz zorlandiklarini biliyorum.
Su anda tartistigimiz konularda adi gecen registerleri Rehber dokumanindan acip anlamaya calismaz ve sormazsaniz anlayamazsiniz.
Bu arada eger elektronik temelli olmayip sadece yazilimci temelli arkadaslar varsa onlar daha da zorlanabilir.
Fakat hazir kutuphaneler bir cozumdur bunlardan yararlanarak uygulama kodlarını yazabilirler, ancak ne olursa olsun registerleri anlamalarini oneriyorum.
Sonucta ST firmasinda kutuphane fonksiyonlarini yazan adamlar registerden yola cikiyorlar.
Register programlama konusuna ısınırsanız, önünüze hangi firmanin hangi çipi konulursa konsun şıkır şıkır çipe kod yazabilirsiniz. Yeterki çipin rehber tarzında dokümanı olsun.
Pin Çıkışlarını Modüllere göre düzenleyerek yükledim, ayrıca yanlarına kullanılabilecek fonksiyon tiplerini de belirttim
eğer bir modülle çalışmak istersek bulunması kolay olsun diye,
bir de siz gözatın yanlış yazdığım bir nokta var mı bunun kontrolünü de yapmış oluruz
http://www.4shared.com/file/8MeEKyr8/STM32F4Discovery_Pinouts.html
(Not: Eğer sayfayı açamıyorsanız DNS'inizi değiştirin)
Edit:hatalı dosya
Alıntı yapılan: bunalmis - 22 Ekim 2011, 16:45:17
mcan sanki icimden bir his bu register olaylarini sevemedigini soyluyor. Dogrumu? Hazir kutuphaneler kullanip isin bu kismindan kacmak gibi bir niyetin mi var?
:) Aksine bu register olayını ve dosyaları anlamaya çalışıyorum yanlız bazı dosyaların içinden çıkamadım,en basit karşılaştığım olay
DENEME_M3.axf: Error: L6200E: Symbol SystemInit multiply defined (by system_stm32f10x.o and clean-main.o).
kendi system_init() fonksiyonumu yazdığımda bu hatayı alıyorum, bir başka açıdan eğer kendi system_init() fonksiyonumu kullanmak için "#include stm32f10x.h" satırını kaldırırsam bu sefer
clean-main.c(13): error: #20: identifier "GPIOD" is undefined
hatasını alıyorum.Acaba orjinal dosyada sytem_init() fonksiyonunun adını mı değiştirsem?Forumdan
Alıntı YapAra çalışma olarak
void SystemInit() yerine void systemInit() yada void SYstemInit() init yazın ardından F7 tuşuna basın.
Build Output penceresinde oluşan hata mesajına dikkat edin.
Ardından hatayı yokedin ve
int SystemInit()
{
}
olarak değiştirin ve tekrar F7 ile programınızı derlemeye çalışın.
Bunu okudum ancak o hatayı yok edemedim,kendi system_init() fonksiyonumun adını büyük küçük harf farkı yaratarak değiştirirsem bu sefer startup dosyası benim system_init() fonksiyonumu değil de kendi hazır fonksiyonunu kullanacak sanırım.Ben aksine her bir biti öğrenmekden yanayım pic programlarken genelde okuyup kendim değer veririm ,ancak bu arm yazmaçları bu psoc yazmaçları gibi karışık açıkcası yazmaç kısmı değil beni zorlayan programlama ile ilgili ekstra tanımlamalar ; import export , linker ,make file,weak ve bunun gibi daha önceden pek aşina olmadığım tanımlamalar .Özellikle bu startup dosyasını hiç sevmedim hangi dille yazılmış anlamadım __initial_sp yazmışlar bu nedemek mesela? ___ işaretini başa koyunca ne oluyor.Asm mi değilmi nerde belirtiyor #asm gibi bir başlangıcı yok.
Bir kere şundan emin olalım.
Eğer Keil dersleri konusunda anlattığım şekilde Deneme adında bir klasör ve bunun içinde Deneme adında proje oluşturduysanız ve içine verdiğim örnek kodları yazdıysanız
bahsettiğiniz hataları almazsınız.
Yok eğer hazır gelen bir projeyi editleyerek bir şeyler yapıyorsanız;
Proje dosyasında genellikle main fonksiyonu ve SystemInit fonksiyonu birbirinden ayrı C dosyalarında tutulur.
Eğer böyleyse ve siz tutup main fonksiyonunun olduğu dosyaya SystemInit fonksiyonu yazarsanız projede toplam iki tane SystemInit fonksiyonu olur ve haliyle derleme aşamasında hata alırsınız.
(Deneme projesinde en tepeye #include "STM32F4xx.h" satırı ekleyerek derleyicinin program içinde yazdığımız registerleri tanımasını sağladık.)
Ben kendi projeme system_stm32f10x.c dosyasını da eklemişim o sebeple hatayı alıyormuşum şimdi o dosyayı projeden çıkardım h dosyasını geri ekledim hata gitti,tabiki bazı yazmaçlar aynı değil o sebeple oraları değiştirmem gerekiyor şimdilik sildim yazmaçlı kısımların bir kısmını.
Alıntı Yap......Özellikle bu startup dosyasını hiç sevmedim hangi dille yazılmış anlamadım __initial_sp yazmışlar bu nedemek mesela? ___ işaretini başa koyunca ne oluyor.Asm mi değilmi nerde belirtiyor #asm gibi bir başlangıcı yok.
Startup dosyası asm ile yazılmış ve Startup'a da girersek bu kurs bitmez. Bir dosyanın ext'i s ise asm, c ise C, h ise header anlamına geliyor.
__initial_sp, reset ardından donanımsal olarak okunup SP registerine atılan SP adresi. Bunun sayısal değerini Keil oluşturuyor.
Başında __ olan değişkenlerin değerleri derleyici tarafından tespit ediliyor.
# asm yazmaya gerek yok çünkü dosyanın uzantısı .s bu asm olduğu anlamına geliyor ve dosyanın içi asm ve derleyiciye özgü pesudo kodlardan oluşuyor.
weak ilginç bir tanımlayıcı. Eğer asm fonksiyonda bir asm label varsa buna rağmen C dosyanızda bu labeli fonksiyon olarak tanımlarsanız asm deki tanım geçersiz kalıyor ve C deki tanım kullanılmaya başlıyor.
Örneğin C de interrupt fonksiyonlarını yazmazsanız asm dosyadaki interrupt fonksiyonlar kullanılıyor. C de interrupt fonksiyonu yazdığınızda artık asm de (startupda) yazılan fonksiyon geçersiz oluyor.
Alıntı yapılan: ErsinErce - 22 Ekim 2011, 17:21:30
Pin Çıkışlarını Modüllere göre düzenleyerek yükledim, ayrıca yanlarına kullanılabilecek fonksiyon tiplerini de belirttim
eğer bir modülle çalışmak istersek bulunması kolay olsun diye,
bir de siz gözatın yanlış yazdığım bir nokta var mı bunun kontrolünü de yapmış oluruz
http://www.4shared.com/file/8MeEKyr8/STM32F4Discovery_Pinouts.html
(Not: Eğer sayfayı açamıyorsanız DNS'inizi değiştirin)
ne zamandır DNS değiştirmedim. Kullanılır Bir DNS verirmisiniz
Alıntı yapılan: muhittin_kaplan - 22 Ekim 2011, 18:31:36
ne zamandır DNS değiştirmedim. Kullanılır Bir DNS verirmisiniz
http://www.opendns.com/
208.67.222.222
208.67.220.220
google dns
8.8.8.8
8.8.4.4
@bunalmıs hocam iyi akşamlar öncelikle
void Delay()
{
unsigned int i;
for(i=0;i<0x800000;i++);
}
fonksiyonu kaç saniye gecikme yapıyor
0x800000 =8.388.608
kez tekrar ediyor
bir tekrarı kaç clockta yapmış oluyoruz bunlara biraz değinsek güzel olmazmı
kaç clockta bir saniye geçiyor? 168milyon clockta bir saniye geçiyor sanırım bu hızda kullandığımız için
mesela portun çıkış frekansı delay fonksiyonunun süresini etkilermi?
cok teşekkür ederim
Gecikme rutinlerini örnekteki gibi yazarsak rutinin ne kadar geçikme yapacağı derleyicinin optimizasyon ayarıyla değişken hale gelir. (Bu ayarlara ileride değineceğiz)
Herhangi bir optimizasyon seviyesi için bahsettiğiniz sorunun cevabı derlenen kodların asm çıktısında gizli.
Yaklaşık olarak ASM komutların hepsini 1 cycle alır ve her BX, B komutu için 3 ilave ederseniz bunu da döngü sayısı ve (168 E6)^1 ile çarparsanız yaklaşık sonucu bulursunuz. Fakat bu konulara girmek bu aşamada son derece lüzumsuz olur.
Portun I/O hızı buradaki Delay süresini etkilemez.
Kodu yazarken bir kaç deneme ardından 0x800000 değerinin flash gösterisinde güzel göründüğüe karar verdim öyle bıraktım.
Yukarıdaki koda benzer bir kaç örnek daha yaptıktan sonra timer ile tekrardan yanıp sonen led ornegı yapacağız. O zaman timera yüklenen değerden yola çıkınca çok kesin olarak geçikme süresini hesaplayabiliriz ve asm kodlara bakmamıza gerek kalmaz.
Gecikme İçin SystemTick Kullanılıyor sanırım.
Hocam Ayrıca ilk Aşamada "Şunlar Şunlar Yapılmalı" (Kodlar Yazılmaya Başlarket Port Ayarlamaları gibi Osilator vs ) diye bir liste oluşturabilirmiyiz ?
void Delay(){
unsigned int i;
for(i=0;i<0x800000;i++);
}
bu arada int olan tanım long olarak değişmesi gerekiyor, gözden kaçmış ufak bir ayrıntı
https://www.picproje.org/index.php/topic,35794.msg256473.html#msg256473
Alıntı Yapbu arada int olan tanım long olarak değişmesi gerekiyor, gözden kaçmış ufak bir ayrıntı
Arm işlemcilerle çalışırken int 32 bit, long int 64 bit demek.
Alıntı yapılan: bunalmis - 22 Ekim 2011, 19:36:14
Arm işlemcilerle çalışırken int 32 bit, long 64 bit demek.
bu arm nin özelliğimidir yoksa 32 bit olmasının özelliğimidir
yoksa keil inmi?
bi onceki konuyu anladım hocam teşekkür ederim
timer ile çalışmaya başladıktan sonra kendi delay fonksiyonlarımızı yazacagız sanırım doğrumu anlamışım hocam
int değerin 32 bit oluşunun sebebinin 32 bit işlemciyle çalışıyor olmamızdan kaynaklandığını düşünüyorum.
işlemcinin kapasitesine göre mi bu Tamsayı (int) belirleniyor. Yani işlemci 16bit olsaydı int 16bit mi olurdu
Ozaman 8 bit de bir karşıtlık var.
Alıntı yapılan: muhittin_kaplan - 22 Ekim 2011, 19:19:39
....Hocam Ayrıca ilk Aşamada "Şunlar Şunlar Yapılmalı" (Kodlar Yazılmaya Başlarket Port Ayarlamaları gibi Osilator vs ) diye bir liste oluşturabilirmiyiz ?
İşlemciyi init etmek için yapılması gerekenler.
1. Clock ayarlamaları (Xtal, PLL, BUS clk ayarlamaları)
2. Kullanılacak portların ayarlamaları (I/O, Alternatif fonksiyon vs vs)
3. Kullanılacaksa Timer, ADC vs vs lerin ayarlamaları
Örneklerde neyi neden yaptığımız anlaşılsın diye örnekleri özel olarak hazırlıyor ve hiç bir fazla kod eklemiyorum.
Okuma yazma bilmeyenlere önce harfler sonra heceler vs öğretiliyordu fakat bu günlerde tersden gidiliyor ya. Buna benzer
bir durum var ve konuların şu anki yöntemde en kolay öğrenileceğini düşünüyorum.
Örnekleri üstün körü değil de bizzat işin içinde olarak incelediğinizde zaten neyin neden yapılması gerektiği kendiliğinden anlaşılacak.
Benim gibi m3 ile deneme yapan arkadaşlar için @Bunalmis in kodunu kopya çekerek m3 için yapmaya çalıştım ve çalıştırdım led yanip sönüyor :)
denemek isteyenler için buraya koyuyorum kod m3 içindir.#include "STM32F10x.h"
void delay(void);
void SystemInit (void)
{ RCC->APB2ENR |= 0x00000016; // GPIOD donanımının clock sinyalini uygulayalım
GPIOC->CRL = 0x33333333; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOC->CRH = 0x33333333; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
}
void delay()
{
unsigned int i;
for(i=0;i<0x80000;i++);
}
int main()
{
while(1)
{
GPIOC->ODR= 0xFFFFFFFF; // Ledler yansin
delay();
GPIOC->ODR= 0x00000000; // Ledler sonsun
delay();
}
}
Alıntı yapılan: muhittin_kaplan - 22 Ekim 2011, 19:45:18
işlemcinin kapasitesine göre mi bu Tamsayı (int) belirleniyor. Yani işlemci 16bit olsaydı int 16bit mi olurdu
Ozaman 8 bit de bir karşıtlık var.
int minimum 16 bit.
Çünkü byte evrensel bir tanım ve 8 bit anlamına geliyor.
Bizi şu anda ilgilendiren
byte 8
short 16
int 32
long int 64
Bunlara zaten C derslerinde Gerbay değinecek. Gerbay, geçtiğimiz hafta içinde kursa başlayamayacağını söyledi sanırım önümüzdeki hafta dersleri başlatmış olur.
@mcan
Eğer CM3 işlemcilerle hiç çalışmadı ve bu kodu CM4 için verilmiş örneklere bakarak kendin uyarladıysan bravo. (kodlarında eksik yada fazla bir şey varmı bilmiyorum fakat bu aşamada önemli değil)
En başta CM3 işlemci ile çalışalım diyenlere hayır bu CM4 kartını kaçırmayalım kursu izledikten sonra kendiniz CM3ü kullanabilirsiniz derken işte bundan bahsediyordum.
http://www.keil.com/support/man/docs/armccref/armccref_Babfcgfc.htm
adresinde tipler belirtilmiş, bunalmis hocanın dediği gibiymiş, CM4 harici Keil'in manualini de iyi okumak lazım anlaşılan =/
Alıntı yapılan: bunalmis - 22 Ekim 2011, 19:57:32
int minimum 16 bit.
Çünkü byte evrensel bir tanım ve 8 bit anlamına geliyor.
Bizi şu anda ilgilendiren
byte 8
short 16
int 32
long 64
Bunlara zaten C derslerinde Gerbay değinecek. Gerbay'ın geçtiğimiz hafta içinde kursa başlayamayacağını söyledi sanırım önümüzdeki hafta dersleri başlatmış olur.
@mcan
Eğer CM3 işlemcilerle hiç çalışmadı ve bu kodu CM4 için verilmiş örneklere bakarak kendin uyarladıysan bravo.
En başta CM3 işlemci ile çalışalım diyenlere hayır bu CM4 kartını kaçırmayalım kursu izledikten sonra kendiniz CM3ü kullanabilirsiniz derken işte bundan bahsediyordum.
Sağolun hocam valla neredeyse bütün gün bişeyler okuyor takip etmeye çalışıyorum özellikle .h dosyalarında baya zaman kaybettim sonunda zorda olsa ledi yaktım ,yoksa kendimi salak hissedecektim, :)
ancak anlamadığım bir nokta soft dökümanı karıştırırken addresleri anlamadım .
Düzeltme ; .h dosyasında arama yaparken gözümden kaçmış şimdi adresler tamam ve anlaşılır biçimdeler,sadece pdf dökümanında biraz karışık biçimde yazıyor bana göre.
Alıntı Yap6.4.1 GPIO port mode register (GPIOx_MODER) (x = A..I
Address offset: 0x00
Reset values:
● 0xA800 0000 for port A
● 0x0000 0280 for port B
● 0x0000 0000 for other ports
gibi şeyler var konu başında ama tam olarak anlamadım GPIOD nin adresi nedir?
long 64 yazarken hata yaptım ve editledim.
Alıntı yaptığın kodda da long 64 görünüyor. Doğrusu Long int in 64 bit oduğu.
GPIOD aşağıdaki gibi stm32f4xx.h içinde tanımlı.
#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
Header dosyada Base adresleri öğrenebilirsin. Buna ilgilendiğin adresin ofsetini eklersen istediğin portun gerçek adresini de bulmuş olursun.
Ofset Adres=Gerçek adres - Base Adres
Bu konuları Gerbay anlatacak.
C de biraz yol katettikten sonra h dosyalarına baksanız daha iyi olur.
Eğer değişkenimiz işaretsiz sayıları yerleştirmek için kullanılacaksa yukarıdaki Delay örneğinde int değişkeni unsigned int yapmamız daha doğru olur.
Alıntı yapılan: mcan - 22 Ekim 2011, 19:53:32
Benim gibi m3 ile deneme yapan arkadaşlar için @Bunalmis in kodunu kopya çekerek m3 için yapmaya çalıştım ve çalıştırdım led yanip sönüyor :)
denemek isteyenler için buraya koyuyorum kod m3 içindir.#include "STM32F10x.h"
void delay(void);
void SystemInit (void)
{ RCC->APB2ENR |= 0x00000016; // GPIOD donanımının clock sinyalini uygulayalım
GPIOC->CRL = 0x33333333; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOC->CRH = 0x33333333; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
}
void delay()
{
unsigned int i;
for(i=0;i<0x80000;i++);
}
int main()
{
while(1)
{
GPIOC->ODR= 0xFFFFFFFF; // Ledler yansin
delay();
GPIOC->ODR= 0x00000000; // Ledler sonsun
delay();
}
}
1. Yeni bir proje oluşturup 32f100RB yi seçtim
2. startup dosyasını eklemesini söyledim
3.bir dosya oluşturup main.c adında kaydedip kodu yapıştırdım.
4.source gurub a ekledim derledim hata verdi. siz nasıl yaptınız ?
Hangi hatayı verdi?
Bua arada bende stm32f103 re var.
Şimdi baktım senin referencemanual farklı bakalım farklı bişey olarak neler var muhtemelen yazmaçlar farklı olabilir mi bakalım.
Yüzeysel biçimde göz gezdirdim pek bir fark yok ,hata nerde verdi ona göre bakalım.
Alıntı Yap@mcan
Eğer CM3 işlemcilerle hiç çalışmadı ve bu kodu CM4 için verilmiş örneklere bakarak kendin uyarladıysan bravo. (kodlarında eksik yada fazla bir şey varmı bilmiyorum fakat bu aşamada önemli değil)
En başta CM3 işlemci ile çalışalım diyenlere hayır bu CM4 kartını kaçırmayalım kursu izledikten sonra kendiniz CM3ü kullanabilirsiniz derken işte bundan bahsediyordum.
bunu bende şimdi deniyodum arkadaş once yapmış
gerçekten ogrettiginiz temel bilgilerle yapmak zor degil
ama hazır fonksiyonlarla ogretseydiniz asla boyle bişey yapamazdık
@mcan tebrikler
bende şimdi eksigimi buldum sayende
ben iki manuel i de açtım yavaştan gidiyordum :)
#error "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
Projeyi oluştururken kullanacağın işlemciyi STM32F10x olarakseçmiş ve startup kodunu ekle demişmiydin?
evet
hatam bu sanırım aynı :D
#error "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
bende herşeyi olması gerektigi gibi yaptım
kodda belki hata olabilr skywalker senin config nasıl ?
#include "stm32f10x.h"
void SystemInit (void)
{
RCC->APB2ENR |= 1 << 4
GPIOC->CRH &= 0xFFFFFF00; // (Ledler bu pinlerde)
GPIOC->CRH |= 0x00000033; // (Ledler bu pinlerde) 11:çıkış modu maksimum 50 mhz
}
int main()
{
while(1)
{
Alıntı yapılan: muhittin_kaplan - 22 Ekim 2011, 20:16:27
1. Yeni bir proje oluşturup 32f100RB yi seçtim
2. startup dosyasını eklemesini söyledim
3.bir dosya oluşturup main.c adında kaydedip kodu yapıştırdım.
4.source gurub a ekledim derledim hata verdi. siz nasıl yaptınız ?
Hocam bende denedim bende de aynı hatayı verdi.
C:\Keil\ARM\INC\ST\STM32F10x\STM32F10x.h(80): error: #35: #error directive: "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
Target not created
Hocam Yoksa 32f100RB değilde başka modelimi secmek lazım.
Hocam derslerde söyle bir ifade var:
Alıntı Yap
1) ARM işlemci Reset ardından sırayla önce, Startup_stm32f4xxx.s dosyasındaki kodları koşturur.
2) SystemInit adındaki fonksiyonu koşturur.
3) main() fonksiyonunu koşturur.
Bu da ikinci led yakıp söndürme uygulamasından bir bölüm:
Alıntı Yap
void Delay()
{
unsigned int i;
for(i=0;i<0x800000;i++);
}
int main()
{
while(1)
{
GPIOD->ODR= 0x0000F000; // Ledler yansin
Delay();
GPIOD->ODR= 0x00000000; // Ledler sonsun
Delay();
}
}
İkinci led yakıp söndürme uygulamasında "main()" fonksiyonundan önce "delay()" fonksiyonu tanımlamışsınız. Yukarıda yazılanlardan yola çıkarak, yazılımsal olarak "main()" fonksiyonundan önce yada sonra herhangi bir fonksiyon tanımlamanın hiç bir önemi yok, önce "main()" fonksiyonu koşturulur diyebilir miyiz?
C:\Keil\ARM\INC\ST\STM32F10x\STM32F10x.h(80): error: #35: #error directive: "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
Target not created
Hatasını arastırdıgımda sunu buldum
#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
#error "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
#endif
Bunun acılımı nedir ?
önce cihazı (mikrodenetleyiciyi) seçin diyor
sayment
main fonksiyonundan onceki kullanılan fonksiyonlar
main içinde yer alan fonksiyonlardır
bunları sonada yazabilirsin fakat busefer tanıtmanız gerekir
karışıklık olmasın diye hocam boyle yazmış
dikkat etmen gereken şu
delay fonksiyonu aslında main içinde kullanılmak üzere yazılmıştır
ben iyi anlatamadım sanırıım
/////////////////
muhittin hocam f100RB yi seçmedinmi sende neden boyle hata veriyor bizde?
Peki bu fonksiyonları "main" fonksiyonundan sonra yazdığımızda tanıtma dediğiniz işlemi nasıl yapacağız ?
evet 32f100RB seçtim
Yanlız kendi örneğinde
system_stm32f10x.c ile nirlikte altında
stm32f10x.h
core_cm3.h
core_cmInstr.h
core_cmFunc.h
system_stm32f10x.h
stdint.h
da ekli. hangi kütüphaneler ki bunlar
bende anlamadım orasını işte :S
Alıntı yapılan: sayment - 22 Ekim 2011, 21:26:46
Peki bu fonksiyonları "main" fonksiyonundan sonra yazdığımızda tanıtma dediğiniz işlemi nasıl yapacağız ?
main fonksiyonu her c programında bulunması gereken özel bir fonksiyondur
main fonksiyonu bir c programının calışmaya başladıgı ana fonksiyondur
programınız derlenirken
mantıken yukarıdan aşağıya doğru derlenir
yukarıdan aşagıya doğru derlenirken
ilk başta karşısına
void Delay()
fonksiyonu cıkar
ve bunu derler
sonra bunu hafızasında tutar
daha sonra delay fonksiyonu kullanıldıgında
bu fonksiyonun yukarıda derlendigini hatırlar ve işleme devam eder
fakat siz delay fonksiyonunu tanımlamadan
delay fonksiyonunu kullanmak isterseniz;
derleyiciniz delay ın nereden geldigini bilemez ve derleme sırasında hata verir yada program çalışmaz(derleyiciye gore degişebilir)
(halbuki siz aşagıda yazdınız belki ama o daha aşagıya gelmediki)
oyüzden fonksiyonlar main den once yazılır
yada şoyle yapılır
mainden once fonksiyonun ismi belirlenip yazılır
daha sonra ise main in altına fonksiyonun içerigi yazılır şu şekilde bi ornek verebiliriz
int Delay(); /////////burada onceden int olarak fonksiyonun ismini tanımlıyoruz ki derleyicimizin aşagıda bunu gordügünde kafası karışmasın artık tanımlanmış bir delay fonksiyonumuz var
int main()
{
while(1)
{
GPIOD->ODR= 0x0000F000; // Ledler yansin
Delay();
GPIOD->ODR= 0x00000000; // Ledler sonsun
Delay();
}
}
void Delay() // ve şimdi fonksiyonumuzu yukarıda tanımladıgımız için mainden sonrada istedigimiz gibi yazabiliriz
{
unsigned int i;
for(i=0;i<0x800000;i++);
}
@gambit1244
Açık ve net anlatımınız için teşekkür ederim. Anladım.
Alıntı yapılan: sayment - 22 Ekim 2011, 21:49:34
@gambit1244
Açık ve net anlatımınız için teşekkür ederim. Anladım.
nedemek .. biraz anlatım ozrlü oldugum için 4 5 kez editledim ama sonunda bişeye benzedi :D
Alıntı yapılan: gambit1244 - 22 Ekim 2011, 21:55:40
nedemek .. biraz anlatım ozrlü oldugum için 4 5 kez editledim ama sonunda bişeye benzedi :D
Estağfirullah gayet açık anlatmışsınız :)
muhittin_kaplan Hocam;
Program basında ki
"STM32F10x.h" kodu yerine
"stm32f10x_lib.h"
ekleyince normal şekilde derleme yapıyor.
Build target 'Target 1'
compiling main.c...
linking...
Program Size: Code=412 RO-data=304 RW-data=0 ZI-data=1632
"Deneme.axf" - 0 Error(s), 0 Warning(s).
ST32F100RB için (stm32 discovery kit) blinky.
Sanırım kütüphaneleri eklemeyince oluyor. Kendi Bilinky aldım üstüne yukarda geçen kodu yapıştırdım.
http://www.4shared.com/file/Fr3BmpqM/Blinky.html
rar dosyasında main.c yok muhittin hocam
siz calıştırdınızmı?
Alıntı yapılan: bunalmis - 21 Ekim 2011, 15:14:25
Aşağıdaki örnek programı Keil ders başlığında son konuda vermiştim.
#include "STM32F4xx.h"
void SystemInit()
{
RCC->AHB1ENR |= 0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislarinı en yuksek hizda kullanacagiz
}
int main()
{
while(1)
{
GPIOD->ODR= 0x0000F000; // Ledler yansin
GPIOD->ODR= 0x00000000; // Ledler sonsun
}
}
C dersleri başladığında göreceğiz fakat şimdiden RCC->AHB1ENR şeklinde satır görürsek bunun, RCC register grubunun bir üyesi olan AHB1ENR registeri anlamına geleceğini bilelim. Yanı sonuçta bu bir register. Bu registeri Rehberde RCC_AHB1ENR olarak bulabilirsiniz.
Deneme kitindeki ledler D portunun 15, 14, 13 ve 12 nolu bitleriyle kontrol ediliyor.
GPIOD->ODR= 0x0000F000; // Ledler yansin
GPIOD->ODR= 0x00000000; // Ledler sonsun
Yukarıdaki kodlar 32 bitlik D portuna 0x0000F000 ardından da 0x00000000 yazıyor.
Yani ilk satır 4 ledin hepsini birden yakıyor, sonraki satırda hepsini birden söndürüyor.
Şimdi SystemInit fonksiyonundaki
RCC->AHB1ENR |= 0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislarinı en yuksek hizda kullanacagiz
satırlarına bakın.
Rehber dokumanda RCC_AHB1ENR, GPIOD_MODER ve GPIOD_OSPEEDR registerlerin anlatıldıkları sayfaları bulun.
Neden bu registerlerin içine yukarıdaki sayıları yüklediğimin cevabını bulmaya çalışın.
Bu çok önemli bir çalışma. Muhakkak uğraşın.
@bunalmış hocam moder ve oseedr komutları çok sade ve güzel bir şekilde anlattınız RCC->AHB1ENR komutu hakkında tam bir açıklama bulamadım yada görmedim aceba bu komut;
clock verip- keserek
seçilen portları aktif-deaktif
seçilen ethernet Rx-Tx aktif- deaktif
seçilen USB girişlerini aktif - deaktif mi ediyor?
rcc konusunu şu sayfada pekiştirebilirsin muhittinkaplan
cortexm3 için yazılmış fakat aradaki farkı ayırt edersin sanırım bir iki rakam dışında mantık aynı
http://coskuntasdemir.net/gomulu-sistemler/stm32-discovery-ile-ilk-adimlar-3.html
Alıntı yapılan: gambit1244 - 22 Ekim 2011, 22:19:38
rar dosyasında main.c yok muhittin hocam
siz calıştırdınızmı?
blinky.c kullanılıyor.
yanlız burada Bunalmış Hocama Bir sorum var
keil ile alakalı başlıkta ini dosya yapmıştık neden ?
(Şu an yükleme yapamıyorum download butonundan. debug yapabiliyorum)
Alıntı yapılan: gambit1244 - 22 Ekim 2011, 22:25:43
rcc konusunu şu sayfada pekiştirebilirsin muhittinkaplan
cortexm3 için yazılmış fakat aradaki farkı ayırt edersin sanırım bir iki rakam dışında mantık aynı
http://coskuntasdemir.net/gomulu-sistemler/stm32-discovery-ile-ilk-adimlar-3.html
RCC yi anladım registerin Reset and Clock Control.
İstediğimiz Çevresel cihaza yada porta clok uygulamamızı sağlıyor.
ARM işlemcide hangi çevre birimini kullanacaksak o çevre biriminin clock sinyalini aktif hale getirmeliyiz.
Biz GPIOD yi kullandığımıza göre GPIOD nin cloğunu açacağız.
Rehber Sayfa 110u açtığında 5.3.10 RCC AHB1 peripheral clock register (RCC_AHB1ENR)
göreceksin. RCC_AHB1 registerinde GPIOD nin cloğunu harekete geçiren bitin 0. değil, 1. değil, 2. değil 3. bit olduğunu göreceksin.
1000 ikili sayısı 8 olduğuna göre RCC_AHB1=8 yazacağız.
Fakat ben kurs boyunca mecbur kalmadıkça decimal yerine hex değer kullanacağım ve RCC_AHB1=0x00000008 yazacağım.
Alıntı yapılan: muhittin_kaplan - 22 Ekim 2011, 22:27:40
blinky.c kullanılıyor.
yanlız burada Bunalmış Hocama Bir sorum var
keil ile alakalı başlıkta ini dosya yapmıştık neden ?
(Şu an yükleme yapamıyorum download butonundan. debug yapabiliyorum)
ini dosyasını Keil derslerinde söylemiştik. Simülasyon için gerekiyordu. Gerçek kartla çalışmaya başlayınca artık o dosya ile işimiz olmayacak.
Yükleme yapamıyorum derken karta mı yükleme yapamıyorsunuz? Eğer öyleyse Keil'de simülasyonla çalışma-kartla çalışma kısmına göz atın.
şöyle hocam
Karta doğrudan yükleme yapıp ardından reset atınca çalışması gerekir diye düşünüyorum. yanlız çalışmıyor.
debug start yaptığımda çalışıyor. sonrasında debugdan çıktığımda da çalıştığını gözlüyorum.
(http://img8.imageshack.us/img8/3558/reister.jpg)
bu resimde de sağ üst köşede görüldüğü gibi ben de öyle anlamıştım sol üsk köşede de ethernet ve usb leri aktif veya pasif etmeye yarıyor galiba
Alıntı Yap
ARM işlemcimizde her biri 16 bit olan 5 adet GPIO bulunmaktadır. Bunlar GPIOA, GPIOB, GPIOC, GPIOE, GPIOE dir.
Derslerde böyle yazmışsınız ancak işlemcinin şemasında 9 tane GPIO gözüküyor. Kafam karıştı ?(Ayrıca iki kez GPIOE yazılmış.)
[IMG]http://img580.imageshack.us/img580/4867/gpio.jpg[/img] (http://imageshack.us/photo/my-images/580/gpio.jpg/)
Uploaded with ImageShack.us (http://imageshack.us)
Alıntı yapılan: M_B - 22 Ekim 2011, 22:09:01
muhittin_kaplan Hocam;
Program basında ki
"STM32F10x.h" kodu yerine
"stm32f10x_lib.h"
ekleyince normal şekilde derleme yapıyor.
Build target 'Target 1'
compiling main.c...
linking...
Program Size: Code=412 RO-data=304 RW-data=0 ZI-data=1632
"Deneme.axf" - 0 Error(s), 0 Warning(s).
evet diğer kütüphanelere gerek kalmadan yeni proj eoluşturup 32f100rb yi seçip kodları yazdığımızda ve #include "stm32f10x_lib.h" eklediğimizde normal oluyor.
ama hala yükleyememe problemini bulamadım sadece debug yaparken yüklüyor.
Alıntı yapılan: sayment - 22 Ekim 2011, 22:46:26
Derslerde böyle yazmışsınız ancak işlemcinin şemasında 9 tane GPIO gözüküyor. Kafam karıştı ?(Ayrıca iki kez GPIOE yazılmış.)
(http://img580.imageshack.us/img580/4867/gpio.jpg) (http://imageshack.us/photo/my-images/580/gpio.jpg/)
Uploaded with ImageShack.us (http://imageshack.us/)
İki kez GPIOE yazdığım kısmı düzelteyim.
Rehber dokumanı çipin bacak sayısından bağımsız bir dokuman. STM32F40x serisine ait. O yüzden o dokumanda F,G,H,I gibi ilave GPIO lar görebilirsiniz.
Fakat bizim STM32F-Discovery kitimizdeki çip 100 bacaklı. Hard Sayfa 39 ve 40 a bakarsanız neden F,G,H,I olmadığını anlayacaksınız.
Anladım teşekkür ederim. O grafiği sadece kullanacağımız işlemciye ait zannediyordum. Seri için olduğunu bilmiyordum.
Debug btonundan programı yüklüyor. Fakat Load butonuna basıldığında program yüklenememesinin sebebi ST-Link le ilgili program parçacığının hatasıymış.
Yapacak bir şey yok. ST düzeltirse düzeltir. (Belki de Keil firması düzeltilmesini istemiyordur)
Selamlar bu istediğimiz biti set edip bize 32 bitlik sayıyı veren ,bitleri tersine çevirebilen vbg basit işler için bir program varmı bildiğiniz?
STM32F407 nin kit üzerindeki diğer donanımlar ile paylaşılan portların tablosu
[IMG]http://img153.imageshack.us/img153/3361/pintablosu.jpg[/img]
Alıntı yapılan: sayment - 22 Ekim 2011, 22:46:26
Derslerde böyle yazmışsınız ancak işlemcinin şemasında 9 tane GPIO gözüküyor. Kafam karıştı ?(Ayrıca iki kez GPIOE yazılmış.)
[IMG]http://img580.imageshack.us/img580/4867/gpio.jpg[/img] (http://imageshack.us/photo/my-images/580/gpio.jpg/)
Uploaded with ImageShack.us (http://imageshack.us)
hocam hard dosyamızın ilk sayfasında da yazdığı gibi hard dosyası
STM32F405xx ve
STM32F407xx çipleri için hazırlnamıştır
bu resimde bizim kullandığımız çipin koç adet çıkış portu olduğu yazıyor
Alıntı yapılan: bunalmis - 22 Ekim 2011, 22:54:59
İki kez GPIOE yazdığım kısmı düzelteyim.
Rehber dokumanı çipin bacak sayısından bağımsız bir dokuman. STM32F40x serisine ait. O yüzden o dokumanda F,G,H,I gibi ilave GPIO lar görebilirsiniz.
Fakat bizim STM32F-Discovery kitimizdeki çip 100 bacaklı. Hard Sayfa 39 ve 40 a bakarsanız neden F,G,H,I olmadığını anlayacaksınız.
Alıntı yapılan: sayment - 22 Ekim 2011, 22:46:26
Derslerde böyle yazmışsınız ancak işlemcinin şemasında 9 tane GPIO gözüküyor. Kafam karıştı ?(Ayrıca iki kez GPIOE yazılmış.)
[IMG]http://img580.imageshack.us/img580/4867/gpio.jpg[/img] (http://imageshack.us/photo/my-images/580/gpio.jpg/)
Uploaded with ImageShack.us (http://imageshack.us)
hocam hard dosyamızın ilk sayfasında da yazdığı gibi hard dosyası
STM32F405xx ve
STM32F407xx çipleri için hazırlnamıştır
[IMG]http://img194.imageshack.us/img194/3711/adszzbr.png[/img] (http://imageshack.us/photo/my-images/194/adszzbr.png/)
Uploaded with ImageShack.us (http://imageshack.us)
bu resimde bizim kullandığımız çipin koç adet çıkış portu olduğu yazıyor
Eline sağlık,
Acaba en başta GPIOE yada GPIOA olacak şekilde alt alta
Örneğin GPIOD için
PD15 Led6 Blue
PD14 Led5 Red
PD13 Led3 Orange
PD12 Led4 Green
PD5 STMP2141STR Out pin
PD4 CS43L32 Reset
Şeklinde text bir tablo da yapabilirmiyiz.
Port bazında olursa bakınca hemen hangi portun hangi pinleri boşta anlarız.
Burada dursun.
Not: Bu arada bizim çipte GPIOH a ait 2 pin varmış.
taneryilmaz (https://www.picproje.org/index.php?action=profile;u=30665) ın verdiği tabloda 82 tane I/O var görünüyor.
82/16 dan 5 tane 16 bitlik GPIO var. Geriye 2 tane kalıyor onlar da GPIOH ın 0 ve1 nolu I/O ları.
Alıntı yapılan: mcan - 22 Ekim 2011, 23:02:10
Selamlar bu istediğimiz biti set edip bize 32 bitlik sayıyı veren ,bitleri tersine çevirebilen vbg basit işler için bir program varmı bildiğiniz?
https://www.picproje.org/index.php/topic,35721.0.html son iletisinde
STM32F407 nin kit üzerindeki diğer donanımlar ile paylaşılan portların listesi
[IMG]http://img263.imageshack.us/img263/4633/pinlistesi.jpg[/img]
harikasın bu ileride çok işimize yarıycak gerçek proje yaparken
hangisi kullanılıyo hangisi boş burdan goruruz
ellerine sağlık
Benim mesaj arada kaldığından pek gören olmadı galiba
MC_Skywalker hocam kendini yorma pinlerin listesini akşam üstü hazırlamıştım
buradan çekebilirsiniz
http://www.4shared.com/file/8MeEKyr8/STM32F4Discovery_Pinouts.html
Edit:hatalı dosya
emeginize sağlık
bişey sormak istiyorum
Ledleri flash eden program ı debug ediyordum
system init içine yazılanları yazıp derleyince debug yapmıyor
system init içini boşaltıp derleyince düzgün çalışıyor neden boyle yapıyor sizde durum ne arkadaşlar??
Aslında debug yapıyor ama while satırlarına takılıyor. Aynı sorunla bende karşılaştım aşağıdaki o satırları yorum satırı yapınca düzeldi. Registerların içeriği değişmesine rağmen o satırları debug modunda atlatamadım. Ama tahminim canlı canlı debug yaparken böyle bir sorun olmaz.
// Programın başı
#include "STM32F4xx.h"
void SystemInit()
{
volatile int i, DBG;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
// while (!(RCC->CR & 0x00020000)); // Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=4 ve Q=14 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
// while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
// while ((RCC->CFGR && 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
int main()
{
while(1)
{
if (GPIOA->IDR & 0x000000001) GPIOD->ODR= 0x0000F000; // Ledler yansin
else GPIOD->ODR= 0x00000000; // Ledler sonsun
}
}
// Programın sonu.
main fonksiyonunun içindeki while(1) yazan satıra breakpoint koyun sonra debug yaparken reset butonuna basıp f5 e basın sonra f11 ile ilerleyin bahsettiğiniz sorun ortadan kalkacaktır. yani o satırları yorum haline getirmenize gerek yok.
Peki hocam while'ın koşulunun sağlanmasına rağmen neden bu şekilde bir takılma söz konusu oluyor, yada sadece bizde mi oldu?
Alıntı yapılan: bunalmis - 22 Ekim 2011, 23:13:55
Acaba en başta GPIOE yada GPIOA olacak şekilde alt alta
Örneğin GPIOD için
PD15 Led6 Blue
PD14 Led5 Red
PD13 Led3 Orange
PD12 Led4 Green
PD5 STMP2141STR Out pin
PD4 CS43L32 Reset
Şeklinde text bir tablo da yapabilirmiyiz.
Port bazında olursa bakınca hemen hangi portun hangi pinleri boşta anlarız.
Burada dursun.
@bunalmış hocam umarım istediğiniz gibi faydalı bir liste olmuştur.
Cortex M4 discovery KİT giriş çıkış pinleri http://www.4shared.com/file/Kc-kRolE/STM32F4DISCOVERY_PinoutsV2.html
usta inş. devreler gelince boyle sorun olmaz :D
gayet iyi gidiyoruz bir aksilik çıkmasın :D
@mozkan87 (https://www.picproje.org/index.php?action=profile;u=14335)
Programı aynen derledim ve kartsız debug ettim. Ne while satırında ne de while icinde herhangi bir takılma yok. F11 ile adım adım gidiyor.
@
bunalmişAlıntı Yapvoid SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
bu satırı neden eklediğinizi kavrayamadım,
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
, burada stabil olana kadar zaten bekletiyoruz ekstradan başlangıçta bir beklemeye neden ihtiyaç duydunuz?
Tamamdır yamak hocam
#include "STM32F10x.h"
void delay(unsigned int);
int ih;
void SystemInit (void)
{
RCC->APB2ENR |= 0x00000016; // GPIOD donanımının clock sinyalini uygulayalım
GPIOC->CRL = 0x33333333; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOC->CRH = 0x33333333;
RCC->CR |= 0x0010000; // HSE aç
while (!(RCC->CR & 0x00020000)) // HSE tamam mı devam mı?
{
GPIOC->ODR |= 0x20; // Ledler yansin
delay(0x90000);
GPIOC->ODR &= 0xFFFFFFDF; // Ledler sonsun
delay(0x40000);
}
RCC->CFGR = 0x001D0000; // PLL ayarla
RCC->CR |= 0x001000000; // PLL aç
while (!(RCC->CR & 0x0002000000)) // PLL Kilitlendi mi?
{
GPIOC->ODR |= 0x200; // Ledler yansin
delay(0x90000);
GPIOC->ODR &= 0xFFFFFDFF; // Ledler sonsun
delay(0x40000);
}
FLASH->ACR = 0x32; // Flash gecikme ayarı
RCC->CFGR = 0x001D0002; // SİNYAL KAYNAĞI PLL
}
{
void delay(unsigned int i)
unsigned int z;
for(z=0;z<i;z++);
}
int main()
{
while(1)
{
GPIOC->ODR= 0x0000FFFF; // Ledler yansin
delay(0x80000);
GPIOC->ODR= 0x00000000; // Ledler sonsun
delay(0x80000);
}
}
C4 tam hızda çalışırda c3 çalışmazmı :) Yine @Bunalmis hocamızın kodundan esinlenerek yazdım,Flash ile alaklı kodu kaldırırsanız hse kaynaklı pll çalışmıyor,sadece hsı,hse yada hsi+pll çalışıyor dökümana göre hsi+pll de çalışmaması lazım ancak orda bir güzellik var hsi yi ikiye bölüp pll ye giriyor o da 36 mhz ediyor sanırım fark azaldıkca flash latency kompanze edebiliyor ,kesin bilmiyorum...Bende debugger olmadığından led kodlarını system_init in içine yazdım.
Alıntı yapılan: taneryilmaz - 23 Ekim 2011, 02:16:55
@bunalmış hocam umarım istediğiniz gibi faydalı bir liste olmuştur.
Cortex M4 discovery KİT giriş çıkış pinleri http://www.4shared.com/file/Kc-kRolE/STM32F4DISCOVERY_PinoutsV2.html
Çok faydalı olmuş @taneryilmaz çok uğraşmışsın anlaşılan, çok sağol...
Hocam ben gece while koşulu sağlanıyor dedim ama şimdi ayrıntılı olarak incelediğimde sağlanmadığını gördüm "HSERDY" ve "PLLRDY" bitleri set edilmiyor. Yani o nedenle sürekli burada takılı kalıyor. Dün gece while(1)'in başına break point koyunca sorunsuz çalıştı ama nedenini anlamaya çalışıyorum. Şu an tekrar takılmaya başladı.
Bunalmıs hocam
Bizde dersleri ilgiyle izliyor, anlamaya gayret ediyoruz ,ben daha once keil kullanmadım ,keil ile ilgili anlatımınızda , Debug.ini dosyasının olusturulmasından bahsetmissiniz, bunu beceremedim ,mumkunse yeniden anlatabilirmisiniz, tesekurler
@NaMcHo
Alıntı Yapbu satırı neden eklediğinizi kavrayamadım,
Bu satırın amacı pll kitlendiğinde bir sorun oluşup işlemeciye program yüklenemezse reset atılıp bu döngü esnasında program yüklenebilmesi için.Benim başıma geldiği için biliyorum. Ben de genelde kullanırım.Yani koruma amaçlı bi satır. İşlemci kodları çalıştırmaya başlar başlamaz her ihtimale karşı pll ayarlarının yapılmaması lazım.
Birde pll ayarlamalarımızı yaparken su sekilde hesaplamıssınız
// 8 Mhz Xtal OSC calisti ama biz hala 16Mhz RC Osc ile calisiyoruz.
// Simdi de PLL katsayilarini ayarlayalim. M=8, N=336, P=2 ve Q=7 degerlerini ders notlarinda hesaplamistik.
// Rehber Sayfa 95 de PLLCFGR register aciklamalarina gore yerlestirirsek
RCC->PLLCFGR = 0x07405408;
// PLL calismaya baslasin (Rehber Sayfa 95)
ben hesaplayınca = 0x07425408 cıkıyor acaba yanlısmı hesaplıyorum
Evet sizin hesaplamanızda hata var sizin hesaba göre baktığımız zaman 17. bitin 1 olması gerkiyor ama o zaman P=6 oluyor.
0000 0111 0100 0010 0101 0100 0000 1000
0 7 4 2 5 4 0 8
burada p degeri 16. ve 17. bitler degilmi
p=2 icin 17. bitin 2 olması gerkmezmi
Alıntı yapılan: stlg - 23 Ekim 2011, 12:38:33
....Debug.ini dosyasının olusturulmasından bahsetmissiniz, bunu beceremedim ,mumkunse yeniden anlatabilirmisiniz
Notepadde asagidaki satirlari yazip Debug.ini adiyla saklayin. (Yalniz Debug.ini.txt olmasin)
FUNC void Setup (void) {
SP = _RDWORD(0x08000000); // Setup Stack Pointer
PC = _RDWORD(0x08000004); // Setup Program Counter
xPSR = 0x01000000; // Set flag "T"
}
load %L incremental
MAP 0x00000000, 0x000000FF READ WRITE;
MAP 0x40000000, 0x400FFFFF READ WRITE;
_WDWORD(0x00000000,_RDWORD(0x08000000));
_WDWORD(0x00000004,_RDWORD(0x08000004));
Setup();
Alıntı yapılan: stlg - 23 Ekim 2011, 14:01:39
0000 0111 0100 0010 0101 0100 0000 1000
0 7 4 2 5 4 0 8
burada p degeri 16. ve 17. bitler değilmi
p=2 icin 17. bitin 2 olması gerkmezmi
P'nin 2 olması için 00 olması gerektiği yazılmış rehberin 96. sayfasında.
(http://imageshack.us/photo/my-images/685/adszpft.jpg/)
Simdi anladım tesekurler
for (i=0;i<0x00100000;i++); // (Internal RC osc oturma ve kurtarma)
Alıntı Yapbu satırı neden eklediğinizi kavrayamadım,
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
Alıntı YapBurada stabil olana kadar zaten bekletiyoruz ekstradan başlangıçta bir beklemeye neden ihtiyaç duydunuz?
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
Yukarıdaki yada benzeri bir şartı bekleyen rutinlerde, yazım yada mantık hatası yaptığımızı varsay. (Pekala çok basit, bir satırlık kod yazarken bile hata yapabiliriz.)
Karta voltaj verdiğinizde CPU hurra kosmaya baslar ve mikrosaniyeler içinde son derece hayati önemi olan SystemInit kodlarınızın içine dalar.
Eğer program geliştirme aşamasında çok tehlikeli hatalı kodlar yazdıysanız bunun sonucunda, Jtag portu gibi kritik portları yasaklamış olabilir, CPU'yu içinden çıkamayacağı sonsuz döngülere sokabilirsiniz.
Böyle durumlarda CPUnun elinden tutup düştüğü bataklıktan çıkartmak gerekir. Eğer JTAG portu devre dışı kaldıysa (Bu iki üç satırlık koda bakar) çip çöpe gidecek demektir.
(Yada özel yazılımları işletmek gerekir)
Yukarıdaki senaryo STM çipimiz için ne kadar geçerlidir bilemiyorum. Fakat TI çiplerde bu senaryo tamı tamına aynen yaşanabiliyor.
Bu nedenle en başa bir geçikme programı ekliyorum (Benim tercihim). Bu geçikme sayesinde CPU JTAG'ı iptal edecek yanlıs kodları işletemeden JTAG'dan müdahale edebiliyoruz.
En başa konan gecikme rutinini, tüm kodlarım mükemmel hale geldiğinde kaldırıp atıyorum.
Ders notlarını sürekli olarak editleyeceğimi söylemiştim. Nitekim tek bir virgül için bile editliyorum.
Ancak ders notlarından alıntı yapıp şu an okuduğunuz başlık altına kopyalanan kodlar, editlenmiş son ders notunun daha önceki hali olabiliyor.
Örneğin ders notlarında daha önceleri hatalı olup daha sonra
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
olarak düzelttiğim satırlar, buradaki tartışmalarda hatalı haliyle alıntılanmış olabiliyor. (mozkan87 (https://www.picproje.org/index.php?action=profile;u=14335) nin mesajı)
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=4 ve Q=14 yapalim
Bu nedenle kafanız karışırsa ders notlarının güncel haline göz atmalısınız.
Hocam notları PDF haline getirip yayınlasak?Ne düşünürsünüz bu konuda ?
İsteyen pdf hazırlasın fakat pdf, kurs bittiğinde hazırlanırsa daha az hatalı olacaktır.
Rehber ve Hard yetiyor zira pdflerden artık gına geldi. :)
ben hazırlıyorudum değişmeler olması nedeniyle ara verdim
Ornegin Rehber 148 sayfada GPIOx_MODER register açıklamalarında Moder 15,14,13,12 ile ilgili bitlere bakın. (Bit no:31-30, 29-28, 27-26 ve 25-24)
Bunların her biri iki bit tanımlıdır ve 2 bit 4 ayrı durumu belirler. Bunlar;
MODERy[1:0]: Port x configuration bits (y = 0..15)
These bits are written by software to configure the I/O direction mode.
00: Input (reset state)
01: General purpose output mode
10: Alternate function mode
11: Analog mode
Eğer biz GPIO'nun 15,14,13,12 pinlerini output tanımlayacaksak yukarıdaki bilgiler ışığında bu bitleri 01 yaparız.
--------------------------------------
Fakat, yazım ve okunurluk kolaylığı açısından bazen bazi header dosyalarinda registerlerin her bir biti tanimlanmistir.
Hatta Rehber dokumanin register aciklamalari, header dosyada C formatinda işlenmiştir.
Örneğin
Moder15_Output aslında 0x40000000
Moder14_Output aslında 0x10000000
Moder13_Output aslında 0x04000000
Moder12_Output aslında 0x01000000 olarak hazır tanımlıdır.
Tanımlı değilse de zamanınız varsa kendiniz tek tek tanımlarsınız
Bu durumda Rehber dokumanına aşırı bağımlı GPIOD->MODER = 0x55000000; yazımı yerine
GPIOD->MODER = Moder15_Output | Moder14_Output | Moder13_Output | Moder12_Output; yazabilirsiniz. Bu aslında
GPIOD->MODER = 0x40000000 | 0x10000000 | 0x04000000 | 0x01000000; yazımı demektir ve GPIOD->MODER = 0x55000000; ile tamamen eşanlamlı olur.
GPIOD->MODER = Moder15_Output | Moder14_Output | Moder13_Output | Moder12_Output; yazımını okuduğunuzda Rehbere bakmadan 15, 14,13 ve 12 nin output tanımlı olduğu anlaşılır.
Fakat GPIOD->MODER = 0x55000000; yazımını okuduğunuzda amacı anlayamaz ve Rehber dokumanında GPIOD_MODER in anlatıldığı 148. sayfaya bakmanız gerekir.
--------------------------------------
Header dosyada her bir GPIO biti için ayrı ayrı MODER tanımı yapmak yerine
MODER_INP=0;
MODER_OUT=1;
MODER_ALT=2;
MODER_ANG=3;
benzeri bir tanım yapılıp (Define ile)
Ardından GPIOD->MODER = 0x55000000; yazmak yerine
GPIOD->MODER= MODER_OUT<<30 | MODER_OUT<<28 | MODER_OUT<<26 | MODER_OUT<<24; yazım şekli, anlaşılırlığı biraz olsun artırır.
--------------------------------------
Bir süre sonra biz de bu şekilde kod yazmaya başlayacağız. Fakat şu anda ARM işlemcilerde registerlerin felsefesini öğrenmekteyiz ve bir süre daha hex rakamlarla yolumuza devam etmemiz gerekiyor.
Eğer bu tip tanımların olduğu header dosya bulursanız (bende yok) elimizin altında bekletelim ve bir süre sonra programlarımızda bu header dosyayı kullanalım.
(TI'ın ilgili header dosyaları bu tip tanımlamalardan dolayı o kadar uzundu ki yüzlerce Kb tutuyordu. Fakat programlar hazır bu tanımlardan dolayı çok anlaşılır ve kolay yazılabiliyordu)
STM32F407 çipimize yakında interrupt kodu yazacağız. Cortex M4 NVIC dokumanını bulan varmı?
Interrupt dersini de bitirdiğimizde PIC işlemciyi, register programlama yoluyla kullanan tüm arkadaşlar ARM çipimizi sanki PIC işlemci kullanıyormuşcasına
kullanmaya başlayabilecekler.
Bu durumda PIC'i asm ve/veya Hitech ile kullananlar ARM işlemciye çok çabuk adapte olacaklar. Fakat hazır fonksiyonları (Basic, CCS) kullanan arkadaşları da unutmayacağız.
hocam aradığımız dosya bu olabilirmi?
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0439b/DDI0439B_cortex_m4_r0p0_trm.pdf
Daha detayli bir dokuman yokmu acaba. Bu dokuman bana biraz soguk geldi.
CM4 NVIC ile CM3 NIVIC farklimidir acaba? Bunu arastiran oldumu? Bana sanki nerdeyse tipa tip aynidir gibi geliyor.
hocam bu hard dökümanının olduğu linki buraya atabilirmisiniz masa üstünü temizlerken sildim şimdi ilk verdiğiniz linki açamadım
https://www.picproje.org/index.php/topic,35721.0.html (https://www.picproje.org/index.php/topic,35721.0.html)
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439b/Cihfihfe.html
bu sayfada aradığımız konuda(nvic) birden fazla döküman onun için çok zayıf görünmüş olabilirmi konumuzla alakalı 5 döküman var
Alıntı yapılan: bunalmis - 23 Ekim 2011, 19:33:20
Daha detayli bir dokuman yokmu acaba. Bu dokuman bana biraz soguk geldi.
CM4 NVIC ile CM3 NIVIC farklimidir acaba? Bunu arastiran oldumu? Bana sanki nerdeyse tipa tip aynidir gibi geliyor.
benzer yapıya sahip diye biliyorum,
hatta çipimiz STM32F2 serisinden geliştirilmiş galiba CPUID gibi konularda bu serinin bilgilerinin unutulduğu erratadan anlaşılıyor.
araştırmak istediğiniz konu ne hocam belki Peripheral driverlarına bakarakta çıkartabiliriz
NVIC registerlerinde, interruptlara izin verme, yasaklama, öncelik tanımlama gibi bilgilerin bit bazında anlatıldığı dokümanı arıyorum.
Örnek programlar başlığında Timer7 ile yanıp sönen led programını vermiştim. Bu programı interrupt ile çalışan şekle dönüştüreceğim.
core_cm4.h da yapılan NVIC structure tanımları hiç hoşuma gitmedi. Değiştirmeyi önereceğim fakat bu kezde ST nin kendi örnekleri sorun çıkartacak.
Mecburen mevcut header tanımlamalarına sadık kalacağız.
ST nin driverlarında misc.h ve misc.c içinde nvic için tanımlamalar barındırıyor bir bakabilir misiniz hocam, yola çıkacak bilgiler verebilir
Nerede bunlar? Daha önce ST ile hiç çalışmadım ne nerde bilmiyorum.
http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4_dsp_stdperiph_lib.zip
Libraries\STM32F4xx_StdPeriph_Driver içinde .c ler src, .h lar inc klasörü içerisinde
=================================================================
Aslında temel programların anlaşılmasından sonra bu driverlar üzerinden gidebiliriz
sonuçta aynı ayarları yapıyoruz ama bu driverlar sayesinde daha düzenli/anlaşılır duruyor
=================================================================
ayrıca
http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4discovery_fw.zip
adresinde discovery'nin üzerinde gelen yazılımın kodları harici USB HOST-Device-OTG kütüphaneleri de mevcut
ve örnekleri de içine belki işinizi kolaylaştırır bunalmis hocam
Interrupt kodlarını yazdım fakat bunun için TI dokumanlarından yararlandım. Bu böyle olmayacak muhakkak NVIC ın registerlerini bit bit anlatan dokümanı bulmalıyız.
https://www.picproje.org/index.php/topic,35896.msg256761/topicseen.html#msg256761 (https://www.picproje.org/index.php/topic,35896.msg256761/topicseen.html#msg256761)
Görüldüğü gibi NVIC da ilgili interrupta izin vermek yeterli. Örneğimizde sadece tek interrupt olduğundan öncelik tanımlamasına gerek yok.
Reference Manualde verilen Interrupt and exception vectors tablosunda (sf:195) ilk sütun position diyor anladığım kadarıyla burası yazmaçtaki yeri
Piority sütunuda Piority adreslerindeki yerini gösteriyor
ST tabloları alıştığımız yatay pozisyon yerine dikey yapıyor galiba :o
Alıntı yapılan: bunalmis - 23 Ekim 2011, 23:33:31
Interrupt kodlarını yazdım fakat bunun için TI dokumanlarından yararlandım. Bu böyle olmayacak muhakkak NVIC ın registerlerini bit bit anlatan dokümanı bulmalıyız.
https://www.picproje.org/index.php/topic,35896.msg256761/topicseen.html#msg256761 (https://www.picproje.org/index.php/topic,35896.msg256761/topicseen.html#msg256761)
Görüldüğü gibi NVIC da ilgili interrupta izin vermek yeterli. Örneğimizde sadece tek interrupt olduğundan öncelik tanımlamasına gerek yok.
Bunalmiş hocam bende cm3 için yazmaya çalışıyorum ve bu dökümana bakıyorum acaba aradığınız bilgi sayfa 119 dan başlayan bilgilermi ?
Döküman bu ;
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf)
Evet bu ama ne olur ne olmaz diye bunun 1 numara buyugu lazim. Fakat CM4 ile CM3 de NVIC'in ayni olma ihtimali cok yuksek. Asil aradigimiz dokumani buluncaya kadar http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf) bunu kullanalim. Sagolasin.
O dosyadaki bilgiler m4 için burada mevcut bunu mu arıyorduk hocam?
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CIHIGCIF.html
Alıntı yapılan: ErsinErce - 24 Ekim 2011, 01:09:35
O dosyadaki bilgiler m4 için burada mevcut bunu mu arıyorduk hocam?
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CIHIGCIF.html (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CIHIGCIF.html)
Evet bu, bunu daha önce gorduysem de register anlatımlarındaki register kutucuklarını begenmediğimden önemsememişimdir.
Tamam bu durumda NVIC doküman sıkıntımız kalmadı.
bende bit bit anlatıma sahip olsun dediğinizden es geçmiştim.
#include "STM32F10x.h"
void delay(unsigned int);
static int ih;
int zg;
void TIM7_IRQHandler(void)
{
if (ih == 0)
ih=1;
else
ih=0;
TIM7->SR = 0x0;
zg = TIM7->SR;
}
void SystemInit (void)
{
RCC->APB2ENR |= 0x00000016; // GPIOD donanımının clock sinyalini uygulayalım
GPIOC->CRL = 0x33333333; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOC->CRH = 0x33333333;
RCC->CR |= 0x0010000; // HSE ON
RCC->CFGR = 0x001D0000; // PLL ayarla
RCC->CR |= 0x001000000; // PLL aç
FLASH->ACR = 0x32; // Flash gecikme ayarı
RCC->CFGR = 0x001D0702; // SİNYAL KAYNAĞI PLL APB1 HCLK/16
RCC->APB1ENR |= 0x00000020; //Timer7 ye clock verelim
TIM7->DIER = 0x1;
TIM7->PSC = 0x157; //182=B6 182*5= H393
TIM7->ARR = 0xFFFF;
TIM7->CR1 = 0x85;
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
}
void delay(unsigned int i)
{ unsigned int z;
for(z=0;z<i;z++);
}
int main()
{
while(1)
{
if(ih ==0)
GPIOC->ODR= 0x20; // Ledler yansin
else
GPIOC->ODR= 0x200; // Ledler yansin
delay(0x80000);
GPIOC->ODR= 0x00000000; // Ledler sonsun
delay(0x80000);
}
}
CM3 için timer7 yi kullanan interrupt örneği ,sizin kodlar aynen çalışıyor ,anlamadığım nokta neden zg = TIM7->SR; gibi bir kodla bu biti okuyoruz? Okumadan önce sıfırlamıştık ,kodu kendim yazarken program istediğim gibi çalışmıyordu sizin koddan bu kısmı aynen kopyaladım ve şimdi çalışıyor olay ne anlamadım gece gece :)
Şu ana kadar neler yaptık;
CPU clock kaynağını kullanmayı,
GPIO portunu I/O olarak kullanmayı,
GPIO yu alternatif fonksiyon amaçlı kullanmayı,
Timer kullanmayı,
Interrupt kullanmayı
Çok basit anlamda da olsa gördük.
Kartlarınız geldiğinde bunları bizzat deneme şansınız olacak.
Şu anda deneme yapmamız gereken DMA, UART, I2C konuları var. Aslında çok konu var.
Fakat C dersleri geride kaldı. Ayrıca kursa katılanlar konuları takip ediyorlarmı etmiyorlarmı, anlıyorlarmı anlamıyorlarmı hiç fikrim yok.
Öte yandan ARM programlamayı, registerlere kuru sayılar yükleyerek yazmak gördüğünüz gibi mümkün hatta çok kısa kodlarla işler yütülebiliyor fakat okunurluğu yok.
Bundan sonrası için nasıl yola devam edelim?
Biraz dinlenelim mi?
arkadaşlar AHB hız ayarlamasını çalışıyordumda kafama takıldı
(http://img546.imageshack.us/img546/6526/ekrntsth.jpg)
burda 8 9. bitler rezerve
0xx: AHB clock not divided
100: AHB clock divided by 2
şimdi biz
AHB yi RCC->CFGR |= 0x00009400; olarak ayarladıgımızda
AHB ye 4 yazmış oluyoruz
0xx olanımı yoksa
100 olan yani 2 ye bölenimi seçmiş oluyoruz
Mesela
Bits 2y:2y+1 MODERy[1:0]: Port x configuration bits (y = 0..15)
Register ayarlamalarında sıkca gecen bu ifadelerin ne anlama geldigini biraz anlatabilirmisiniz
Alıntı yapılan: stlg - 24 Ekim 2011, 01:48:54
Mesela
Bits 2y:2y+1 MODERy[1:0]: Port x configuration bits (y = 0..15)
Register ayarlamalarında sıkca gecen bu ifadelerin ne anlama geldigini biraz anlatabilirmisiniz
Burada diyorki mesela y=6 olsun Port x için 6.pin ile alakalı Moder MODER6 dır. Moder 6 ise 2*6= 12. ile 2*6+1 = 13. bitler tarafından kontrol edilir.
Alıntı yapılan: stlg - 24 Ekim 2011, 01:48:54
Mesela
Bits 2y:2y+1 MODERy[1:0]: Port x configuration bits (y = 0..15)
Register ayarlamalarında sıkca gecen bu ifadelerin ne anlama geldigini biraz anlatabilirmisiniz
Gereksiz yere kafa karıştırmış.
y gördüğün yere 0....15 arasında sayılar koyabilirsin.
2y ve 2y+1 ile, seçtiğin y'ye ait pinin registerdeki bit numaralarını bulabiliyorsun.
Mesela y=1 için yani GPIOnun 1'ci pinin ayarlamasını MODER registerinde 2*1=2 ve 2*1+1=3 nolu bitler yapıyor.
0.pin 0,1
1.pin 2,3
3.pin 4.5 gibi
Adam bunu formülize etmiş Bits 2y:2y+1 MODERy[1:0]: Port x configuration bits (y = 0..15) demiş.
Bu vektör tablo olayıda neyin nesi? Kesme olduğu zaman dallanacağı adresi mi değiştirmeye yarıyor?
Alıntı yapılan: mcan - 24 Ekim 2011, 01:30:45
....CM3 için timer7 yi kullanan interrupt örneği ,sizin kodlar aynen çalışıyor ,anlamadığım nokta neden zg = TIM7->SR; gibi bir kodla bu biti okuyoruz? Okumadan önce sıfırlamıştık ,kodu kendim yazarken program istediğim gibi çalışmıyordu sizin koddan bu kısmı aynen kopyaladım ve şimdi çalışıyor olay ne anlamadım gece gece :)
Software can read as well as clear this bit by writing 0.
Bu cümlenin tam olarak Türkçe karşılığı nedir?
Software bu biti okuyabilir, sifir yazarak bu biti silebilir.
reserve bitlere ne yazarsanız farketmez sonuçta hep aynı değeri okursunuz
atama yaparken o bitleri es geçme gibi bir durum söz konusu değil
0x00009400 ile 8 e bölünüyor
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0
bunalmis hocanın dersinde verdiği program ile daha net görebilirsin
ayrıca
TIMx_SR rc_w0 tipinde bir yazmaçmış ilk cümle tam türkçeye nasıl çevrilir tıkandım
(rc_w0: Software can read as well as clear this bit by writing 0. Writing '1' has no effect on the bit value.)
Alıntı yapılan: mcan - 24 Ekim 2011, 02:04:19
Bu vektör tablo olayıda neyin nesi? Kesme olduğu zaman dallanacağı adresi mi değiştirmeye yarıyor?
Interrupt oluştuğunda ve kabul edildiğinde İşlemci hangi interrupt programını koşturacağını bu vektörden öğreniyor.
Bu tablo hazır. Size düşen tek şey, interruptın numarasından yada adından yola çıkıp Startup dosyasında vektor bölümündeki label adını öğrenmek ve C programınızda yazacağınız fonksiyona bu adı vermek.
Alıntı yapılan: bunalmis - 24 Ekim 2011, 02:05:23
Software can read as well as clear this bit by writing 0.
Bu cümlenin tam olarak Türkçe karşılığı nedir?
İşin açığı ben o cümleyi tam anlamadım, anladığım yazılım bu biti okumanın yanısıra 0 yazarak silebilir de.Yani hem okuyabiliriz yada istersek 0 yazıp silebiliriz.
Eğer anlamı "yazılım o biti 0 yazarak silmenin yanı sıra okuyarak da silebilir." ise neden iki kere sildik?
http://www.eksisozluk.com/show.asp?t=as%20well%20as
dediğine göre okuyarak da 0 yazarak da temizleyebiliyormuşuz
Alıntı yapılan: ErsinErce - 24 Ekim 2011, 02:07:42
reserve bitlere ne yazarsanız farketmez ....
Bu çok tehlikeli.
Normalde yapılması gereken (fakat şu ana kadar verdiğim örnek programlarda yapmadım) reserve bitleri registerden okuyup aynen geri yazmaktır.
Çünkü bu rezerv bitler, çipin silicon revizyona girmesi ardından başka amaçlarla kullanılabilir. Bu durumda fi tarihinde yazdığınız kod ileri tarihlerde satın alacağınız çiplere yüklendiğinde çalışmayabilir yada abuk sabuk şeyler yapabilir.
Bu nedenle bir registere doğrudan veri yüklemek yerine,
1. Registeri oku
2. Değiştirilmesi gereken bit haricindeki bitleri maskele
3. Değişmesi gereken bitleri yerine koy
4. Sonucu registere yaz olmalıdır.
Bunu da bu vesileyle hatırlatayım. Dokümanlarda bu uyarı sık sık yapılır.
Timer interrupt kodlarımı yazarken o cümleyi aynen sizin anladığınız gibi anladım ve o anlama göre yazdım ve kodlarım çalışmadı.
Kodları debug ederek, registerin gerçekten 0 yüklenince silindiğini fakat sadece okunursa silinmediğini gördüm.
Bu durumda cümleyi yanlış tercüme ettiğimi yada burada BUG olduğunu varsaydım hem sildim hem okudum kod çalıştı.
Once silip sonra okumak yerine, önce okuyup sonra silmenin de işe yaramadığını gördüm.
Bu durumda o cümlenin Türkçesi anladığımız gibi olmayabilir. Belki de çipte bir BUG vardır.
Ilerleyen tarihlerde isin asli ortaya cikti. Interruprt rutininde bu biti sifirlamaya kalksarsak ve hemen ardindan da interrupt rutinininden cikarsak
sistem bir daha int rutinine girmiyor cunku aslinda bir silinmemis oluyor.
Silme isleminden sonra bir kac tane nop eklenmeli yada silme komutu int rutinine girer girmez isletilmeli. int rutinindeki diger kodlar isletilirken TIM7_SR registerindeki bitimiz silinme firsati taninmis oluyor. Sorun AHP frekansi ile CPU frekansinin ayni olmamasi yada pipeline mekanizmasindan kaynaklanan dusuk seviye olusan bir sorun.
Hatamı düzelttim, bunu bilmek iyi oldu teşekkür ederim
bunalmis hocam ayrıca C dersleri başlamadan Hard_Fault gibi durumlar neden oluşur, nasıl aşılır, neler yapılmamalı
bunlardan bahsedebilirseniz çok iyi olur bende o konuya takılmış durumdayım,
hem programlama sırasında da bize yol gösterir diye düşünüyorum, yoksa sonraki konular mı bu durumlar?
Silinmeme durumu sadece simülatörde mi oluyor hocam yoksa kartta da aynı şekilde mi?
Evet fault ve exceptionları sonraki konularda göreceğiz.
TI dan kolayca oluşturabildiğim exceptionlar STM32F407 de oluşmuyor. (Şu ana kadar izlenimlerime göre TI mı ST mi derseniz cevabım kesinlikle TI.)
Alıntı YapSilinmeme durumu sadece simülatörde mi oluyor hocam yoksa kartta da aynı şekilde mi?
Simülatörü kullanmıyorum, kodları karta yüklüyor ve karttan debug ediyorum.
Yanlış anlaşılmasın, eğer TIM7->SR set ise
TIM7->SR=0; Bu komut gerçekten de TIM7_SR yi siliyor. Fakat aşağıdaki satır yazılmazsa bir daha interrupta girmiyor.
i=TIM7->SR;
Eğer TIM7->SR set ise
i=TIM7->SR; komutu flağı silmiyor. Tekrar okursam hala set olduğunu görüyorum.
Alıntı yapılan: ErsinErce - 24 Ekim 2011, 02:28:34
Hatamı düzelttim, bunu bilmek iyi oldu teşekkür ederim
bunalmis hocam ayrıca C dersleri başlamadan Hard_Fault gibi durumlar neden oluşur, nasıl aşılır, neler yapılmamalı
bunlardan bahsedebilirseniz çok iyi olur bende o konuya takılmış durumdayım,
hem programlama sırasında da bize yol gösterir diye düşünüyorum, yoksa sonraki konular mı bu durumlar?
Silinmeme durumu sadece simülatörde mi oluyor hocam yoksa kartta da aynı şekilde mi?
Ben bendeki cm3 kartı ile deniyorum ve çalışmıyor.
Daha yukarıdaki mesajında da çalıştığını söylemiştin.
Alıntı yapılan: bunalmis - 24 Ekim 2011, 02:37:39
Daha yukarıdaki mesajında da çalıştığını söylemiştin.
Yukarıda verdiğim kod çalışıyor ancak "okuma" yada "sıfır yazma" satırını kaldırırsam çalışmıyor.
Sizin koddaki gibi okuma yapınca çalışıyor ama normalde sadece sıfır yazınca çalışmıyor.
Arkadaş da sanırım gerçekde okuma yapmadan sadece sıfır yazarak siliniyor mu diye sordu. ,Bu sebeple gerçek kart üzerinde okuma yapmadan çalışmıyor demek istedim.
Ayrıca hocam şunu sizdeki kartta denermisiniz
TIM7->SR = 0x0;
TIM7->SR = 0x0;
TIM7->SR = 0x0;
Üç kere silince okuma yapmaya gerek kalmadan kod aynen çalışıyor .okuma kodunu silip yerine 3 kere TIM7->SR = 0x0; kodunu yazdım şimdi aynı biçimde çalışıyor.Acaba timer7 nin saat frekansı kodların koştuğu frekansdan farklı diye bişeylermi oluyor? Yada "At overflow or underflow regarding the repetition cou..." diyor dökümanda , acaba biz interrupta girdiğmizde Underflow olayı da mı gerçekleşiyor?
Sizin frekans daha yüksek belki 5-6 kere yinelemeniz gerekeblir bende 3 kere yetti.
Peş peşe 3 kez silmek işe yaramadı. CPU frekansını yarı yarıya düşürüp denedim gene olmadı.
Alıntı yapılan: bunalmis - 24 Ekim 2011, 03:01:14
Peş peşe 3 kez silmek işe yaramadı. CPU frekansını yarı yarıya düşürüp denedim gene olmadı.
Ben ahb prescaler değerini düşürdüm yani timer7 nin clock frekansını arttırdım şimdi 1 kodla siliyor. Okuma yapmadan sadece sıfır yazınca siliniyor.
Frekanslarla alakalı bir iş var ama ne ?Eger siz sistem frekansini dusurdunuz ve bisey degismedi ise, olay cpu frekansi ile 'bus-timer' frekansi arasindaki orandan kaynaklaniyor olabilir.
"100: AHB clock divided by 2" olarak ayarladım.
CPU frekansını yarıyarıya düşürünce mecburen hem AHB hem de APB frekansları yarıya düştü. APB frekansını artıramam cunku en yuksek degerde çalışıyorum.
Hem AHB hemde APB yi ayrı ayrı düşürmem de işe yaramadı.
Olayın aslı neyse bir şekilde çıkar. Bana BUG gibi geldi.
Alıntı yapılan: bunalmis - 24 Ekim 2011, 01:31:33
Şu ana kadar neler yaptık;
CPU clock kaynağını kullanmayı,
GPIO portunu I/O olarak kullanmayı,
GPIO yu alternatif fonksiyon amaçlı kullanmayı,
Timer kullanmayı,
Interrupt kullanmayı
Çok basit anlamda da olsa gördük.
Kartlarınız geldiğinde bunları bizzat deneme şansınız olacak.
Şu anda deneme yapmamız gereken DMA, UART, I2C konuları var. Aslında çok konu var.
Fakat C dersleri geride kaldı. Ayrıca kursa katılanlar konuları takip ediyorlarmı etmiyorlarmı, anlıyorlarmı anlamıyorlarmı hiç fikrim yok.
Öte yandan ARM programlamayı, registerlere kuru sayılar yükleyerek yazmak gördüğünüz gibi mümkün hatta çok kısa kodlarla işler yütülebiliyor fakat okunurluğu yok.
Bundan sonrası için nasıl yola devam edelim?
Biraz dinlenelim mi?
Hocam ben kendi payıma dersleri takip ediyorum ve etmekte de zorlanıyorum.Başlangıç da C dersleri ile başlayıp temelden girileceğinden bahsedilmişti.
Ama ARM serisine yabancı olmayan ve C bilgisi iyi olan arkadaşlar bodoslama daldılar konuya..Bunu yadırgamıyorum gayet normal.Amacım eleştirmek de değil zaten.
Lakin aşağıdaki topic bomboş kaldı.
https://www.picproje.org/index.php/topic,35720.0.html (https://www.picproje.org/index.php/topic,35720.0.html)
Sabırla sıranın benim gibilere gelmesini bekliyorum. :-[
@bunalmis
Kısmen konu dışı olacak ama 32 Bit Hesaplayici programınızda, sonuç bölümünü seçilip kopyalayacak şekilde yapmanız mümkün mü? Demek istediğim, ben ilgili bit'leri kutucuklara tıklayarak set ediyorum. İşim bittikten sonra sol altta hex karşılığı görmeme rağmen seçemiyorum, dolayısıyla kopyalayamıyorum.
O ozellik zaten var. Hic kopyalamaya calismadan paste demeyi denedinmi?
Alıntı yapılan: bunalmis - 21 Ekim 2011, 15:14:25
Aşağıdaki örnek programı Keil ders başlığında son konuda vermiştim.
#include "STM32F4xx.h"
void SystemInit()
{
RCC->AHB1ENR |= 0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislarinı en yuksek hizda kullanacagiz
}
int main()
{
while(1)
{
GPIOD->ODR= 0x0000F000; // Ledler yansin
GPIOD->ODR= 0x00000000; // Ledler sonsun
}
}
C dersleri başladığında göreceğiz fakat şimdiden RCC->AHB1ENR şeklinde satır görürsek bunun, RCC register grubunun bir üyesi olan AHB1ENR registeri anlamına geleceğini bilelim. Yanı sonuçta bu bir register. Bu registeri Rehberde RCC_AHB1ENR olarak bulabilirsiniz.
Deneme kitindeki ledler D portunun 15, 14, 13 ve 12 nolu bitleriyle kontrol ediliyor.
GPIOD->ODR= 0x0000F000; // Ledler yansin
GPIOD->ODR= 0x00000000; // Ledler sonsun
Yukarıdaki kodlar 32 bitlik D portuna 0x0000F000 ardından da 0x00000000 yazıyor.
Yani ilk satır 4 ledin hepsini birden yakıyor, sonraki satırda hepsini birden söndürüyor.
Şimdi SystemInit fonksiyonundaki
RCC->AHB1ENR |= 0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislarinı en yuksek hizda kullanacagiz
satırlarına bakın.
Rehber dokumanda RCC_AHB1ENR, GPIOD_MODER ve GPIOD_OSPEEDR registerlerin anlatıldıkları sayfaları bulun.
Neden bu registerlerin içine yukarıdaki sayıları yüklediğimin cevabını bulmaya çalışın.
Bu çok önemli bir çalışma. Muhakkak uğraşın.
iş yüzünden çok nadir bakabiliyorum ve dediğiniz komutlara baktım ve şunları çıkardım.
AHB1ENR : reginin 3.biti d portunun clok unu aktif ediyor.
GPIOD->MODER : d portu 16 bacaklı, 32biti 2şerli gruplandırarak 1 port için 4 farklı durum belirlemesi yapılailiyor, rehberde
yazana göre 01 verince çıkış olarak ayarlıyoruz, bu sebepten 0x55000000 sayısını giriyoruz.
GPIOD->OSPEEDR : aynı mantıkla 1 çıkış için 4 farklı çalışma hızı belirleyebiliyoruz 11 max hiz çalıştırmak için.
hesapladığımızda 0xFFFFFFFF değerini buluyoruz.
@bunalmıs hocam GPIOD->OSPEEDR= 0xFFFFFFFF yerine GPIOD->OSPEEDR= 0xFF000000 değerini verebilirmiyiz? nasıl olsa diğer portları
kullanmıyoruz.?
ayrıca ledleri yakmak için GPIOD->ODR= 0x0000F000 yerine GPIOD->BSRR = 0X0000F000
ve ledleri söndürmek için GPIOD->ODR= 0x00000000 yerine GPIOD->BSRR = 0XF00000000 komut ve değerleri kullanılabilirmi? keilde derlerken
hata verdi. kütüphanede 1 sıkıntı olabilirmi?
kullanılabilir ise bu komutları işleme hızları farklımıdır?
Alıntı yapılan: dombilik - 24 Ekim 2011, 09:22:33
Hocam ben kendi payıma dersleri takip ediyorum ve etmekte de zorlanıyorum.Başlangıç da C dersleri ile başlayıp temelden girileceğinden bahsedilmişti.
Ama ARM serisine yabancı olmayan ve C bilgisi iyi olan arkadaşlar bodoslama daldılar konuya..Bunu yadırgamıyorum gayet normal.Amacım eleştirmek de değil zaten.
Lakin aşağıdaki topic bomboş kaldı.
https://www.picproje.org/index.php/topic,35720.0.html (https://www.picproje.org/index.php/topic,35720.0.html)
Sabırla sıranın benim gibilere gelmesini bekliyorum. :-[
Size hak veriyorum. https://www.picproje.org/index.php?topic=35908.msg256759;topicseen#msg256759 (https://www.picproje.org/index.php?topic=35908.msg256759;topicseen#msg256759) den hızlı şekilde C ye giriş yapıp anlatımları başlatalım.
Asıl C başlığımızdaki dersler daha sonra sistematik ilerler.
Alıntı yapılan: bunalmis - 24 Ekim 2011, 10:05:26
O ozellik zaten var. Hic kopyalamaya calismadan paste demeyi denedinmi?
Haklısınız, panoya otomatik olarak kopyalıyormuş :).
Alıntı yapılan: bunalmis - 24 Ekim 2011, 01:31:33
Şu ana kadar neler yaptık;
CPU clock kaynağını kullanmayı,
GPIO portunu I/O olarak kullanmayı,
GPIO yu alternatif fonksiyon amaçlı kullanmayı,
Timer kullanmayı,
Interrupt kullanmayı
Çok basit anlamda da olsa gördük.
Kartlarınız geldiğinde bunları bizzat deneme şansınız olacak.
Şu anda deneme yapmamız gereken DMA, UART, I2C konuları var. Aslında çok konu var.
Fakat C dersleri geride kaldı. Ayrıca kursa katılanlar konuları takip ediyorlarmı etmiyorlarmı, anlıyorlarmı anlamıyorlarmı hiç fikrim yok.
Öte yandan ARM programlamayı, registerlere kuru sayılar yükleyerek yazmak gördüğünüz gibi mümkün hatta çok kısa kodlarla işler yütülebiliyor fakat okunurluğu yok.
Bundan sonrası için nasıl yola devam edelim?
Biraz dinlenelim mi?
evet hocam biraz frene basıp C dersleri ile senkron gitmek daha iyi olacaktır diye düşünüyorum.
Alıntı yapılan: bunalmis - 22 Ekim 2011, 22:16:25
User butonuna basıldığında ledleri yakan basılmadığında ledleri söndüren program
CPU 8 Mhz Xtal OSC ile 168Mhz de koşuyor.
AHB frekansı 168 Mhz
APB1 frekansı 42 Mhz
APB2 frekansı 84 Mhz
// Programın başı
#include "STM32F4xx.h"
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
int main()
{
while(1)
{
if (GPIOA->IDR & 0x000000001) GPIOD->ODR= 0x0000F000; // Ledler yansin
else GPIOD->ODR= 0x00000000; // Ledler sonsun
}
}
// Programın sonu.
hocam burda 2tane FLASH->ACR komutu var1tanesini kullanıyoruz, açıklama olarak ikisine de aynı şeyleri yazmışsınız ama verilen değerler farklı, bunun nedeni RCC->PLLCFGR katsayılarına verdiğimiz değerlermidir. Yani RCC->PLLCFGR e verdiğimiz değerlere göre FLASH->ACR değerlerimi değişiyor? bu soruyu gözüme takıldığı için soruyorum daha incelemede bulunmadım. mantıksız 1soru olabilir şimdiden özür dilerim :)
Alıntı yapılan: kck87 - 24 Ekim 2011, 10:13:54
AHB1ENR : reginin 3.biti d portunun clok unu aktif ediyor. Aynen dediğiniz gibi
GPIOD->MODER : d portu 16 bacaklı, 32biti 2şerli gruplandırarak 1 port için 4 farklı durum belirlemesi yapılabiliyor, rehberde
yazana göre 01 verince çıkış olarak ayarlıyoruz, bu sebepten 0x55000000 sayısını giriyoruz. Evet
GPIOD->OSPEEDR : aynı mantıkla 1 çıkış için 4 farklı çalışma hızı belirleyebiliyoruz 11 max hiz çalıştırmak için.
hesapladığımızda 0xFFFFFFFF değerini buluyoruz.
@bunalmıs hocam GPIOD->OSPEEDR= 0xFFFFFFFF yerine GPIOD->OSPEEDR= 0xFF000000 değerini verebilirmiyiz? nasıl olsa diğer portları kullanmıyoruz.? Evet, kullanmadığımız için diğerlerinin hızını 00 yaparak yavaşlatabilirsiniz.
ayrıca ledleri yakmak için GPIOD->ODR= 0x0000F000 yerine GPIOD->BSRR = 0X0000F000
ve ledleri söndürmek için GPIOD->ODR= 0x00000000 yerine GPIOD->BSRR = 0XF0000000 komut ve değerleri kullanılabilirmi?
Aynen dediğiniz gibi.
Keilde derlerken hata verdi. kütüphanede 1 sıkıntı olabilirmi? Bunun sebebi STM32F4xx.h header dosyasını hazırlayan vatandaş
GPIOD_BSRR registerinin C tanımlamasını rehberdeki şekline göre tanımlamamış da bunu 16 lık iki parçaya bölmüş.
(ARM registerlerine 8, 16 ve 32 olarak erişilebilir.)
Bu durumda header dosyaya göre GPIOD->BSRRL = 0XF000 Ledleri yakar
GPIOD->BSRRL = 0XF000 Ledleri söndürür
kullanılabilir ise bu komutları işleme hızları farklımıdır?
Hayır hiç bir farkı olmaz. Fakat portta bit manuplasyonu yaparken yazılımda diğer bitleri maskelemeyle vs uğraşılmayacağı için
yazılım sadeleşir dolayısı ile hızımız artar. (Mevcut örneklerde bu durum sözkonusu değil)
Alıntı yapılan: kck87 - 24 Ekim 2011, 10:56:39
Programların SystemInit fonksiyonunda 2tane FLASH->ACR komutu var 1 tanesini kullanıyoruz, açıklama olarak ikisine de aynı şeyleri yazmışsınız ama verilen değerler farklı, bunun nedeni RCC->PLLCFGR katsayılarına verdiğimiz değerlermidir. Yani RCC->PLLCFGR e verdiğimiz değerlere göre FLASH->ACR değerlerimi değişiyor? bu soruyu gözüme takıldığı için soruyorum daha incelemede bulunmadım. mantıksız 1soru olabilir şimdiden özür dilerim :)
// FLASH->ACR = 0x00000705; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
Normalde olması gereken üstteki. Fakat Çipte BUG var ve bu yüzden alttakini kullanıyoruz. Bu yüzden ikisinide yazdım fakat birisinin başına // koydum.
Alıntı yapılan: bunalmis - 24 Ekim 2011, 12:00:37
// FLASH->ACR = 0x00000705; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
Normalde olması gereken üstteki. Fakat Çipte BUG var ve bu yüzden alttakini kullanıyoruz. Bu yüzden ikisinide yazdım fakat birisinin başına // koydum.
anladım hocam sağolun, şu BUG nedir biraz açsak yada terimler kısmında açıklasak iyi olur hocam :)
Bunalmis Bey,
Bu forumdaki insanlara ARM öğretmek için gösterdiğiniz azmi ve çabayı takdir ediyorum, ayrıca bunun için teşekkür ediyorum. Cortex M-4 discovery kiti elime geçer geçmez ben de sizin yazılarınızı takip etmeye başlayacağım.
Sizden bir ricam olacaktı. Yeni başlayacaklar için bir konu açıp, yeni başlayacakların hangi konuyu hangi sırayla takip etmeleri gerektiğini o konu da belirtebilirseniz sevinirim. Konularınıza şöyle bir göz ucuyla baktım, fakat yeni başlayacak biri olarak hangi konuyu takip etmekle başlayacağımı kestiremedim.
İlginiz ve alakanız için tekrar teşekkürler...
Arkadaşlar linkteki kodu debug etmeyi deneyebilirmisiniz. Ne yaptıysam "while (!(RCC->CR & 0x00020000)); " satırını atlatamadım. Çünki RCC->CR registerının HSERDY biti set olmuyor. System init içindeki diğer while döngüleride aynı şekilde. Onları yorum satırı yapınca sorun klamıyor ama registerlarda HSERDY, PLLRDY bitleri set edilmemiş oluyor.
http://www.4shared.com/file/Nm7cdwgu/led.html
o satırı bende debug edemedim varmıdır bi sebebi yoksa kitlemi çalışmak gerekiyo
Ben 2 gündür aklıma estikçe kodun o kısmıyla ilgileniyorum. Tahminime göre simülatör ile alakalı bir durum ama bunalmis hocam ben sorunsuz simülatör ile debug ettim yazmıştı. O yüzden uğraştım ama sonuç alamadım. Ve dosyaları yüklemeye karar verdim. Aynı şekilde keille birlikte gelen blinky projesinide inceledim HSERDY ve PLLRDY bitleri set olmuyor ama orada timeout koymuşlar belirli bir süre sonra o satırları atlıyor.
Hemen kontrol deyim. Acaba simülatörden ST-Link'e geçmeyi mi unutttum. Normalde simulatör, donanımı simüle etmez. Etmesi için varsa bu özelliğinin seçilmesi lazım.
Edit: Muhtemelen Debugger ST-Link de kaldı. Simulatör de o satırlar geçilmiyor. (Kusura bakmayın)
Anlaşılmıştır hocam bu kısımları kitler ulaşınca hem tekrar hem de kontrol amaçlı bakmamız gerekecek. Teşekkürler. Bu arada blinky projesini incelerken yapılan port tanımları oldukça okunaklı geldi portların takibi açısından.
bunalmis hocam ST nin kendi örneklerinde simülatör PLL kısmını direk geçiyor,
arada ne fark diye baktığımda başlangıçta şu ayarlamalar yapılıyor
System_Init bu şekilde başlıyor system_stm32f4xx.c içinde
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset CFGR register */
RCC->CFGR = 0x00000000;
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x24003010;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Disable all interrupts */
RCC->CIR = 0x00000000;
==================================== Buradan sonrası aynı
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
Evet bu kodu inceledim. Burada timeout var o nedenle geçiyor.
Bu durumu üstü kapalı olarak dersler başlığında yazmış lakin yazdığım açıklamayı ben de beğenmemiştim.
Şöyle demiştim.
Alıntı YapSystemInit kodları, basit yazılsa ne olur karmaşık yazılsa ne olur?
Bu sorunun cevabını bilmeniz çok önemli. Çünkü cevabı, yazım şeklinde tercih yapmanızı, dolayısıylada sizin ARM hayatınızı şekillendirecektir.
Reset işlemi ardından çipin ne kadar registeri varsa hepsi tabiri yerindeyse fabrikasyon değerlerini alır.
SystemInit kodlarınızı bu varsayımla yazarsanız, daha açık ifadeyle, kodlarınız, sadece reset işleminden çıkılır çıkılmaz çalıştırılacak, daha sonra çalıştırılmayacak varsaysayımı ile yazarsanız yazılım sade olacaktır. Çünkü tüm registerler bilinen değerlere sahiptir. Size, Rehber dokumandaki register anlatımlarına göre registerlerin bitlerini set yada reset etme işi kalır.
Fakat bu şekilde yazacağınız kodları, gelişigüzel bir safhada çağırmaya kalktığınızda işlemcinin yada donanımın çakılması sorununu yaşayabilirsiniz.
Bu sorunun çözümü daha dikkatli yazım şeklini gerektirir. Daha önceden değer almış registerler donanım çalışırken bir anda ilk değerlere döndürülemez kademeli olarak döndürülmelidir. Bu tip registerlere en güzel örnek clock ayarlamalarının yapıldığı registerlerdir.
(Son konuya ait açıklamayı ben de beğenmedim. Bir ara tekrardan ele alacağım. Fakat şimdilik böyle kalsın)
Bunu tartışmak bugüne nasipmiş.
Tartışalım. Neden biz daha basit kodlar yazdık?
Sizinde dediğiniz gibi fabrikasyon değerlerinin sağlandığını düşünerek direk ayarlamalara girdik
bu değerlerden emin olmak için ilk başta kendimiz yüklememiz gerek ki çalışmama vb durumlara düşmeyelim
doğru mudur hocam?
Alıntı yapılan: ErsinErce - 24 Ekim 2011, 16:26:10
Sizinde dediğiniz gibi fabrikasyon değerlerinin sağlandığını düşünerek direk ayarlamalara girdik
bu değerlerden emin olmak için ilk başta kendimiz yüklememiz gerek ki çalışmama vb durumlara düşmeyelim
doğru mudur hocam?
bana da mantıklı geldi, olabilir.
Mesela ST nin kodundaki
RCC->CIR = 0x00000000; /* Disable all interrupts */ satırına bakalım.
Resetten taze kurtulmuş çipin zaten tüm interruptları disable durumundadır.
Biz RCC_CIR registerden tekrardan disable etme yoluna gitmedik.
Dolayısı ile lüzumsuz kodları yazmadık.
Ancak;
Yazdığımız SystemInit, herhangi bir zamanda herhangi bir yerden tekrar çağrılacaksa bu durumda SystemInit kodları bizim yazdığımız gibi basit yazılmamalıdır.
Fakat daha kursa başlar başlamaz da kodlarımızı, çok sayıda çevrebirimi registeri kullanarak yazıp anlatmaya kalksaydım kursu anlaşılır kılamazdım.
Zaten bizim de SystemInit kodlarını Hard Reset haricinde çağırmak gibi niyetimiz de yok.
@bunalmis hocam merhaba
FLASH->ACR = 0x00000605; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
satırında
6 vaitstate seçmiyoruz 5 wait state seçiyoruz
fakat bu 6 clock cycle a tekabül ediyor anladıgım kadarıyla. arkadaşların kafası karışmasın diye soyliyim dedim.
örnek c programları bolümünde yazıyordu
kolay gelsin
Dogru diyorsun. Aciklama kismindaki 6WS yi 5WS olarak degistireyim.
(http://www.cncdesigner.com/STM/CLK_PLL.JPG)
hocam birşey daha kafama takıldı
şimdi bu clock tree ye ve bizim system init dosyamıza baktıgımızda
ilk başta
16MHz HSI RC yi kullanıyoruz
burda AHB presc ' a giden bir switch var 3 kademeli
aynı zamanda paralel olarak "M" bölücüsüne giden iki giriş var
16Mhz HSI RC ile işimiz bittiğinde 8Mhz HSE 'ye ordanda PLL i aktif edip 168 mhz ile P den çıkıp "AHBPRESC" e giriyoruz.
artık PLL e geçtiğimize göre "HSION" bitini sıfır yapıp(16 MHZ'i durdurup) enerji tasarrufu sağlayabilirmiyiz
yoksa bu bize her daim lazımmı bunu kapatırsak sonra işlemcinin çalışmama ihtimali gibi(kısır döngü) şeyler olabilirmi
yada her resetlediğimizde bu internal osc ayarları başa dönermi(sadece bu sistemin çalışma mantıgını anlamak için sordum yoksa okadar enerjinin kaybının önemi yok benim için)
teşekkür ederim
üstat alttakiler çıkış bence hse kendine gelip işinin başına geçince kapatılır
Alıntı yapılan: ilhan_mkp - 25 Ekim 2011, 00:37:15
üstat alttakiler çıkış bence hse kendine gelip işinin başına geçince kapatılır
hocam alttakiler derken switch in altındakilerden bahsettim
yani m bölücüsüne girenlerden
en alttakiler ise çıkışlar
PLLCLK ve PLL48CK
peki bu HSI off yapıldıgında
işlemciye reset attığımızda kısır döngü olurmu
yoksa resetten sonra fabrikasyon ayarlaramı doner onu anlamadım
CPU, PLL'den gelen clock ile beslenmeye basladigi andan itibaren elbette HSI yi kapatabilirsin. Bu da guc tasarrufu yapar.
Her reset isleminde registerlerin alayi fabrikasyon degerlerine doner.
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
Kirmizi satirlarda CPU hala HSI ile besleniyor
Yesil olan satirda artik PLL ile besleniyoruz ve artik HSI yi bu satirda yda daha sonra kapatabilirsiniz.
Kavunici satirda CPU HSI ile mi yoksa PLL ile mi besleniyor tam belli degil fakat HSI ile beslenmesi daha mantikli
Alıntı yapılan: mcan - 23 Ekim 2011, 11:30:46
#include "STM32F10x.h"
void delay(unsigned int);
int ih;
void SystemInit (void)
{
RCC->APB2ENR |= 0x00000016; // GPIOD donanımının clock sinyalini uygulayalım
GPIOC->CRL = 0x33333333; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOC->CRH = 0x33333333;
RCC->CR |= 0x0010000; // HSE aç
while (!(RCC->CR & 0x00020000)) // HSE tamam mı devam mı?
{
GPIOC->ODR |= 0x20; // Ledler yansin
delay(0x90000);
GPIOC->ODR &= 0xFFFFFFDF; // Ledler sonsun
delay(0x40000);
}
RCC->CFGR = 0x001D0000; // PLL ayarla
RCC->CR |= 0x001000000; // PLL aç
while (!(RCC->CR & 0x0002000000)) // PLL Kilitlendi mi?
{
GPIOC->ODR |= 0x200; // Ledler yansin
delay(0x90000);
GPIOC->ODR &= 0xFFFFFDFF; // Ledler sonsun
delay(0x40000);
}
FLASH->ACR = 0x32; // Flash gecikme ayarı
RCC->CFGR = 0x001D0002; // SİNYAL KAYNAĞI PLL
}
{
void delay(unsigned int i)
unsigned int z;
for(z=0;z<i;z++);
}
int main()
{
while(1)
{
GPIOC->ODR= 0x0000FFFF; // Ledler yansin
delay(0x80000);
GPIOC->ODR= 0x00000000; // Ledler sonsun
delay(0x80000);
}
}
C4 tam hızda çalışırda c3 çalışmazmı :) Yine @Bunalmis hocamızın kodundan esinlenerek yazdım,Flash ile alaklı kodu kaldırırsanız hse kaynaklı pll çalışmıyor,sadece hsı,hse yada hsi+pll çalışıyor dökümana göre hsi+pll de çalışmaması lazım ancak orda bir güzellik var hsi yi ikiye bölüp pll ye giriyor o da 36 mhz ediyor sanırım fark azaldıkca flash latency kompanze edebiliyor ,kesin bilmiyorum...Bende debugger olmadığından led kodlarını system_init in içine yazdım.
{
void delay(unsigned int i)
unsigned int z;
for(z=0;z<i;z++);
}
satırında üstteki süslü parantez yanlış yerde oyüzden derleme yapmaz
cortexM3 kiti ile deneme yapıcak arkadaşlar o parantezi 2 satır aşagıya indirirse sorun ortadan kalkar
NOT: CORTEX M3 kiti için koddur
mcan eline sağlık
birde bu kodu düzgün derledim fakat
sanırım debug.ini dosyasından sorun kaynaklanıyor
orjinal stm32 klasoründeki ram.ini ilede denedim yine olmadı
No ULINK Device found
Error:Flash Download failed- Target DLL has been cancelled
hataları alıyorum
mümkünse senin kullandıgın ini dosyasını bana yazarmısın
teşekkürler..
Sen Debuggerda simulatoru değil ULink i secmissin. Yani Keil kartla calisacagini anlamis fakat ULinki bulamamis.
Kartla calisiyorsan Keil, Ulinki bulamadigina gore T-Link kullaniyor olabilirmisin? Oyle ise Ulink yazan yeri T-Link yapmalisin.
Alıntı yapılan: bunalmis - 25 Ekim 2011, 01:53:08
Sen Debuggerda simulatoru değil U-Link i secmissin. Yani Keil kartla calisacagini anlamis fakat U-Linki bulamamis.
hocam ama bende kit var onun üzerinde denemek istedim
ulink takılı (stlink)swd yi seçtim cortexM3Discovery kitim var
********************
hocam tamamdır
menüde projects > options for "Target1" > Utilities
sekmesinden ST-link i seçtim sorun düzeldi yükledim
:D oleyy
***************
program çalışmadı ama :( (ledler yanıp sonmedi )
yarın debug yapıp adım adım gözden geçirmeye çalışırım
sanırım "stm32f10x.h" yerine "stm32f10x_lib.h" yazdıgımız için bi sorun oldu
@mcan sen karta programı atıp ledlerin yanıp sondugunu gördünmü?
Alıntı yapılan: gambit1244 - 25 Ekim 2011, 01:54:29
hocam ama bende kit var onun üzerinde denemek istedim
ulink takılı (stlink)swd yi seçtim cortexM3Discovery kitim var
********************
hocam tamamdır
menüde projects > options for "Target1" > Utilities
sekmesinden ST-link i seçtim sorun düzeldi yükledim
:D oleyy
***************
program çalışmadı ama :( (ledler yanıp sonmedi )
yarın debug yapıp adım adım gözden geçirmeye çalışırım
sanırım "stm32f10x.h" yerine "stm32f10x_lib.h" yazdıgımız için bi sorun oldu
@mcan sen karta programı atıp ledlerin yanıp sondugunu gördünmü?
evet ledler yanip sonuyor ama , problem su olabilir sen hangi porta ledleri bagladin ve hangi bacaklara? ledleri ben sadece c9 ve c5 e bagladim.
@mcan
kitin üstündeki 2 ledi kullanmıyormusun???? :'( :'(
boşuna ugraşmışım düngece teşekkürler..
bi sorum daha var
ben bu programile debug moduna girebiliyorum fakat debug kütüphande dosyasında bir satırda takılıp kalıyor
ve ordan başka yere hareket ettiremiyorum
acaba ini dosyasından mı kaynaklanıyor
sen kusursuz debug yapabiliyomusun?
@gambit1244 sende hangi kit var ,ben et arm stamp kullaniyorum bu yuzden uzerinde neredeyse hic birsey yok.ledleri kendim bagladim.
Software olarak debug etmiştim ama bende debugger olmadığından ledler ile debug etmeye çalışıyorum.Çipi de seri porttan stm32 nin kendi loader i ile programlıyorum.
Birde benim gözlemlediğim eğer hse ile çalışan pll çakılırsa hsi den devam ediyor,eğer hsi yi kapatırsanız problem anında komple susabilir,ayrıca okurken gözüme çarpmıştı bir yazmaç ile bu otomatik osilatör geçişini kontrol ediyorduk şimdi iş yerinden bakamadım akşam ayrıntılı yazarım.
Aha da buldum
If the HSE oscillator is used directly or indirectly as the system clock (indirectly means: it is
used as PLL input clock, and the PLL clock is used as system clock), a detected failure
causes a switch of the system clock to the HSI oscillator and the disabling of the HSE
oscillator. If the HSE clock (divided or not) is the clock entry of the PLL used as system clock
when the failure occurs, the PLL is disabled too.
Bu durumda siz pll kullanırken hsi yi de durdurursanız herhangi problemde işlemci durması lazım.Ben denerken kristali söktüm ve 8 mhzde çalışmaya devam etti demekki hsi yi kendi otomatik aktif etti.
@Bunalmış ve Hocalarım.
Olay Biraz Hızlı Gitmiş Basic den başka dil ile çalışmamış ve PIC den başka işlemci ile uğraşmamış arkadaşlar muhtemelen "Artiz ne arar la bazarda" diye bakıyorlar.
Aşırı Hız Uyarısı Alıyorum Zihnimden.
muhittin hocam son yazılanlar c bilenler için sonuçta hiç bilmeyenlerin onları yetişmesi zor biraz acemilere biraz ustalara emin olun basic kullanmış herkez sizin gibi düşünüyor siz yine basicde itap yazacak seviyedesiniz bizim durum daha bir yaş ;D
Alıntı yapılan: ilhan_mkp - 25 Ekim 2011, 23:24:14
muhittin hocam son yazılanlar c bilenler için sonuçta hiç bilmeyenlerin onları yetişmesi zor biraz acemilere biraz ustalara emin olun basic kullanmış herkez sizin gibi düşünüyor siz yine basicde itap yazacak seviyedesiniz bizim durum daha bir yaş ;D
emin olun kurs bu şekilde giderse.
c dersleri kapsamlılaşırsa
bununla yetinmeyip ileri c gibi temel c eğitimi veren kitap alırsanız
ve azim gösterirseniz burda arm öğrenemicek kimse yok
emek ve zaman ayırdıktan sonra herkez yapabilir
benimde sizden farkım yok inanın
mikrodenetleyicinin p4 işlemciden farkını 8 ay once ogrenmiş biriyim ben
5 ay önce c mi yoksa asembly mi öğrenmeye başlasam diye forumlarda çırpınan biriydim
vakit ve emek..
ve dahada otesi burda sana bana yardım etmek isteyen biçok temiz kalpli insan var (ben dahil)
Basic bilen arkadaslar https://www.picproje.org/index.php/topic,35908.0.html (https://www.picproje.org/index.php/topic,35908.0.html) adresinde yazdiklarimizi 1 bilemediniz 2 gunde ezberleyebilir.
Ezberlemeniz gereken komutlari alt alta yazsak komik bir sayi cikar.
----------------------------------------------------------------------------------
C den zerre anlamayan fakat Basic de program yazabilen, gun icinde ara ara online olabilecek ve acacagim baslikta sadece 2 gunlugune forumda ardi ardina karsilikli mesaj yazabilecek 1 adet gonullu lazim.
2 gun ezber zamaniniz var. Ayin 28 inde de 2 gunluk ozel yazismaya baslayacagiz.
Bu gonullu ile yapacagimiz yazismalar daha sonra Basic bilenlere ozel ders yerine gececek.
Varmi kendine guvenen. (Garanti veriyorum, 1 Kasimda kodlarini C ile yazmaya baslayacak.)
Ayni calismayi bir de asm bilen arkadasla yapariz.
(Yalniz bu arkadas, 8 bit islemcide hex FF neden -1 demektir biliyor olsun.)
Hocam Bir Adım Öne Çıkmak İsterim Ama Ben Klasman Dışıyım Sanırım.
C algısı Olmayan Biri ve Özellikle Mesaide Mesaj Yazabilen Biri Gerek Sanırım :)
Galiba 2 gunluk yazisma, cumartesi pazara denk geliyor. Gelmiyorsa da ezber suresini 3 gune cikartalim.
C ye yabanci olmasi tercih edilir.
Alıntı yapılan: bunalmis - 25 Ekim 2011, 23:51:57
(Yalniz bu arkadas, 8 bit islemcide hex FF neden -1 demektir biliyor olsun.)
sanırım bu satır benim içindi. hocam pbp $ff için -1 değil 255 karşılığını veriyor. farklı bir kullanım biçimi var ise eğer Orhan ALTINBAŞAK kitabında bahsetmemiş.
bu durumda ben gönüllülük şansımı kaybettim gibi görünüyor.
ben gönüllüyüm isterseniz hafta içi iki günde olabilir hiç farketmez ama şartlarım uyuyormu bilmiyorum şöyleki pbp de and or ve if else yapılarını kullanarak zaman rölesi ve Makinaya özel akıllı röle programı yazıyordum for next'ti hiç kullanmadım veya daha değişik yapıları. LCD sürme pwm vs gibi şeyleri yaptım ama birtürlu gldc süremedim (isis de çalıştı realde çalışmadı)
birde şu var işaretli sayılarle pek uraşmadım
Alıntı yapılan: papsukkal - 26 Ekim 2011, 03:22:29
sanırım bu satır benim içindi. hocam pbp $ff için -1 değil 255 karşılığını veriyor. farklı bir kullanım biçimi var ise eğer Orhan ALTINBAŞAK kitabında bahsetmemiş.
bu durumda ben gönüllülük şansımı kaybettim gibi görünüyor.
Bende de hata olmus. -1 neden FF dir deseydim sorun olmazdi.
En azindan asagidaki Basic komutlarini cayir cayir kullanmak lazim.
let rem dim and or xor not if else for next goto gosub return inp out (peek poke yada benzeri)
Alıntı yapılan: bunalmis - 25 Ekim 2011, 23:51:57
Basic bilen arkadaslar https://www.picproje.org/index.php/topic,35908.0.html (https://www.picproje.org/index.php/topic,35908.0.html) adresinde yazdiklarimizi 1 bilemediniz 2 gunde ezberleyebilir.
Ezberlemeniz gereken komutlari alt alta yazsak komik bir sayi cikar.
----------------------------------------------------------------------------------
C den zerre anlamayan fakat Basic de program yazabilen, gun icinde ara ara online olabilecek ve acacagim baslikta sadece 2 gunlugune forumda ardi ardina karsilikli mesaj yazabilecek 1 adet gonullu lazim.
2 gun ezber zamaniniz var. Ayin 28 inde de 2 gunluk ozel yazismaya baslayacagiz.
Bu gonullu ile yapacagimiz yazismalar daha sonra Basic bilenlere ozel ders yerine gececek.
Varmi kendine guvenen. (Garanti veriyorum, 1 Kasimda kodlarini C ile yazmaya baslayacak.)
Ayni calismayi bir de asm bilen arkadasla yapariz.
(Yalniz bu arkadas, 8 bit islemcide hex FF neden -1 demektir biliyor olsun.)
Bende seve seve gönüllü olurum.Çalıştığım işyerinde internetim yok.Fırsat buldukça Cep telefonu ile bağlanıyorum.
İşe gidiş-geliş saatlerimde belli olmuyor.Evde bulunduğum zamanlar (tabii çağrılmadığım sürece ) sürekli forumun başındayım.
Alıntı yapılan: bunalmis - 26 Ekim 2011, 10:03:56
Bende de hata olmus. -1 neden FF dir deseydim sorun olmazdi.
00000000 - 00000001 = 11111111
bkz: iki'nin tümleyeni (http://tr.wikipedia.org/wiki/%C4%B0kinin_t%C3%BCmleyeni)
bkz: insanlar bazen neden 10'a ayrılır? (http://www.yildiz.edu.tr/~uzun/SS_PDF/SS_02_SaySis.pdf)
bkz: nerd (http://en.wikipedia.org/wiki/Nerd)
ben gönüllüyüm.bahsi gecen kodları kullandım da dim komutuprotonda değilmiydi?neyse beni de dahl edin.okula gtmedim daha üniye sreklli online haldeyim..gönüllüyüm.
dim-var vs aynı şey
@eistain_54 Tamam o zaman seninle yola çıkalım.
Geçmişine baktım. CCS ve Keil başlığında bir kaç küçük vukuatın olsa da temiz sayılırsın. (C geçmişin yok görünüyor)
https://www.picproje.org/index.php?action=profile;area=statistics;u=17738 (https://www.picproje.org/index.php?action=profile;area=statistics;u=17738)
Microlar için proton yada başka bir Basic bilmem. Fakat bu dert değil, sen senin Basic, ben GW-Basic bilgisi ile arada biryerde buluşuruz.
O zaman linkini verdiğim başlıktaki anlatımları oku. Daha doğrusu ezberle.
Mesela o başlıkta neyi ezberleyeceksin. C de AND sembolü & dur,
for bir döngü komutudur. fordan sonra parantez gelir., parantezin içinde döngü değişkeninin başlangıç, döngüden çıkış şartı vardır...
// açıklama satırırı için kullanılır vs vs. 2 günde ezberlersin. Bundan adım gibi eminim.
iyide hocam ordaki bnm istatistiki verilerim:)lütfen bu kadar desifre olmak istemiyorum
O bilgiler zaten forum üyelerine açık ki.
Alıntı yapılan: mozkan87 - 26 Ekim 2011, 16:07:45
O bilgiler zaten forum üyelerine açık ki.
muhakkak...ben şakasına söyledim ama ezberlemeem gereken kısmı anlamadım?
Alıntı yapılan: eistain_54 - 26 Ekim 2011, 16:11:36
muhakkak...ben şakasına söyledim ama ezberlemeem gereken kısmı anlamadım?
https://www.picproje.org/index.php/topic,35908.0.html (https://www.picproje.org/index.php/topic,35908.0.html)
Bu linkte yazdıklarımı oku. Özellikle
Bla Bla Bla Bla renkli karakteri olan yazıları.
Verdiğim linkte, kitaplardaki gibi bir cansıkıcı anlatım yok. Okuyucunun mantık yürüterek kafasında bir şeyler şekillendirmesini hedefledim.
(Zaten kitap yazacak kadar C'ye hakim değilim.)
arkadaşlar
c projelerinde timer ve interrupt kullanılmış programlar var
bununla ilgili anlatım biyerde yapıldıda bennmi bulamıyorum yoksa ileridemi yapılıcak
Arkadaşlar interrupt ile ilgili temel şeyleri anlatan bir döküman var mı? İnterrupt aktif edildikten sonra interrupt handler nasıl oluşturulur bunun gibi temel şeyleri anlatan herhangi bir döküman varsa paylaşırsanız sevinirim. İlla m4 ile ilgili olması şart değil. Teşekkürler.
@eistain_54 (https://www.picproje.org/index.php?action=profile;u=17738)
Nasıl hazırmısın yoksa bir gün daha bekleyelimmi?
hocam takıldığım yerler var akşşama biter...
Hocam anlamadıım iki konu var...
structure ve union
pointer
onları ben de çözemedim. basit bir anlatım olsa ne güzel olur...
Alıntı yapılan: mozkan87 - 27 Ekim 2011, 22:38:58
Arkadaşlar interrupt ile ilgili temel şeyleri anlatan bir döküman var mı? İnterrupt aktif edildikten sonra interrupt handler nasıl oluşturulur bunun gibi temel şeyleri anlatan herhangi bir döküman varsa paylaşırsanız sevinirim. İlla m4 ile ilgili olması şart değil. Teşekkürler.
Orneklerle anlatmiyor fakat register aciklamalari asagidaki dokumanlarda.
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0439b/DDI0439B_cortex_m4_r0p0_trm.pdf (http://infocenter.arm.com/help/topic/com.arm.doc.ddi0439b/DDI0439B_cortex_m4_r0p0_trm.pdf)
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf)
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CIHIGCIF.html (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CIHIGCIF.html)
Ornek programlar kismindaki NVIC ayarlamalarini anlatacagiz. Simdilik frene bastik.
Alıntı yapılan: bunalmis - 23 Ekim 2011, 23:22:46
Timer 7 ve interrupt kullanarak yanıp sönen led programı
int main()
{
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
}
@bunalmış hacam biraz geriden geliyoruz galiba kusura bakmayın bir sorum olacaktı
yukarıdaki kodda RCC->APB1ENR|=0x00000020 i int main() de kullandığınız için mi timer7 yi aktif etti biz bunu
void SystemInit() de kullandığımızda ( RCC->APB1ENR|=0x00000020 ) GPIOF i aktif ediyor doğru mu anlamışım ?
Alıntı Yapvoid SystemInit() de kullandığımızda ( RCC->APB1ENR|=0x00000020 ) GPIOF i aktif ediyor doğru mu anlamışım ?
Bu yanlış, çünkü GPIOF clock'u RCC_APB1ENR değil RCC_AHB1ENR açıp kapatıyor.
Olay kodu SysInit yada main içine yazmakla alakalı değil. İstediğin yere yaz farketmez.
Alıntı Yap
Olay kodu SysInit yada main içine yazmakla alakalı değil. İstediğin yere yaz farketmez.
Hımm.. @bunalmış hocam düzeltmeniz için teşekkür ederim. şimdi aynı konu ile başka bir sorum olacaktı
adım adım koşturarak led yakmaya çalıştığımız program ben de sorunsuz olarak çalıştı.
Timer 7 kullanarak Ledleri flash eden program (Interrupt kullanılmıyor) bu programı derleyip adım adım koşturmak isteyince
1. si
Alıntı Yap
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =42000; // Prescaler değerimiz 42000, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 84E6 / (42000) = 2000 Hz
TIM7->ARR =2000; // Counter, Decimal 2000 olunca basa donsun 1 sn demek
TIM7->CR1|=0x0001; // Counter Enable
bu kısım ı keilde gözlemlediğimde;
ADIM ADIM YUKARIDAKİ SATIRLARI İŞLİYOR AMA TIM7 DE FARKLI (AŞAĞIDAKİ) DEĞERLERİ GÖRÜYORUM
TIM7_CR1=0x00000080
TIM7_PSC=0x0000A410
TIM7_ARR=0x000003E8
TIM7_DIER=0x00000001
TIM7_CR1=0x00000081
2. si
Alıntı Yapwhile(1)
{
if (TIM7->CNT > 1000) GPIOD->ODR= 0x0000F000; // Ledler yansin
else GPIOD->ODR= 0x00000000; // Ledler sonsun
}
döngüye girdiğinde ledleri yakmıyor. d portunda hiçbir değişiklik olmuyor.
Aceba nerede yanlışlık yapıyorum ?
Bende bu satırda takıldım
TIM7->DIER=0x0001; // Update Int enable
burada timer7 için int aktif edilmiş
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
burada da nvic'de de izin verilmekte demekki farklı şeyler
şimdi rehber hard ve generic user gide'ye göz attım
NVIC->ISER[0] dan NVIC->ISER[7] ye kadar 8 registerler var ama bununla ilgili açıklayıcı bir bilgi göremedim yada gözden kaçırdım.
peki NVIC->ISER[1] = 0X00800000; deki 0X00800000 değeri neye istinaden verildi ve
NVIC->ISER[1] in TIM7 ye ait olduğunu nereden anladık.
Ayrıca
TIM7 ile ilgili kodları debug ettiğimde TIM7_CNT de değer değişimi gözlemleyemiyorum.
keille alakalı bir durum mu yoksa benimlemi
Reference Manual sayfa 196'da kesmeler için position numaraları var.Diyelimki siz position numarası 23 olan EXTI9_5 kesmesini aktif edicekseniz
NVIC->ISER[0]=(1<<23) yazarak ISER registerındaki 23.biti set edersiniz, yani NVIC->ISER[0] da position numarası 0 olandan 31 olana kadar olan kesmeler kontrol edilir.
NVIC->ISER[1] ise 32'den 63'e kadar olanlar kontrol edilir.Örneğin position numarası 41(41-32=9) olan RTC_Alarm kesmesini aktif edicekseniz NVIC->ISER[1]=(1<<9) yazarak aktif edersiniz.
@taneryilmaz Alıntı Yap
TIM7_CR1=0x00000080
TIM7_PSC=0x0000A410
TIM7_ARR=0x000003E8
TIM7_DIER=0x00000001
TIM7_CR1=0x00000081
Benim verdigim degerlerle sizin verdiginiz degerler ayni. Ben bazilarini decimal yazdim siz hex.
Sadece TIM7_CR1 e 01 yukledigimiz halde 0x81 okumana anlam veremedim.
Bunu bir ara arastiracagim.
Kartla calisiyorsun değilmi?
@madpicTIM7->DIER=0x0001; // Hey Timer7 !!!, int uretmene izin veriyorum demek
NVIC->ISER[1] =0x00800000; // Hey NVIC !!!, Sana TIMER7 INT yollarsa bune degerlendir demek
0x800000 de set edilen bit 0 dahil 23. bit.
NVIC_ISER[0] da da 32 bit var yani 53.bit
TIMER 7 int da zaten external int siralamasinda 53. sirada.
Alıntı Yap
TIM7 ile ilgili kodları debug ettiğimde TIM7_CNT de değer değişimi gözlemleyemiyorum.
keille alakalı bir durum mu yoksa benimlemi
Kartla calismiyorsaniz bir sey diyemem.
Ote yandan TIMER7 ile kartla calisirken bazi gariplikler yasadik ve bunu tartistik. Gozden kacan bir sey de olabilir. Su anda hic bir fikrim yok.
Interrupt yazilimi haric digerlerini anladiysaniz cok iyi. INT konusunu aciklayacak bir seyler yazmamiz gerekecek zaten.
Alıntı yapılan: bunalmis - 29 Ekim 2011, 12:24:41
Benim verdigim degerlerle sizin verdiginiz degerler ayni. Ben bazilarini decimal yazdim siz hex.
Sadece TIM7_CR1 e 01 yukledigimiz halde 0x81 okumana anlam veremedim.
Bunu bir ara arastiracagim.
Kartla calisiyorsun değilmi?
hocam kartsız çalışıyorum keil debuger de
RCC->APB1ENR|=0x00000020;
> TIM7->CR1=0x0080;
TIM7->PSC =42000;
TIM7->ARR =1000;
TIM7->DIER=0x0001;
NVIC->ISER[1] = 0X00800000;
> TIM7->CR1|=0x0001;
TIM7_CR1 e ilk önce 0x80 yüklüyoruz sonra TIM7_CR1 | = 0x01 le or luyoruz sonra 0x81 gördüm ekranda
merhaba arkadaşlar rehber dosyamızın 50. sayfasında register adreslerinin verildigi sayfada aklıma birşey takıldı
0x4002 2000 - 0x4002 23FF GPIOI
0x4002 1C00 - 0x4002 1FFF GPIOH
0x4002 1800 - 0x4002 1BFF GPIOG
0x4002 1400 - 0x4002 17FF GPIOF
0x4002 1000 - 0x4002 13FF GPIOE
0X4002 0C00 - 0x4002 0FFF GPIOD
0x4002 0800 - 0x4002 0BFF GPIOC
0x4002 0400 - 0x4002 07FF GPIOB
0x4002 0000 - 0x4002 03FF GPIOA
şeklinde bir tablo var burada mesela 0x4002 0000 - 0x4002 03FF arasının GPIOA ya ait olduğu yazıyor.
GPIOA neden bu kadar çok registeri meşgal ediyor anlamadım ?
Alıntı yapılan: bunalmis - 24 Ekim 2011, 02:18:23
Bu nedenle bir registere doğrudan veri yüklemek yerine,
1. Registeri oku
2. Değiştirilmesi gereken bit haricindeki bitleri maskele
3. Değişmesi gereken bitleri yerine koy
4. Sonucu registere yaz olmalıdır.
Bunu da bu vesileyle hatırlatayım. Dokümanlarda bu uyarı sık sık yapılır.
Merhaba bu gün dökümanı karıştırırken güzel bir özellik hakkında yazı okudum ve uyguladım.
Eğer benim gibi alışkanlıklardan dolayı maskeleme yada yukarıdaki gibi 4 adımlı işlem yapmak istemiyorsak bit banding tam bize göre. :) Ayrıca hızlı.
Tüm arm'larda varmı bilmiyorum ancak bizimkinde ve c3 de var.
Olay kısaca şöyle sram deki ve çevre ünitelerindeki sınırlar içinde kalan her bir bit, bir word(32 bit) e aynalanmış.
Örnek olarak 9 byte ram'miz olsun . 1 byte ram kullanılabilir değişken için ve geri kalan 8 byte ise 1. baytın her bir bitini temsil etsin.
2 numaralı bayta 1 yazmak aslında, 1 numaralı baytın 0 numaralı bitine yazmakla aynı işlem.
Yöntem eğer elimizdeki ram ve adres az sayıda ise çok mantıksız gibi görünüyor ancak işlemcimiz 32 bitlik 4 gb adresleyebiliyor çoğu mikrokontrolcünün ise maximum 1-2 mb internal remi var geri kalan boş adresleri böyle değerlendirmişler. Bu şekilde aynı pic deki gibi bit bit işlem yapabiliyoruz .
(http://img440.imageshack.us/img440/9932/11353777.jpg)
Mesela aynı adresdeki 16 biti set ediceksek bu işlem yerine maskeleme daha hızlı sonuç verecektir diye düşünüyorum.Ayrıca şuna dikkat etmekde yarar var .Çevrebirimlerinin yazmaçları dökümanda 32 bitlik gibi verilmiş, ancak dökümanda ayrıca offsett değerleri de var ve genelde 4 er 4 er artıyor. Yani her 1 byte ın adresi var.Bu sebeple mesela RCC_CR yazmaçı içindeki HSEON biti için bit_banding kullanmak istiyorsak RCC_CR(0x4202 1000)'nin adresinin 16.biti yerine RCC_CR'nin adresinin bir fazlasının(0x4202 1001) 7 numaralı biti demek doğru oluyor. Bit numaraları 0 ile 7 arasında,0 ve 7 dahil.
Önceden örnek olarak verdiğim kodu bu şekilde değiştirdim
#include "STM32F10x.h"
//SRAM_BB_BASE sram için bitband bölge adresi, SRAM_BASE ise sram in gerçek adresi .Bu tanımlamalar .h dosyasının içindeydi
#define BIT_LEVEL_SRAM(a,b) ((SRAM_BB_BASE + (a-SRAM_BASE)*32 + (b*4)))
#define BIT_LEVEL_PERI(a,b) ((PERIPH_BB_BASE + (a-PERIPH_BASE)*32 + (b*4)))
#define RCC_APB2ENR (RCC_BASE+0x018) //0x18 adresini Soft dökümanında RCC register map adlı konu başlığının altındaki tablodan aldım.
#define GPIO_C_ENABLE *((volatile unsigned int *)(BIT_LEVEL_PERI(RCC_APB2ENR,4))) // 4.bit GPIO_C_ENABLE biti
void delay(unsigned int);
static int ih;
int zg;
void TIM7_IRQHandler(void)
{
if (ih == 0)
ih=1;
else
ih=0;
TIM7->SR = 0x0;
//TIM7->SR = 0x0;
//TIM7->SR = 0x0;
}
void SystemInit (void)
{
GPIO_C_ENABLE = 1 ;//RCC->APB2ENR |= 0x00000016; önceki durumda bu şekilde maskeliyorduk.
GPIOC->CRL = 0x33333333; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOC->CRH = 0x33333333;
RCC->CR |= 0x0010000; // HSE ON
RCC->CFGR = 0x001D0000; // PLL ayarla
RCC->CR |= 0x001000000; // PLL aç
FLASH->ACR = 0x32; // Flash gecikme ayarı
RCC->CFGR = 0x001D0402; // SİNYAL KAYNAĞI PLL APB1 HCLK/16
RCC->APB1ENR |= 0x00000020; //Timer7 ye clock verelim
TIM7->DIER = 0x1;
TIM7->PSC = 0x1FF; //182=B6 182*5= H393
TIM7->ARR = 0xFFFF;
TIM7->CR1 = 0x85;
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
}
void delay(unsigned int i)
{ unsigned int z;
for(z=0;z<i;z++);
}
int main()
{
while(1)
{
if(ih ==0)
GPIOC->ODR= 0x20; // Ledler yansin
else
GPIOC->ODR= 0x200; // Ledler yansin
delay(0x40000);
GPIOC->ODR= 0x00000000; // Ledler sonsun
delay(0x40000);
}
}
Eğer C'de iyileşirseniz çoğu yüke onun üzerine yıkabilirsiniz. Aşağıdaki program yazım tekniği ile hatasız kod yazılabilir.
Yoksa 32bitlik sayılarla uğraşılması gerekir.
LcdGpio->Bits.Data4bit = da_ta >> 4; // high order nibble'ı gönder
LcdGpio->Bits.RS=1;
LcdWr(da_ta);
LcdGpio->Bits.RS=0;
AfioRegs->mapr.bits.CAN_REMAP = PinNo;// CanRx_PB8_CanTX_PB9 gibi PB8(CanRX),PB9(CanTX)
LcdGpio->Bits.ENB=1;
CanRegs->sFilterRegister[CanFilterId].fr1.b32=CanMsgId; // 32bit ID
CanRegs->sFilterRegister[CanFilterId].fr2.b32=CanMsgId; // 32bit ID
CanRegs->sTxMailBox[0].tir.bits.STID |= Msg->ID.Std; // 11bit
GpiodOdrReg->Bits.LCD_CS=0;
GpiodOdrReg->Bits.LCD_RS=0;
GpiodOdrReg->Bits.LCD_RD=1;
Tmrx->egr.bits.UG=1;
Tmrx->sr.bits.UIF=0;
Tmrx->dier.bits.UIE=1;
UsartxRegs->cr1.bits.TE = 1; // Tx enable
UsartxRegs->cr1.bits.RE = 1; // Rx enable
while(Spix->sr.bits.BSY);
Spix->dr.b16.low = SpiData;
gpioa_crh.bits.MODE9=GpioMODE_50mhz_out; // 50mhz out
gpioa_crh.bits.CNF9=GpioCNF_PUPD_in_APP_out; // alternate pushpull
void SystemOscInit(void)
{
// önce rcc dahili osc'ye ayarlanır ve tüm çarpanlar ve interruptlar silinir
RccRegs->cr.bits.HSION=1;
while(RccRegs->cr.bits.HSIRDY == 0);
// Dahili osc bölen ve çarpanları resetle
RccRegs->cfgr.b32 &= 0xF8FF0000; //Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], ADCPRE[1:0] and MCO[2:0]
// HSEON,CSSON,PLLON bitleri clear
RccRegs->cr.b32 &= 0xFEF6FFFF;
// HSEBYP bit clear
RccRegs->cr.b32 &= 0xFFFBFFFF;
// PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE bits clear
RccRegs->cfgr.b32 &= 0xFF80FFFF;
// tüm interruptlar off
RccRegs->cir.b32 = 0;
// Buraya kadar dahili osc seçtik ve tüm diğer ayarları sildik
// şimdi high speed external osc'yi seçip ayarlayacağız
RccRegs->cr.bits.HSERDY=0;
RccRegs->cr.bits.HSEON=1; // harici osc enable
while(RccRegs->cr.bits.HSERDY == 0); // hazırlanıncaya kadar bekle
// HCLK=SYSCLK
RccRegs->cfgr.bits.HPRE=0; // sysclk bölünmez, 8 için 2'ye, 9 için 4'e,.......F için 512'ye bölünür
// RccRegs->cfgr.bits.HPRE=0x8;
// PCLK2 = HCLK/1 =72mhz'e ayarlayacağız (max 72mhz olur)
// burada 56Mhz
RccRegs->cfgr.bits.PPRE2=0; // 0 için bölünmez, 4,5,6,7 için sırasıyla HCLK/2,HCLK/4,8,16'ya bölünebilir
// PCLK1 = HCLK/2 maxsimum 36mhz olabilir, 0 için bölünmez(kullanılamaz,72mhz olamıyacağı için)
// 56/2=28Mhz
// timerlar ise rcc_cfgr.bits.PPRE1=1; olmadığı durumlarda x2 olur (bu durumda yine 56Mhz)
// 4'e bölünmüş olsaydı(rcc_cfgr.bits.PPRE1=5;) PCLK1=56/4=16Mhz olur timerlar ise 16x2=32Mhz'de sayardı
RccRegs->cfgr.bits.PPRE1=4; // 2'ye böl. (4,5,6,7 için sırasıyla HCLK/2,HCLK/4,8,16'ya bölünebilir)
// ADCCLK = PCLK2/6 =72/6=12mhz (en fazla 14mhz olabiliyor)
// 56/8=7Mhz'de çalışsın , acelesi yok :)
RccRegs->cfgr.bits.ADCPRE=3; // 0,1,2,3 sırasıyla PCLK2/2,PCLK2/4,PCLK2/6,PCLK2/8
/*
Flash latency için aşağıdaki şart gerekli
000 Zero wait state, if 0<SYSCLK<=24MHz
001 One wait state, if 24MHz<SYSCLK<=48 MHz
010 Two wait states, if 48MHz<SYSCLK<=72 MHz
*/
FlashRegs->acr.b32&=((u32)0x00000038);
FlashRegs->acr.bits.LATENCY=2; // yüksek frekans olduğu için 2
FlashRegs->acr.bits.PRFTBE=1; // Prefetch buffer enable, flash'a yazmak için gerekli
// Pllclk=8mhz*7mhz=56mhz
RccRegs->cfgr.bits.PLLXTPRE=0; // xtal'i bölme, 1 için HSE/2 olur
RccRegs->cfgr.bits.PLLSRC=1; // PLL'e HSE'yi bağla
// RccRegs->cfgr.bits.PLLMUL=7; // 7+2 kadar HSE'yi çarpar 9x8mhz,
RccRegs->cfgr.bits.PLLMUL=5; // 5+2 kadar HSE'yi çarpar 7x8mhz=56Mhz,
// pll nable
RccRegs->cr.bits.PLLON=1;
while(!RccRegs->cr.bits.PLLRDY); // pll hazır oluncaya kadar bekle
// system clk olrak pll bağla
// RccRegs->cfgr.bits.SW=0;
RccRegs->cfgr.bits.SW=2; // 0-HSI,1-HSE(pll'siz),2-PLL, PLL'i bağla
while(RccRegs->cfgr.bits.SWS!=2); // PLL sistem clk kaynağı oluncaya kadar bekle
}
@Bunalmis hocam ben timer7 kesme olayını araştırıyorum , şöyle bişeyle karşılaştım void TIM7_IRQHandler(void)
{
if (ih == 0)
ih=1;
else
ih=0;
TIM7->SR = 0x0;
//ipb = DAC->CR;
for( ii=0;ii<1;ii++){}
}
Timer 7 ile aynı busda olan başka bir çevre birimini okuduğumda (burdaki örnekde dac) yada ufak bir gecikme sağladığımda da interrupt flag siliniyor. Eğer zamanınız olursa sizdeki kittede deneyebilirmisiniz .Bende for döngüsüne 1 koymak yetti, 0 koyarsam gene olmuyor. Belki sizin kartda 2-3 gerekebilir.
Ek:
One potential issue with M3 designs is a pipeline hazard with the peripheral vs NVIC. If you clear the interrupt as the last thing before exiting an interrupt handler the pipelining, write buffers and disparity in clocks will create a condition where the peripheral is still signalling the interrupt when the M3 decides to tail-chain, causing the handler to reenter (priorities may impact which) and the peripheral will have cleared when you look at it. To avoid this be sure to clear the interrupt upon entry. ie Check source, dismiss, process, leave
As to your issue about knowing which epoch of the 16-bit timer you're looking at. Take a look at using the core cycle counter for a long term timebase, the 32-bit counter has an epoch >1min. The cycle counter is part of the trace unit, and is present in all STM32 parts I've checked.
İnternette karıştırır-araştırıken forumun birinde bu yazıya rastladım.
Bit Banding'i keil ve iar'da denemiştim, zamanlama anlamında büyük bir avantaj getirmiyor. Maskele ile aynı sonuçları almıştım. Ama tabii belki sizi bit maskelemekten kurtarır fakat aynı şeyi güzel bir macro ile sizde yazabilirsiniz.
Alıntı Yap
void TIM7_IRQHandler(void)
{
if (ih == 0)
ih=1;
else
ih=0;
TIM7->SR = 0x0;
// ipb = DAC->CR;
for( ii=0;ii<1;ii++){}
}
Timer 7 ile aynı busda olan başka bir çevre birimini okuduğumda (burdaki örnekde dac) yada ufak bir gecikme sağladığımda da interrupt flag siliniyor. Eğer zamanınız olursa sizdeki kittede deneyebilirmisiniz .Bende for döngüsüne 1 koymak yetti, 0 koyarsam gene olmuyor. Belki sizin kartda 2-3 gerekebilir.
TI urunlerinde soyle bir uyari bulunurdu. Aklimdan cikmis, bu durumda STM de de ise yarar gorunuyor.
Uyarı şöyle; Bir porta bir sey yazdiktan sonra tekrar okumak gerekirse iki nop isletin oyle okuyun denmekte.
STMde 2 değilde 3 der 4 der bilmiyorum. Fakat STM dokumanlarinda simdilik boyle bir uyariyla karsilasmadim.
Hem sıfır yazma hem de okuma saçmalığı halloldu.
void TIM7_IRQHandler()
{
volatile short i;
static char LedFlag=0;
TIM7->SR=0; // Timer Int Flagý silelim
LedFlag=(LedFlag+1)&1;
if (LedFlag) GPIOD->ODR= 0x0000F000; // Ledler yansin
else GPIOD->ODR= 0x00000000; // Ledler sonsun
}
Evet sorun anlaşıldı. Rutinin en sonunda Timer7 int flağı silip interrupt rutininden çıkarsak sorun oluşuyor. İlk başlarda önce okuyup ardından da silerek buna çözüm bulmuştuk.
Yukarıdaki çözümde ise int rutinine girer girmez flağı siliyoruz ardından da int rutininde asıl kodlarımız var. Böylece flag, int rutininden çıkmadan önce silinecek vakti buluyor ve sorunun ortaya çıkışını engelliyor.
Önceki örneklerimizde TIM7->SR=0; silme komutunu veriyoruz. Fakat hemen altında da int rutininden çıkıyorduk. Sil komutu derhal işleme alınmıyor çünkü APB hızı CPU dan düşük.
(Sorun donanım bazında ve çok alt seviyelerde.)
Ya yukarıdaki örnekteki gibi yapın yada int flağı sildikten sonra bir kaç tane NOP koyun. Yada flağın silindiğini yazılımsal olarak kontrol edin.
Alıntı YapOne potential issue with M3 designs is a pipeline hazard with the peripheral vs NVIC. If you clear the interrupt as the last thing before exiting an interrupt handler the pipelining, write buffers and disparity in clocks will create a condition where the peripheral is still signalling the interrupt when the M3 decides to tail-chain, causing the handler to reenter (priorities may impact which) and the peripheral will have cleared when you look at it. To avoid this be sure to clear the interrupt upon entry. ie Check source, dismiss, process, leave
As to your issue about knowing which epoch of the 16-bit timer you're looking at. Take a look at using the core cycle counter for a long term timebase, the 32-bit counter has an epoch >1min. The cycle counter is part of the trace unit, and is present in all STM32 parts I've checked.
@MCAN bu uyarıyı nereden buldun ?
St nin kendi sayfasında bir forum var orda aktif bir kullanıcının biri yazmış,forumdan okuduğum kadarıyla sadece timer da değil adc vs.. ile yapılan kesmelerde de problem oluyormuş...
Link1 (https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fTimer%20clearing%20update%20event%20flag%20can%20cause%20flagless%20input%20capture%20interrupt&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=120)
Ayrıca foruma açtığım başlığa cpu pipelined cpu dur diye not düşmüşler,evet sorun kesinlikle anlattığınız gibi.
Link2 (https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fTIMER7%20INTERRUPT%20FLAG%20NOT%20CLEARING&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&TopicsView=https%3A%2F%2Fmy%2Est%2Ecom%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FAllItems%2Easpx¤tviews=11)
O uyarının benzerini okurken wiki den buldum olayın genelini özünü bu şekilde anlatmış;
Alıntı YapWhen a programmer (or compiler) writes assembly code, they make the assumption that each instruction is executed before execution of the subsequent instruction is begun. This assumption is invalidated by pipelining. When this causes a program to behave incorrectly, the situation is known as a hazard. Various techniques for resolving hazards such as forwarding and stalling exist.
Anladığım kadarıyla arm işlemcideki ,ilk başlarda anlam veremediğim, bazı status bitlerinin bir kısmı sanırım bu işlere de yarıyor.
@Bunalmis hocam sizin vga probleminin acaba bununla bir alakası olabilirmi?
A non-pipelined processor will have a stable instruction bandwidth. The performance of a pipelined processor is much harder to predict and may vary more widely between different programs.
İlerde kullanılmak üzere , arm başlıklarının birine işe yarar c kütüphanelerini barındıran bir başlık açsak olmazmı?Lcd ,sd ,ethernet,sensörler vs... gibi kütüphaneler.
Alıntı yapılan: eemkutay - 30 Ekim 2011, 23:06:21
Bit Banding'i keil ve iar'da denemiştim, zamanlama anlamında büyük bir avantaj getirmiyor. Maskele ile aynı sonuçları almıştım. Ama tabii belki sizi bit maskelemekten kurtarır fakat aynı şeyi güzel bir macro ile sizde yazabilirsiniz.
Sadece bir değişken yada bir register üzerindeki bit manuplasyonu olarak ele alırsak haklısın. Fakat bilmem neredeki bir biti bilmem neredeki bir bitle AND le sonucu bilmem neredeki bite yerleştir tarzında bir işlemi, bir klasik yolla birde bit banding özelliğini kullanarak yaparsan aradaki fark şaşırtıcı olacaktır.
https://www.picproje.org/index.php/topic,36040.msg258436/topicseen.html#msg258436 (https://www.picproje.org/index.php/topic,36040.msg258436/topicseen.html#msg258436) başlığındaki bitbanding konusuna gözatmanı öneririm.
Alıntı yapılan: bunalmis - 02 Kasım 2011, 07:30:55
Sadece bir değişken yada bir register üzerindeki bit manuplasyonu olarak ele alırsak haklısın. Fakat bilmem neredeki bir biti bilmem neredeki bir bitle AND le sonucu bilmem neredeki bite yerleştir tarzında bir işlemi, bir klasik yolla birde bit banding özelliğini kullanarak yaparsan aradaki fark şaşırtıcı olacaktır.
https://www.picproje.org/index.php/topic,36040.msg258436/topicseen.html#msg258436 (https://www.picproje.org/index.php/topic,36040.msg258436/topicseen.html#msg258436) başlığındaki bitbanding konusuna gözatmanı öneririm.
Bit bandingi registerin bir bitini set/reset için denedim ve benim derleyicinin ve C özelliklerini kullanarak yazdığım bit library'yi kullanıp karşılaştırdım. Komut işleme zamanı olarak hemen hemen aynı sonuçlar aldım. Bit banding için sen pointer'e üzerinden işlem yapmışsın bense define ile tanımlama yazdım, yani doğrudan register adresini kullandım, normalde benim yazdığım kod daha optimize olacaktır. Çünkü derleyici daha derlemeden herşeyi hesaplıyor. Ayrıca sen hep A registeri üzerinde işlem yaptığın için başlangıç şartlarını derleyici 1 kez hesaba katıyor.
Senin bahsettiğin gibi bit banding ile 2-3 farklı registerin farklı bitlerini kullanarak bit üzerinden işlem yapmayı denemedim ama büyük bir fark olacağını sanmıyorum. Çünkü tek bit için ne yapması gerekiyorsa diğerleri içinde aynısını yapmalı ama tek bit üzerinde bir avantajı olsaydı kullanırdım.
Zaten eğer mesele optimizasyon ise, ST library'yi incelerseniz adamlar hiç optimize edelim, asm'ye yakın olsun diye hiç uğraşmamış, önemli olan anlaşılır, görsel, doğru ve hızlı yazılabilecek kodlama tekniği kullanmışlar. Gereksiz ram, pointer kullanımı tavan yapmış ama işte böyle büyük projeler yapılabilir yoksa çok yavaşlarsınız. Eğer kritik zamanlama gerekiyorsa asm kullanmak daha mantıklı. Bu söylediklerim (gereksiz ve fazladan kullanım) eski bir asm'ciye anlaşılması zor gelecektir ama ben daha önce bu durumu yaşamıştım.
Akşam siteye girebilirsem denediğim bit banding tanımlamasını eklerim.
Linkini verdiğim programda init aşaması geçildikten sonra, bit atamalarını sadece tek makine cycle'ında yapıyor.
Örneğin 10 adet biti tek tek set yada reset edeceksen bu sadece 10 makine cycle'ı demek. Bundan daha hızlı bit manuplasyonu da olmaz. (Her clockta bir bit set yada reset)
Hocam sırasımıdır ama;
Pic lerde data set değerlerimizi saklayabileceğimiz eeprom yapısı ARM larda yok sanırım. Bu durumu flash hafızayı kullanarak mı çözeceğiz yoksa harici eeprom mu kullanacağız?
4KB lık pilli ram var. O kullanılabilir. Flash'da kullanılabilir fakat bu konuda bilgim yok.
Alıntı yapılan: fahri- - 02 Kasım 2011, 13:45:13
Hocam sırasımıdır ama;
Pic lerde data set değerlerimizi saklayabileceğimiz eeprom yapısı ARM larda yok sanırım. Bu durumu flash hafızayı kullanarak mı çözeceğiz yoksa harici eeprom mu kullanacağız?
FLASH kullanılıyor. Örnek programda mevcut f1ler için. ancak örnek programda iyileştirmeler yapılmalı, pek yeterli değil.
Alıntı yapılan: bunalmis - 02 Kasım 2011, 10:16:25
Linkini verdiğim programda init aşaması geçildikten sonra, bit atamalarını sadece tek makine cycle'ında yapıyor.
Örneğin 10 adet biti tek tek set yada reset edeceksen bu sadece 10 makine cycle'ı demek. Bundan daha hızlı bit manuplasyonu da olmaz. (Her clockta bir bit set yada reset)
Merhaba,
peki, önce Gpioa odr registerinin 10bitini, sonra Gpiob odr registerinin 5 bitini set eder misin? Fakat pointerleri set edecekken hazırlamalısın yoksa bir anlamı kalmaz. Hız bakıyorsak herşey aynı anda olmalı.
Alıntı yapılan: eemkutay - 02 Kasım 2011, 14:11:14
Merhaba,
peki, önce Gpioa odr registerinin 10bitini, sonra Gpiob odr registerinin 5 bitini set eder misin? Fakat pointerleri set edecekken hazırlamalısın yoksa bir anlamı kalmaz. Hız bakıyorsak herşey aynı anda olmalı.
BitBand özelliğiyle hız kazanacaksam yöntemlerimi ben belirlerim.
#define PA10 (*(volatile unsigned short*) 0x424002A8)
#define PB5 (*(volatile unsigned short*) 0x42408294)
int main()
{
while(1)
{
PA10=1; // GPIOA_ODR da 10 nolu biti set et.
PB5=1; // GPIOB_ODR da 5 nolu biti set et.
PA10=0; // GPIOA_ODR da 10 nolu biti sil.
PB5=0; // GPIOA_ODR da 10 nolu biti sil. }
}
Alıntı yapılan: bunalmis - 02 Kasım 2011, 16:08:40
BitBand özelliğiyle hız kazanacaksam yöntemlerimi ben belirlerim.
#define PA10 (*(volatile unsigned short*) 0x424002A8)
#define PB5 (*(volatile unsigned short*) 0x42408294)
int main()
{
while(1)
{
PA10=1; // GPIOA_ODR da 10 nolu biti set et.
PB5=1; // GPIOB_ODR da 5 nolu biti set et.
PA10=0; // GPIOA_ODR da 10 nolu biti sil.
PB5=0; // GPIOA_ODR da 10 nolu biti sil.
}
}
Merhaba,
Senin yöntemlerini kullansakta aşağıda tek biti bir cycle'da set ettiğini göremedim. Ayrıca bu kullandığın yapı kullanışlı değil, benim daha öncede söylediğim gibi hangi registerin bitini set etmek istiyorsan o registerin adresini girebilecek bir macro veya tanımlama ile yazman daha doğru olur.
#define BitSet(RegAdr,BitNo,Set_Reset) gibi mesela
#define BitSet(GpioaOdr,10,Set)
#define BitSet(GpiobOdr,5,Reset)
[IMG]http://img43.imageshack.us/img43/9927/bitbanding.jpg[/img] (http://imageshack.us/photo/my-images/43/bitbanding.jpg/)
Bahsettiğim yöntemle bitbanding işlemini en hızlı yaparsın. ASM ile yazsak ulaşacağımız hız aynen bu olur.
Ben derlediğimde aşağıdaki ekran görüntüsünden de anlaşılacağı üzere bir bit manuplasyonu tamı tamına 1 cycle alıyor.
(http://www.cncdesigner.com/STM/onecycle.JPG)
Senin yapıyor dediğin resimde de 1 cycle değil, iar'daki gibi 3 asm komutu sonunda set ediliyor,
1) 0x08000286'da Pa0'ın adresini alıyor
2) 0x0800028A'da set edeceği değeri yani 1'i diğer reg'e yazıyor
3) 0x08000294'te de gerçekten set ediyor
yani 1 biti set etmek için 3 asm komutu çalıştırması gerekiyor. 3 cycle gerekli yani.
En kötümser durumda klasik manuplasyonla bir biti set etmek için
port adresini oku,
maskeleme verisini oku,
portu oku,
maskeleme verisi ile OR yap,
veriyi porta geri yaz
olmak üzere 5 adım gerekir.
Bitbanding işleminde ise en kötümser durumda
port adresini oku,
porta yazılacak veriyi oku (1)
bu veriyi porta yaz
olmak üzere 3 adım gerekir.
Dolayısı ile tartışmanın anlamı yok, bitbanding zamanlama açısından çok avantajlı.
En iyimser durumda ise bitbanding cycle başına 1 bit değişimi yapabilir. İki ayrı programda örnek verdim, inanmayan scopla pinlere bakar ve toggle etme frekansını ölçer.
Mesele tartışmak değil, 1 cycle'da 1 biti set ediyor olsa çok kullanışlı olacaktı ama öyle değil maalesef, minimum 3 asm komutu çalıştırması gerekiyor dolayısıyla 3 cycle gerekli. Bunu scopla ölçmeye gerek yok, port pinlerinden registerlere yazmadan çıkacak değil.
Neden ısrar ediyorsun anlamıyorum. while döngüsünde 1 cycle da 1 bit set ediliyor işte. Bu en iyimser duruma denk geliyor.
Kendi derlediğin kodlara bakma benim derlediğim kodlara bak. Senin derleyici optimizasyon yapamamış yada sen yaptırmamışsın.
İnit aşamasına takılma ve while döngüsüne iyi dikkat et. Sadece 5 komut var. 5. cisi loop için diğer 4 tanesi de bit set reset işleri yapıyor.
(http://www.cncdesigner.com/STM/onecycle.JPG)
İşte hata yaptığın noktada orası zaten, while içinde hep aynı yerde dönüyor diyorsun ama register adresleri ve bit değerleri değişmediği için aynı yerde dönüyor, yoksa 3 asm komutu işletmek zorunda kalacak derleyici.
Alıntı Yapbunalmış hocam yanlış değerlendiriyorsunuz, işaretlediğiniz kısmın üstünde de işlemler var sizin bitler ile ilgili olarak. onları da dahil edin. en az 3 cycle
Peki sizleri kırmayayım.
Alın size daha önce verdiğim kod. 1 cycle da 1 bit manüplasyonu.
#define PA10 (*(volatile unsigned short*) 0x424002A8)
#define PB5 (*(volatile unsigned short*) 0x42408294)
int main()
{
while(1)
{
PA10=1; // GPIOA_ODR da 10 nolu biti set et.
PB5=1; // GPIOB_ODR da 5 nolu biti set et.
PA10=0; // GPIOA_ODR da 10 nolu biti sil.
PB5=0; // GPIOA_ODR da 10 nolu biti sil.
}
}
Alın buda ikinci ve yavaş olanı. #define PA10 (*(volatile unsigned short*) 0x424002A8)
#define PB5 (*(volatile unsigned short*) 0x42408294)
void Manuple()
{
PA10=1; // GPIOA_ODR da 10 nolu biti set et.
PB5=1; // GPIOB_ODR da 5 nolu biti set et.
PA10=0; // GPIOA_ODR da 10 nolu biti sil.
PB5=0; // GPIOA_ODR da 10 nolu biti sil.
}
int main()
{
while(1) Manuple
}
Alıntı yapılan: eemkutay - 02 Kasım 2011, 20:01:29
İşte hata yaptığın noktada orası zaten, while içinde hep aynı yerde dönüyor diyorsun ama register adresleri ve bit değerleri değişmediği için aynı yerde dönüyor, yoksa 3 asm komutu işletmek zorunda kalacak derleyici.
Bunu zaten söyledik değilmi. En kötü durumda 3 Cycle olur diye.
int main()
{
while(1)
{
PA10=1; // GPIOA_ODR da 10 nolu biti set et.
PB5=1; // GPIOB_ODR da 5 nolu biti set et.
PB5=0; // GPIOB_ODR da 5 nolu biti set et.
PA10=0; // GPIOA_ODR da 10 nolu biti sil.
PB5=0; // GPIOA_ODR da 10 nolu biti sil.
PB5=1; // GPIOB_ODR da 5 nolu biti set et.
PA10=1; // GPIOB_ODR da 5 nolu biti set et.
PA10=1; // GPIOB_ODR da 5 nolu biti set et.
PA10=0; // GPIOB_ODR da 5 nolu biti set et.
}
}
Oldumu? Gene Cycle başına 1 manüplasyon. İstersen C portunu ilave edeyim. Olmadı D pottunu.
Belli bir port sayısına kadar tek cycleda tek manüplasyonu yapılabilir. Görün artık bunu.
Gerbay ARM asm yi bilirim.
Benim kodlarim oyle cikmaz. Cunku kodlarim immediate index adresleme kullaniyor.
ARM da cok farkli sekillerde yogurt yemeyi bilirim. Mesela verdigin yontem bunlardan birisi ve uzun yoldan yogurt yeniyor.
Elinizde ADR1 ve ADR2 omak uzere iki hedef adres ollsun. Ornegin R2 registerine ADR1 degerini yuklediginizde ADR2 ye ulasmak icin yapmaniz gereken tek sey R2,#Ofset degerini kullanmak olacaktir. Ancak ADR1-ADR nin mutlak degeri kullanilacak komutlarin narrow yada wide olusuna gore belli bir aralikta olmak zorundadadir.
Fakat verdigim kisa kod (eemkutayin yazmami istedigi kod) gerek ASM kullanıcılarını C'ye alıştırma turları (https://www.picproje.org/index.php/topic,36040.0.html) https://www.picproje.org/index.php/topic,36040.0.html (https://www.picproje.org/index.php/topic,36040.0.html)
linkinde verdigim uzun program her cycle da bir bir manuplasyonu yapacak kapasitededir. Ofset degerleri secilen register adres uzakliklari icin uygundur.
Bir bitr atanabilecek deger ya 1 yada 0 olacagindan bunlari da R0 ve R1 icine koyarsaniz geriye store komutlari kullanmak kalir.
STR Rn,[R2,#ofset1]
STR Rn,[R2,#ofset2]
STR Rn,[R2,#ofset3]
STR Rn,[R2,#ofset4]
STR Rn,[R2,#ofset5]
STR Rn,[R2,#ofset6]
....
....
STR Rn,[R2,#ofset9]
STR Rn,[R2,#ofset10]
STR Rn,[R2,#ofset11]
STR Rn,[R2,#ofset12]
STR Rn,[R2,#ofset13]
STR Rn,[R2,#ofset14]
....
....
Seklinde bir suru bit manuplasyon komutunu ardi ardina yazarak manuplasyon yapabilirsiniz. Burada Rn yerine R0 yazarsaniz biti 0 lar, Rn yerine 1 yazarsaniz biti 1 yaparsiniz.
Burada STR lerin her biri bir manuplasyon yapar. Cunku bitband adres alanina erisilmektedir. Ofsetlerin her biri de R2 nin otesinde bir baska adres. Bu sayede sadece ofseti degistirerek R2 ye deger atmaktan kurtulmus oluyorum.
Kisacasi ARM in nasil yogurt yedigini cok iyi biliyorum.
Fakat bu demek değilki istenen her bitband islemini tek cycle da yapacak kod yazabilirim. Bunu belirtmistim. En kotu ihtimalle 3 cycle da yazarim.
Alıntı yapılan: bunalmis - 02 Kasım 2011, 20:31:51
Bunu zaten söyledik değilmi. En kötü durumda 3 Cycle olur diye.
int main()
{
while(1)
{
PA10=1; // GPIOA_ODR da 10 nolu biti set et.
PB5=1; // GPIOB_ODR da 5 nolu biti set et.
PB5=0; // GPIOB_ODR da 5 nolu biti set et.
PA10=0; // GPIOA_ODR da 10 nolu biti sil.
PB5=0; // GPIOA_ODR da 10 nolu biti sil.
PB5=1; // GPIOB_ODR da 5 nolu biti set et.
PA10=1; // GPIOB_ODR da 5 nolu biti set et.
PA10=1; // GPIOB_ODR da 5 nolu biti set et.
PA10=0; // GPIOB_ODR da 5 nolu biti set et.
}
}
Oldumu? Gene Cycle başına 1 manüplasyon. İstersen C portunu ilave edeyim. Olmadı D pottunu.
Belli bir port sayısına kadar tek cycleda tek manüplasyonu yapılabilir. Görün artık bunu.
Olmadı, boşu boşuna inat ediyorsun. Başlangıçta hazırlanmış registerler üzerinden işlem yapıyorsun ve bakın 1 cycle'da oldu diyorsun. Bunu bildiğin için "Belli bir port sayısına kadar tek cycleda tek manüplasyonu yapılabilir" diyosun. Bu bit banding özelliği değil, bu çok working registerli işlemci özelliğidir. İşlemcinin ana registerleri, işlem yapılacak register adreslerini ve bit değerlerini hafızada tutturuyor ve başka işlem yapmadığı için o registerler üzerinde işlem yapmak icap etmiyor ve while içinde döndürdüğü için sanki tek cycle'da işliyormuş gibi söylüyorsun. Oysa farklı farklı registerlerin adreslerini kullansan ve araya işlemcinin working registerlerini kullanmak zorunda olduğu kodlar girse ne demek istediğimi anlıyacaksın.
Inat eden ben degilim sizsiniz. Cunku vermis oldugum orneklere inat eden sizsiniz.
Ozellikle belirtmeme ragmen her istediginiz bitbanding islemini tek cycle da yapacak kod yazamam 3 asm kod gerektirebilecek durumlar var dedim. Yapmami istediginiz A ve B portunda 10 ve 5 nolu bitleri manuple ettim degilmi?. Daha yuzlerce hatta binlerce ornek de yazabilirim. Bu orneklerin hepsi de tek cycle da bitbanding yapar.
Alıntı YapARM mimarisinde herhangi bir memory adresine direk değer yazabiliyormuyuz? böyle bir opcode var mı ARM da?
ARM mimarisinde boyle bir komut yok. Fakat, bit manuplasyonunda manuple edilebilecek deger ya sifir ya da bir dir. Asagida ne denek istedigimi anlayacaksiniz.
Bakin
R2=0x? ? ? Hedef adreslerden birisi.
R0=0
R1=1
STR R0,[R2] // Bununla bir manuplasyon yaptim bunu takip eden satirda
STR R0,[R2,#4] // Bununla bir baska manuplasyon yaptim
STR R1,[R2,#8] // Bununla bambaska bir baska manuplasyon yaptim
....
....
Bu boye gider.
Ben memorye registersiz deger mi atiyorum da bana bu soruyu yoneltiyorsunuz. Sadece en tepede bir kereye mahsus
R2=0x? ? ? Hedef adres
R0=0
R1=1
atamasi yaptim. Daha sonra da basladim bit manuplasyonu yapmaya. Artik ne R0 ne R1 ne de R2 ile oynuyorum. Anlastikmi?
Burada beni limitleyen ne? Soyleyeyim [R2,#ofset] yaziminda ofsetin alabilecegi max ve min degerlerler. Bu bana sinir getiriyor. Bu sinirlar icinde kaldigim surece
her bir komutta bambaska bir biti 1 yada sifir yapiyorum.
Alıntı yapılan: bunalmis - 02 Kasım 2011, 21:40:28
Inat eden ben değilim sizsiniz. Cunku vermis oldugum orneklere inat eden sizsiniz.
Ozellikle belirtmeme ragmen her istediginiz bitbanding islemini tek cycle da yapacak kod yazamam 3 asm kod gerektirebilecek durumlar var dedim. Yapmami istediginiz A ve B portunda 10 ve 5 nolu bitleri manuple ettim değilmi?. Daha yuzlerce hatta binlerce ornek de yazabilirim. Bu orneklerin hepsi de tek cycle da bitbanding yapar.
Neyse bildiğini yap, yanlışta ısrar iyi bir davranış değildir. Daha önceki tartışmalarımızda da aynı şeyleri yapmıştın.
Yukarida yazdiklarimi okursan bana hak vereceksin.
Ben seni anladim ama sen anlamamakta israr ediyorsun.
Mesela bana deki bana bir genel amacli fonksiyon yaz
Bu fonksiyona adresi ve bit numarasini vereyim bana tek cycle da manuplasyon yap de. Tek cycle da yapamam.
Fakat bana GPIOA nin 10 nolu pinini ardindan da GPIOB nin 5 nolu bitini tek cycle da manuple et ederim. Ettim de.
Neyse benim acimdan da tartisma bitmistir.
Fakat hem eemkutaydan hem de Gerbay asagidaki soruya cevap olacak hizli kosan kodu yazarlarsa sevinirim.
Soru basit.
A[3] seklinde arrayim var.
A[0] ve A[1] in yuksek 4 biti sifirdir.
A[0]'nin dusuk bitleri, A3 A2 A1 A0
A[1]'nin dusuk bitleri, B3 B2 B1 B0 dir.
Program;
A[0] ve A[1] den alacagi bitleri A[2] icine A3 B0 A1 B2 A0 B1 A2 B3 siralamasiyla yazacaktir.
Basarilar.
Alıntı yapılan: bunalmis - 02 Kasım 2011, 21:59:55
Yukarida yazdiklarimi okursan bana hak vereceksin.
Ben seni anladim ama sen anlamamakta israr ediyorsun.
Mesela bana deki bana bir genel amacli fonksiyon yaz
Bu fonksiyona adresi ve bit numarasini vereyim bana tek cycle da manuplasyon yap de. Tek cycle da yapamam.
Fakat bana GPIOA nin 10 nolu pinini ardindan da GPIOB nin 5 nolu bitini tek cycle da manuple et ederim. Ettim de.
Asm ve C bilgim oldukça iyidir, bana göre hatalısın. Bitbanding 3 cycle'da, benim yazdığım library 5 cycle'da derleniyor. Tek bit için bit banding 2 cycle avantajlı ama her register adresini tek tek tanımlamak lazım, eğer daha lüks istersen bit isimlerinide tanımlayabilirsin ama aşağıdaki lükse erişmek biraz zor olur. Ve ben istersem aynı anda 3 biti değiştirim bu durumda bit banding 4 cycle yavaş kalır ve 3 kod yazmam gerekir.
[IMG]http://img214.imageshack.us/img214/1103/lib1n.jpg[/img] (http://imageshack.us/photo/my-images/214/lib1n.jpg/)[IMG]http://img213.imageshack.us/img213/7590/lib2.jpg[/img] (http://imageshack.us/photo/my-images/213/lib2.jpg/)
[IMG]http://img513.imageshack.us/img513/1979/lib3b.jpg[/img] (http://imageshack.us/photo/my-images/513/lib3b.jpg/)[IMG]http://img214.imageshack.us/img214/3905/lib4.jpg[/img] (http://imageshack.us/photo/my-images/214/lib4.jpg/)
Sadece sordugum soruya cevap olacak kodu yazmaniz benim icin fazlasiyla yeterli olacaktir.
Alıntı yapılan: bunalmis - 02 Kasım 2011, 22:36:03
Sadece sordugum soruya cevap olacak kodu yazmaniz benim icin fazlasiyla yeterli olacaktir.
Bende soru yazayım sizde bitbanding ile onu bana yazın.
STM içindeki Gpioa_odr, b,c,d odr'nin gerçek adreslerini kullanarak bir dizi oluşturun. Bu diziyi ve adresleri kullanarak, sırasıyla registerlerin 10.bitlerini bitbanding kullanarak set ediniz?
Alıntı yapılan: gerbay - 02 Kasım 2011, 22:51:12
hocam fantazimi yoksa pratikte faydası olacak birşey mi?
hayatımda hiç böyle birşeye ihtiyaç duymadım
Bit manuplasyonu icin guzel bir ornek. Kriptolojide benzer uygulamalari var.
Bir zamanlar cift yuzlu plaket yaptiramazken pcbmi tek yuzde cizer ve epromun datalarini ayni sirayi takip etmeden cpu nun datalarina nasil atlamasiz bagliyorsam oyle baglardim. Benzer sekilde adres bacaklarini da atlama vs olmaycak sekilde baglardim. Ancak eproma atilacak verilerin bu caprazlamadan etkilenmemesi icin aynen soruma benzer sekilde yeni bastan siralanmasi gerekirdi. Bunun avantaji ne olurdu? Tek yuzlu miniminnacik plakete sigdirilmis cpu karti.
Sanirim gercek bir uygulama sorusu.
Alıntı yapılan: eemkutay - 02 Kasım 2011, 22:52:01
Bende soru yazayım sizde bitbanding ile onu bana yazın.
STM içindeki Gpioa_odr, b,c,d odr'nin gerçek adreslerini kullanarak bir dizi oluşturun. Bu diziyi ve adresleri kullanarak, sırasıyla registerlerin 10.bitlerini bitbanding kullanarak set ediniz?
Istiyorsan yazarim ancak hizli calisan kod istersen bitband vs yonteme kendim karar veririm. Birde C mi olsun?
Alıntı yapılan: bunalmis - 02 Kasım 2011, 22:58:23
Istiyorsan yazarim ancak hizli calisan kod istersen bitband vs yonteme kendim karar veririm. Birde C mi olsun?
Mesele C ile program yazmak değil ki amacımız bit banding'i test etmek, burada değişken adresler var ve program çalışırken bu adresler alınıyor bu durumda bit banding ne işe yarayacak bakalım. Yazacaksan bit set etmek için tek seçeneğin var ve bit banding kullanmak.
Şu an ki konuyla alakasız ama aklıma geldi diğer başlık kapalı olduğundan buradan sormak istedim;
siparişler verileli 1 hafta oldu galiba sonrasında bir bilgilendirilme yapılmadı haftaya kartlar gelecek mi bir bilginiz var mı?
bir de C konusunda herkesin yeterli düzeye gelmesine yetecek kadar örnekler verildi sanıyorum,
işlemcimiz üzerinde kaldığımız yerden ne zaman devam edebiliriz?
Anladim tamam yazayim. Aksilik cikarsa en gec yarina siteye koyarim.
Harfi harfine asagidaki soru icin kod yazacagim. (Seni sasirtacagim)
STM içindeki Gpioa_odr, b,c,d odr'nin gerçek adreslerini kullanarak bir dizi oluşturun. Bu diziyi ve adresleri kullanarak, sırasıyla registerlerin 10.bitlerini bitbanding kullanarak set ediniz?
Sende benim soruma ugras.
Alıntı yapılan: ErsinErce - 02 Kasım 2011, 23:13:46
Şu an ki konuyla alakasız ama aklıma geldi diğer başlık kapalı olduğundan buradan sormak istedim;
siparişler verileli 1 hafta oldu galiba sonrasında bir bilgilendirilme yapılmadı haftaya kartlar gelecek mi bir bilginiz var mı?
bir de C konusunda herkesin yeterli düzeye gelmesine yetecek kadar örnekler verildi sanıyorum,
işlemcimiz üzerinde kaldığımız yerden ne zaman devam edebiliriz?
+1
Alıntı yapılan: bunalmis - 02 Kasım 2011, 23:18:10
Anladim tamam yazayim. Aksilik cikarsa en gec yarina siteye koyarim.
Harfi harfine asagidaki soru icin kod yazacagim. (Seni sasirtacagim)
STM içindeki Gpioa_odr, b,c,d odr'nin gerçek adreslerini kullanarak bir dizi oluşturun. Bu diziyi ve adresleri kullanarak, sırasıyla registerlerin 10.bitlerini bitbanding kullanarak set ediniz?
Sende benim soruma ugras.
Tamam, sende bit banding'in tek cycle'da bit set reset işlemini yapacağın bu örnekte yaparsın.
Bir dakika tek cycle demedik. Nerden cikti bu. Adres tablosundan adresi okuyup gelmek zaten bir kac cycle alir.
Adresleri de bitbanding adres yerlestirmeme izin vermeyip fiziksel port adresi kullan dedin. Bit band adresleri olusturmam bile bir kac cycle alir.
10 nolu bitleri set edecektim simdi de set reset cikti.
Yok yok saka bu. Yada kabus.
Alıntı yapılan: bunalmis - 02 Kasım 2011, 23:36:52
Bir dakika tek cycle demedik. Nerden cikti bu. Adres tablosundan adresi okuyup gelmek zaten bir kac cycle alir.
Adresleri de bitbanding adres yerlestirmeme izin vermeyip fiziksel port adresi kullan dedin. Bit band adresleri olusturmam bile bir kac cycle alir.
10 nolu bitleri set edecektim simdi de set reset cikti.
Yok yok saka bu. Yada kabus.
@Bunalmış
Yok sorudaki gibi olacak, reset olmayacak. Ama diziden adresi okuduktan sonra her registerin bitini set etmen için bit banding kullancaksın ve bit banding bir cycle bunları nasılsa biliyorsun, sen söylemiştin. Şimdi bunu gerçeklemeni istiyorum.
Öyle derleyicinin yerine herşeyi sen hesaplayıp bitin doğrudan adresini define ederek olmaz. Gerçek uygulamalarda veriler anlıktır ve ne olduğu belirsizdir. Burada da registerlerin adresleri belirsiz(yani derleyici bilmiyor) ve anlık olarak okuyup bit banding yapacak tümü bu.
Böyle test etmek gerçek performansını verecektir çünkü gerçek uygulamalar da adresler ve bitler değişkendir.
Çok fazla bilemediğimden tartışmaya katılamıyorum ancak okuduğum kadarıyla ;
Alıntı YapBit-banding maps a complete word of memory onto a single bit in the bit-band region. For example, writing to one of the alias words sets or clears the corresponding bit in the bit-band region. This enables every individual bit in the bit-banding region to be directly accessible from a word-aligned address using a single LDR instruction. It also enables individual bits to be toggled without performing a read-modify-write sequence of instructions.
Ayrıca okuduğum dökümanın birinde de bir örnek vermiş ;
http://www.scribd.com/doc/61618474/19/Bit-Banding (http://www.scribd.com/doc/61618474/19/Bit-Banding)
Alıntı YapFor a practical example, the GPIO output data register is
written to in order to set and clear individual IO lines. The physical address of the Port B output register is
0x40010C0C. In this example we want to be able to set and clear bit eight of this word using the above formula.
Word address = 0x40010C0C
Peripheral bit band base = 0x40000000
Peripheral bit band Alias base = 0x42000000
Byte offset from bit band base = 0x40010c0c – 0x40000000 = 10c0c
Bit word offset = (0x10c0c x 0x20) +(8x4) = 0x2181A0
Bit Alias address = 0x42000000 + 0x2181A0 = 0x422181A0
We can now create a pointer to this address using the following line of C:
#define PortBbit8 (*((volatile unsigned long *) 0x422181A0 ))
This pointer can then be used to set and clear the IO port bit:
PB8 = 1; //led on
Which generates the following assembly instructions:
MOVS r0,#0x01
LDR r1,[pc,#104]
STR r0,[r1,#0x00]
Switching the LED off:
PB8 = 0; //led off
Generates the following assembly instructions:
MOVS r0,#0x00
LDR r1,[pc,#88]
STR r0,[r1,#0x00]
Both the set and clear operations take three 16-bit instructions and on the STM32 running at 72 MHz these
instructions are executed in 80nsec. Any word in the peripheral and SRAM bit band regions can also be directly
addressed word-wide so we could perform the same set and clear using the more traditional AND and OR
approach:
GPIOB->ODR |= 0x00000100; //LED on
LDR r0,[pc,#68]
ADDS r0,r0,#0x08
LDR r0,[r0,#0x00]
ORR r0,r0,#0x100
LDR r1,[pc,#64]
STR r0,[r1,#0xC0C]
GPIOB->ODR &=!0x00000100; //LED off
LDR r0,[pc,#40]
ADDS r0,r0,#0x08
LDR r0,[r0,#0x00]
MOVS r0,#0x00
LDR r1,[pc,#40]
STR r0,[r1,#0xC0C]
Now each set and clear operation takes a mixture of 16 and 32-bit operations, which take a minimum of 14 bytes
for each operation and at the same clock frequency take a minimum of 180 nSec. If you consider the impact of bit
banding on a typical embedded application that sets and clears lots of bits in the peripheral registers and uses
semaphores and flags in the SRAM, you are very clearly going to make significant savings in both code size and
execution time and it is all handled in the STM32 header file for you.
Şimdi burada açık olarak daha hızlı olduğunu yazıyor, acaba bizim başlıkda yazılan kodlar daha mı optimize ? ve yaklaşık aynı hızda çıkıyor yoksa komutların 16-32 bit olduğunu hesaplamıyor muyuz?Belkide döküman hatalıdır,ya da eski.
while()
{
Tablo[0] dan_GPIOA_ODR adresini oku bundan yararlanip 10. biti high yap. (Diger bitler bilinmiyor ve ayni kalsin)
Tablo[0] dan_GPIOA_ODR adresini oku bundan yararlanip 10. biti low yap. "
Tablo[1] dan_GPIOB_ODR adresini oku bundan yararlanip 10. biti high yap. "
Tablo[1] dan_GPIOB_ODR adresini oku bundan yararlanip 10. biti low yap. "
Tablo[2] dan_GPIOC_ODR adresini oku bundan yararlanip 10. biti high yap. "
Tablo[2] dan_GPIOC_ODR adresini oku bundan yararlanip 10. biti low yap. "
Tablo[3] dan_GPIOD_ODR adresini oku bundan yararlanip 10. biti high yap. "
Tablo[3] dan_GPIOD_ODR adresini oku bundan yararlanip 10. biti low yap. "
}
Sonra 10 nolu bitlerin karsi geldigi pinlerden herhangi birinden scopla frekansi olc.
Ancak bu sartlarda bitbanding i klasik maskeleme metoduna gore mukayese edebilirsin.
Alıntı yapılan: eemkutay - 02 Kasım 2011, 23:51:57
@Bunalmış
Yok sorudaki gibi olacak, reset olmayacak. Ama diziden adresi okuduktan sonra her registerin bitini set etmen için bit banding kullancaksın ve bit banding bir cycle bunları nasılsa biliyorsun, sen söylemiştin. Şimdi bunu gerçeklemeni istiyorum.
Öyle derleyicinin yerine herşeyi sen hesaplayıp bitin doğrudan adresini define ederek olmaz. Gerçek uygulamalarda veriler anlıktır ve ne olduğu belirsizdir. Burada da registerlerin adresleri belirsiz(yani derleyici bilmiyor) ve anlık olarak okuyup bit banding yapacak tümü bu.
Böyle test etmek gerçek performansını verecektir çünkü gerçek uygulamalar da adresler ve bitler değişkendir.
Olmaz boyle sey. Bitbandingin ne zaman 1 ne zaman 3 cycle olacagini soylemistim zaten. Fakat bindbandingle senin klasik yolla yapacagin manuplasyondan daha hizli manuplasyon yaparim bunda iddialiyim.
Dikkat ettiysen ilk bastaki sorun her defasinda degisti de degisti. Simdi de 10 nolu bitin de degisebilecegini ima ediyorsun.
hocam şu anki konuyla alakalı değil ama kafama takılan iki soru var
1 noktalı sayılar float işlemler
2 c de bölme işleminde kalan
yani en basitinden kök almak için bir fonksiyon gibi bişi yazmak istesek yanlış hatırlamıyorsam kalanı kullanmamız gerekir
Alıntı yapılan: bunalmis - 03 Kasım 2011, 00:07:00
Olmaz boyle sey. Bitbandingin ne zaman 1 ne zaman 3 cycle olacagini soylemistim zaten. Fakat bindbandingle senin klasik yolla yapacagin manuplasyondan daha hizli manuplasyon yaparim bunda iddialiyim.
Dikkat ettiysen ilk bastaki sorun her defasinda degisti de degisti. Simdi de 10 nolu bitin de degisebilecegini ima ediyorsun.
Soru aynı değişen bişey yok. Bu soruda benim amacım derleyicinin bilmediği adreslerde bit banding'i kullanmasıydı ama sorunun cevabını yazmana gerek yok çünkü senin define için kullandığın tüm matematiği derleyici her bir register için yapmak zorunda bu da nerden baksan herbir biti set etmek için yaklaşık 10 cycle harcayacak demektir.
Sanırım anlaşamıyacağız, en güzeli herkes kendi bildiği yoldan yapsın.
Hocalar-ustalar verdiğim dökümanda yazan doğrumu yanlışmı?
@mcan Yazdiklarin dogru.
Herhangi bir adresin herhangi bir bitini herhangi bir zamanda hic bir kurala bagli kalmaksizin bitband yontemi ile degistirmek icin 3 cpu komutu gerekiyor ve klasik maskeleme yontemine gore daha hizli.
Ancak bunun icin malesef kullanacagin her bir bitin bitband alandaki adresini define ile tanimlaman gerekiyor.
Aynen header dosyalarda her bir register adresinin define ile sayfalar dolusu tanimlandigi gibi.
Fakat ben bit tanimlama yapmam dersen de bu hizlara da cikamazsin. Cunku adres hesabini yazilima yaptirmak zaman kaybettirir.
Gerektigi yerde uygun olani secilir.
artık kitler gelsede şu sessizlik bozulsa :D
Kotu fakat guzel tecrube.
Ne kadar tezat değilmi.
eemkutayin yazmami istedigi programi yazarken daha once sizlere onerdigim SystemInit() fonksiyonunun hemen girisindeki delay rutinini koymayi unutup paldir kultur
programi yazdim.
Kodlar startup fonksiyonuna girer girmez port clock sinyallerini aciyor ve GPIOA, GPIOB, GPIOC, GPIOD nin 10. bitini output geri kalanlari da input tanimliyordu.
Bu inanilmaz affedilemez bir hata.
Cunku bu GPIOA PA14 ve PA13 u input moduna ceviriyor. http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf) dokumaninin 31. sayfasindan bakarsaniz bu pinlerin SWD yani software debugging yani karta program yuklemeye ve debug etmeye yarayan pinler oldugunu goreceksiniz. (Cipimiz flashdan boot edince hatali yazdigim systeminit den dolayi derhal Port A yi I/O tanimlayarak SWD yi kapiyordu.)
Haliyle kartima program yukleyemez oldum ve Keil debug moduna sokuldugunda Kart bulunamiyor benzeri mesaj vermeye basladi.
Bunun uzerine https://www.picproje.org/index.php/topic,35721.0.html (https://www.picproje.org/index.php/topic,35721.0.html) basliginda bahsettigim BOOT0 ve BOOT1 pinleri aklima geldi ve Boot0 pininin konumunu degistirmeye karar verdim. Boylece karti flashdan değil de diger kaynaklardan boot edebilecektim. Ramda sacma sapan cop bilgiler olsada bu kodlar SystemInitteki kodlardan daha kotu olamazdi.
Kartimizda BOOT0 pini lowda. BOOT1 pini 1 de. Bu cipin flashdan boot edecegi anlamina geliyor.
Kartin arkasindaki SB18 olarak gosterilen direnci sokunce BOOT0 pinini High yaptim. Yanlis olan ve bu hataya neden olan SystemInit rutinini duzeltip derledim ve karta bu vaziyette program yuklemeyi denedigimde SWD den program atildi. Daha sonra da kartimin SB18 jumperini eski haline getirdim ve kartimi tekrardan kullanabilir hale getirdim.
Bence kotu ve bir okadar da guzel bir tecrube oldu.
Aman dikkat.Bu hataya dusmeyin. Cozumu olsa da adami telaslandiriyor.
Yalniz bu yaptigim kurtarma islemi Flashi nasil sildi bilmiyorum. Flash harici kaynaklardan boot edince PCdeki SWD yazilimi flashi siliyor olabilir. (?)
@Eemkutay ,size bir sorum olacak,normalde yazdiginiz programlarda bit set etmek icin bit band kullanmiyormusunuz yada sizin kullandiginiz genel yapi nasil ? Verdiginiz h dosyasinin icerigine bakarak anladigim kadariyla structure yapisinda registerlarin bitleri tanimlanmis dogru mu? Birde nokta isaretinden sonra derleyici otomatik icerik seceneklerini gosteriyor dogru mu?
Alıntı yapılan: bunalmis - 03 Kasım 2011, 01:35:53
Kotu fakat guzel tecrube.
Ne kadar tezat değilmi.
eemkutayin yazmami istedigi programi yazarken daha once sizlere onerdigim SystemInit() fonksiyonunun hemen girisindeki delay rutinini koymayi unutup paldir kultur
programi yazdim.
Kodlar startup fonksiyonuna girer girmez port clock sinyallerini aciyor ve GPIOA, GPIOB, GPIOC, GPIOD nin 10. bitini output geri kalanlari da input tanimliyordu.
Bu inanilmaz affedilemez bir hata.
Cunku bu GPIOA PA14 ve PA13 u input moduna ceviriyor. http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf) dokumaninin 31. sayfasindan bakarsaniz bu pinlerin SWD yani software debugging yani karta program yuklemeye ve debug etmeye yarayan pinler oldugunu goreceksiniz. (Cipimiz flashdan boot edince hatali yazdigim systeminit den dolayi derhal Port A yi I/O tanimlayarak SWD yi kapiyordu.)
Haliyle kartima program yukleyemez oldum ve Keil debug moduna sokuldugunda Kart bulunamiyor benzeri mesaj vermeye basladi.
Bunun uzerine https://www.picproje.org/index.php/topic,35721.0.html (https://www.picproje.org/index.php/topic,35721.0.html) basliginda bahsettigim BOOT0 ve BOOT1 pinleri aklima geldi ve Boot0 pininin konumunu degistirmeye karar verdim. Boylece karti flashdan değil de diger kaynaklardan boot edebilecektim. Ramda sacma sapan cop bilgiler olsada bu kodlar SystemInitteki kodlardan daha kotu olamazdi.
Kartimizda BOOT0 pini lowda. BOOT1 pini 1 de. Bu cipin flashdan boot edecegi anlamina geliyor.
Kartin arkasindaki SB18 olarak gosterilen direnci sokunce BOOT0 pinini High yaptim. Yanlis olan ve bu hataya neden olan SystemInit rutinini duzeltip derledim ve karta bu vaziyette program yuklemeyi denedigimde SWD den program atildi. Daha sonra da kartimin SB18 jumperini eski haline getirdim ve kartimi tekrardan kullanabilir hale getirdim.
Bence kotu ve bir okadar da guzel bir tecrube oldu.
Aman dikkat.Bu hataya dusmeyin. Cozumu olsa da adami telaslandiriyor.
Yalniz bu yaptigim kurtarma islemi Flashi nasil sildi bilmiyorum. Flash harici kaynaklardan boot edince PCdeki SWD yazilimi flashi siliyor olabilir. (?)
@Bunalmış böyle bir sonuç olmasına üzüldüm ama problemini çözmüşsün bu iyi,
@mcan
evet, register blocklarını gösteriyorum mesela RccRegs,GpioaRegs,CanRegs gibi, sonra registere ulaşan ve register içine bits/b8/b16/b32 olarak erişim sağlayan yapılar kurdum. B16 için low ve hi olarak düşük ve yüksek mertebeli 16bite erişen bir yapı, bits için ise aynı registerlerde isimleri kullandım, 8bit için ise dizi şeklinde yapılar kurdumki indexle istediğim gibi yazabileyim. Ayrıca istediğim donanım modulu cinsinden type'lar tanımladım mesela DMA,CAN,USART,TMR,GPIO...vs. kanallarından birini hazırlayacağım diyelim DMAxInit, CANxInit.vb diye tek fonksiyon var ve bu tüm DMA kanallarını hazırlayabiliyor. Kendi sitemde de dediğim gibi bu yaklaşık 15 günümü aldı ama şimdi rahatım. Zaman geçtikçede daha fazla konfor getiriyorum. Problemler çıkmadı mı? çıktı tabii ki, çünkü pointerlerle uğraşıyorsun ama nerdeyse tüm donanım modüllerini pratik uygulamalarda denedim, sorunsuz çalışıyor, çıkan problemleride düzelttim.
İstersem st library'de benim library'ye entegre edebiliyorum, hatta öyle hazırladım ki yapıyı, istersem bit bit yazarım istersem doğrudan 1-32bit arası yazarım , istersem bu kadar biti maskeleyip yazarım. Çok fonksiyonel oldu, çok zamanımı aldı fakat bu beni nerden baksan 5yıl götürür.
ST'nin diğer güzel yanı, register yapılarını ve isimlerini değiştirmiyor az modifiye ile STM32f2xx, stm32f4xx serine kolayca adapte debilirim ve daha önce yazdığım programlar kolaylıkla çalışacaktır.
Alıntı yapılan: bunalmis - 03 Kasım 2011, 01:35:53
Kotu fakat guzel tecrube.
Ne kadar tezat değilmi.
eemkutayin yazmami istedigi programi yazarken daha once sizlere onerdigim SystemInit() fonksiyonunun hemen girisindeki delay rutinini koymayi unutup paldir kultur
programi yazdim.
Kodlar startup fonksiyonuna girer girmez port clock sinyallerini aciyor ve GPIOA, GPIOB, GPIOC, GPIOD nin 10. bitini output geri kalanlari da input tanimliyordu.
Bu inanilmaz affedilemez bir hata.
Cunku bu GPIOA PA14 ve PA13 u input moduna ceviriyor. http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf) dokumaninin 31. sayfasindan bakarsaniz bu pinlerin SWD yani software debugging yani karta program yuklemeye ve debug etmeye yarayan pinler oldugunu goreceksiniz. (Cipimiz flashdan boot edince hatali yazdigim systeminit den dolayi derhal Port A yi I/O tanimlayarak SWD yi kapiyordu.)
Haliyle kartima program yukleyemez oldum ve Keil debug moduna sokuldugunda Kart bulunamiyor benzeri mesaj vermeye basladi.
Bunun uzerine https://www.picproje.org/index.php/topic,35721.0.html (https://www.picproje.org/index.php/topic,35721.0.html) basliginda bahsettigim BOOT0 ve BOOT1 pinleri aklima geldi ve Boot0 pininin konumunu degistirmeye karar verdim. Boylece karti flashdan değil de diger kaynaklardan boot edebilecektim. Ramda sacma sapan cop bilgiler olsada bu kodlar SystemInitteki kodlardan daha kotu olamazdi.
Kartimizda BOOT0 pini lowda. BOOT1 pini 1 de. Bu cipin flashdan boot edecegi anlamina geliyor.
Kartin arkasindaki SB18 olarak gosterilen direnci sokunce BOOT0 pinini High yaptim. Yanlis olan ve bu hataya neden olan SystemInit rutinini duzeltip derledim ve karta bu vaziyette program yuklemeyi denedigimde SWD den program atildi. Daha sonra da kartimin SB18 jumperini eski haline getirdim ve kartimi tekrardan kullanabilir hale getirdim.
Bence kotu ve bir okadar da guzel bir tecrube oldu.
Aman dikkat.Bu hataya dusmeyin. Cozumu olsa da adami telaslandiriyor.
Yalniz bu yaptigim kurtarma islemi Flashi nasil sildi bilmiyorum. Flash harici kaynaklardan boot edince PCdeki SWD yazilimi flashi siliyor olabilir. (?)
Kafam karıştı.
Normalde boot0'ı 1 yapıp reseti attığınız zaman F1xxx ler http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00167594.pdf deki belgeden görüleceği üzere dahili bootloaderını kullanıp seri porttan veya USBden *.hex kod yüklemeye izin veriyordu.
Bu belgede maalesef f4ler için birşey yazılmamış. ama pek bişeyin değişeceğini zannetmem.
Ki başka bir konuda şu: bahsettiğiniz pinler ilk açılışta "jtag/swd" pinleri. bunları remap yapmadan i/o olarak kullanamazsınız.
Bizim cipte bootloader yok diye biliyorum(?). Cipi kullanilmaz durume geciren katil kod.
void SystemInit()
{
volatile int i;
RCC->AHB1ENR |= 0x0000000F; // GPIO A-B-C-D donanýmýnýn clock sinyallerini uygulayalým
GPIOA->MODER = 0x00100000; // GPIOD 10 Output
GPIOA->OSPEEDR= 0x00300000; // GPIOD 10 Fast Out
GPIOB->MODER = 0x00100000; // GPIOD 10 Output
GPIOB->OSPEEDR= 0x00300000; // GPIOD 10 Fast Out
GPIOC->MODER = 0x00100000; // GPIOD 10 Output
GPIOC->OSPEEDR= 0x00300000; // GPIOD 10 Fast Out
GPIOD->MODER = 0x00100000; // GPIOD 10 Output
GPIOD->OSPEEDR= 0x00300000; // GPIOD 10 Fast Out
}
Ayni kodlari bir daha denemek istemiyorum ama birimizden birinin basina bu durum kesin gelecektir.
Çipimizde embedded bootlader varmış.
Rehber Sayfa 59.
Alıntı yapılan: memo333 - 03 Kasım 2011, 10:12:09
.....Ki başka bir konuda şu: bahsettiğiniz pinler ilk açılışta "jtag/swd" pinleri. bunları remap yapmadan i/o olarak kullanamazsınız.
Bununla ilgili bilgiyi nerede okudunuz.
Alıntı yapılan: bunalmis - 03 Kasım 2011, 12:02:37
Bununla ilgili bilgiyi nerede okudunuz.
f1lere dayanan tecrübelerimden. JTAG uyumlu pinleri direk olarak I/O kullanamazsınız. JTAG Disable yapmanız gerekir.
eemkutayın sorusuna cevap olacak çok genel amaçlı programa örneği zaten https://www.picproje.org/index.php/topic,36040.msg258436.html#msg258436 (https://www.picproje.org/index.php/topic,36040.msg258436.html#msg258436)
linkinde vermişim.
Eğer çevrebirimleri için kullanmak istersek aşağıdaki programı kullanabilirsiniz. Fakat bu kodu önermiyorum.
Eğer ağırlıklı bitbanding işlemleri yapacağınız uygulama varsa her bir biti aynen header dosyalarda tanımlar gibi tek tek aşağıdaki bağıntı gereği tanımlayıp değer atamalasınız. Ancak bu durumda bitbanding işlemlerde hız avantajı yakalarsınız.
Bu uygulamalar özel olarak karşınıza çıkar. (Kriptoloji bunlardan birisi)
Ykarılarda bir yerlerde uzun uzun tartışmaya neden olan 3 clk da mı yoksa 1 clk da mı bitbanding olacak konusuna kısaca dönersek;
Birbirine komşuluk mesafesi -1024.... +16384 bit olan tüm bitleri peş peşe olmak kaydıyla 1 cycle da 1 yada 0 olarak değiştirebilirsiniz.
Bunu da başka bitbanding donanımını kullanmadan daha başka hiç bir kodlama ile yapamazsınız.
Ancak C derleyicinizin sizin bu amacınızı iyi anlaması gerekir. (Keil Speed Level3 optimizasyonu bunun üstesinden geliyor)
Eğer anlayamıyorsa bu durumda asm yazıma yönelinebilir.
eemkutayın istediği Bitbanding doğasına aykırı kod örneği aşağıda.
unsigned short* Bit_Adr(int Wadr,char BitNum)
{
return((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2)));
}
int main()
{
unsigned short* P; A=0;
P=Bit_Adr((int)&GPIOD->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel
*P=1;
}
eemkutay ve Gerbaydan yazmalarını rica ettiğim programları başlığa koyarlarsa, bitbanding için yapacağım özel kodlama zaten yukarıdaki tartışmaya da son noktayı vuracak nitelikte olacaktır.
bitbandingi daha
Alıntı yapılan: memo333 - 03 Kasım 2011, 13:27:06
f1lere dayanan tecrübelerimden. JTAG uyumlu pinleri direk olarak I/O kullanamazsınız. JTAG Disable yapmanız gerekir.
Okumak istiyorum fakat bahsettiğiniz uyarıyı göremedim.
SWD (A14 ve A13) pinlerini moder den I/O yapmama engel olan hiç bir uyarı göremedim çünkü.
ModerA registerinin tek özelliği reset ardından 0x00000000 değil 0xA8000000 değere sahip olması.
Bunun da anlamı Reset ardından hiç bir tanımlama yapmasanız bile A15 A14 A13 alternatif fonksiyon demektir.
Yazdığım Katil kodların yaptığı şey ise derhal GPIO da 10 bit hariç diğerlerini inp yapmak.
Alıntı yapılan: bunalmis - 03 Kasım 2011, 13:38:56
Okumak istiyorum fakat bahsettiğiniz uyarıyı göremedim.
SWD (A14 ve A13) pinlerini moder den I/O yapmama engel olan hiç bir uyarı göremedim çünkü.
ModerA registerinin tek özelliği reset ardından 0x00000000 değil 0xA8000000 değere sahip olması.
Bunun da anlamı Reset ardından hiç bir tanımlama yapmasanız bile A15 A14 A13 alternatif fonksiyon demektir.
Yazdığım Katil kodların yaptığı şey ise derhal GPIO da 10 bit hariç diğerlerini inp yapmak.
Haklısınız. F4lerde durum biraz değişmiş
F1lerde JTAG pinlerini kullanmak için;
/* Disable the Serial Wire Jtag Debug Port SWJ-DP */
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
demek gerekirdi.
F4lerin örneklerinde ve fonksiyonlarında bu durum değişmiş, yukarıdaki fonksiyon olmadan direk I/O olarak atanabiliyor.
O zaman sizin başınıza şu geldi. Bir şekilde sizin katil kod işi bozdu. Sizde BOOT0'ı set edip ST-Link reseti verince Bootloader devreye girdi ve pinler normal konumlarına döndü. Sizde kodu yükleyebildiniz.
Çok dağıttım konuyu toplayayım.
F1lerde
* Her bir pin Default olarak I/O idi. Siz Alternatif Fonksiyonlardan (AF) birini seçerek donanımları ilgili pinler üzerinde çalıştırıyordunuz.(Örneğin SPI) (Bu durum F4lerde de değişmedi.)
* Bazı donanımları default olarak atandıkları pinlerden başka pin takımına taşınabiliyordu. Buna REMAP Denirdi. (örneğin usart pinlerini porta 11-12den portb 13-14e taşınması).
Ayrıca F1 datasheetlerine bakarsanız, JTAG pinlerinin Alternatif Fonksiyon olarak değil, Default olarak tanımlandığını görürsünüz. JTAG pinlerini I/O olarak kullanabilmek için REMAP edilmesi gerekiyordu.
F4lerde
*Remap olayı bayağı bir azaltılmış. Hikmetini bilmiyorum.
*JTAG pinleri sadece alternatif fonksiyon olarak atanmış. Yani AF değerlerini silerseniz I/O olarak kullanabilirsiniz. REMAP'e gerek yok.
Alıntı yapılan: memo333 - 03 Kasım 2011, 14:11:11
....*JTAG pinleri sadece alternatif fonksiyon olarak atanmış. Yani AF değerlerini silerseniz I/O olarak kullanabilirsiniz. REMAP'e gerek yok.
AF yi silmeniz gerek yok. Zaten AF registerlerin reset değerleri default olarak 0.
Bu durumda MODER den o pinleri AF özelliğinden çıkartmak sistemi çökertmeye yetiyor.
Neyse, bu durum başınıza gelirse sorun yok. Nasıl kurtulabileceğinizi yukarıda açıkladım.
Belkide JTAG Pinlerini kilitlemek ileride oluşacak hataları engelleyebilir.
Birde Bülent Hocam GPIO->BSRR kayıtçısı ile GPIO üzerinde atomik işlem yapılabiliyor. Bitbanding sizce bu konuda gereksiz kalmıyor mu?
Adamlar bitbanding özelliğini program yazarı arada sırada bir biti set reset etsin diye koymamışlar.
Bizler 8 16 yada 22 bit verilerle çalışıyoruz.
Peki uygulamanız Ramdaki değişkenleri 1 bitlik veri olarak ele almayı gerektiriyorsa ne yapacaksınız.
Ramda her bir bit için 8 bitlik char tanımlayıp değişkenin her bir bitini gerektikçe test eder (gerekirse kaydırır) kullanırım derseniz çok zaman kaybedersiniz.
İşte bitbanding ramın her bir bitini sizin kullanımınıza açıyor.
Öte yandan BSRR registeri sadece GPIOx_ODR ile erişilen bitlere bit bazında erişim sağlıyor. Bitbanding modunda tüm peripheral registerlere bit bazında erişim sağlıyorsunuz.
Bitbanding de n. bit ile m. biti derhal AND OR XOR + / - * gibi işlmelere tabii tutabilirsiniz.
Aynı işlemi birde char değişkende yapmayı denesene. Ne kadar uzun kodlar oluşur ve anlamsız zaman kaybı olur.
Bitbanding = 1 bitlik memory mimarisi üzerinde bitlerin set reset işlemleri.
Diger Registerlar konusunda kesinlikle haklısınız.
Sadece pin aç/kapa üzerinde BSRR de var ona da değiniliebilir.
Peki bit banding kullanmadan bu yazida gecen olayi nasil asabiliriz? Alternatifi nedir?
Alıntı YapTake the USART for example. The CTS flag goes high and an interrupt handler as part of its job, wants to reset the flag. Don't ask me why, it just does. Meantime, you just received a byte and the RXNE flag is set to indicate that there is data waiting. But the CTS handler is in the middle of a read-modify-write cycle. It has read the status register and is in the process of clearing the CTS flag. When it writes the result back, the RXNE flag will be cleared and the arrival of the character could go un-noticed.
OK, so I just invented all that. the point is, the peripheral registers may need care in setting and clearing bits and the safest way to do that in both cases is through bit-banding. Why? because the changes are atomic. That is, they happen to single bits in on cycle and cannot be interrupted. Thus, there will never be an occasion where you read a bit which can be modified by some other code before you get to write it back out.
Read more: http://www.micromouseonline.com/2010/07/14/bit-banding-in-the-stm32/#ixzz1ceoPzAls
Sanirim bu bitbanding hizli yazmakdan ziyade daha baska bir amaclara hizmet ediyor ornekdeki gibi... peki bint band region olmayan kontrolor yokmu,en azindan cortex mimarisi bunu zorunlumu kiliyor?
Konuyu dağıtmadan minik bir istekte bulunacağım.
İşlmcinin komut setini bulamıyorum. Refsheet , datasheeet vs.. hepsini karıştırdım ama bulamadım. Linki var mı?
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0439b/DDI0439B_cortex_m4_r0p0_trm.pdf
Sayfa 29 da başlıyor.
@mcan
Read modify write yapmaz read write yaparsın. Yada read modify ORR write yaparsın.
rc_w0 a dikkat et. 1 yazarsan bir şeycik olmaz.
Alıntı yapılan: bunalmis - 03 Kasım 2011, 18:36:31
@mcan
Read modify write yapmaz read write yaparsın. Yada read modify ORR write yaparsın.
rc_w0 a dikkat et. 1 yazarsan bir şeycik olmaz.
Ama bitbanding disindaki metodlarda mask kullanmiyormuyuz? Mecbur oku degistir yaz yolunu secmezmiyiz?Ben zaten anlamadim bu atomic yani bolunemez erisimi, anladigim su bitbanding yaparken islemin kendisinin masking `e (oku, degistir, yaz) gore hizli olmasinin yaninda ,bit banding bitmeden interrupta bile girmiyor.Anladigim, adam diyorki rxe bitini 0 yazarak sifirlamak istiyoruz, bunun icin kopmle registeri okuyoruz ,sonra or and gerekli olan operator ile degistiryoruz ,biz bu degisim isini yaparken cts biti 1 oluyor, sonra bizim degisen yazmaci geri usartsr ye yaziyoruz biz okumaya basladigimizda cts 0 oldugundan geri yazarken de ona dokumadigimizdan yazim tamamlaninca arada 1 olan cts islem sonunda sifir oluyor.Bit banding bunun onune geciyor olarak anladim
rc_w0 a dikkat et. 1 yazarsan bir şeycik olmaz. Bu sekilde aciklama getirilmis bitlere 1 yazip sonra yeniden okursak 1 mi okuruz yoksa eskiden ne varsa onu mu okuruz?Kartta deneyecem usenmem gecince :)
Alıntı yapılan: mcan - 03 Kasım 2011, 19:00:40
Ama bitbanding disindaki metodlarda mask kullanmiyormuyuz? Mecbur oku degistir yaz yolunu secmezmiyiz?Ben zaten anlamadim bu atomic yani bolunemez erisimi, anladigim su bitbanding yaparken islemin kendisinin masking `e (oku, degistir, yaz) gore hizli olmasinin yaninda ,bit banding bitmeden interrupta bile girmiyor.Anladigim, adam diyorki rxe bitini 0 yazarak sifirlamak istiyoruz, bunun icin kopmle registeri okuyoruz ,sonra or and gerekli olan operator ile degistiryoruz ,biz bu degisim isini yaparken cts biti 1 oluyor, sonra bizim degisen yazmaci geri usartsr ye yaziyoruz biz okumaya basladigimizda cts 0 oldugundan geri yazarken de ona dokumadigimizdan yazim tamamlaninca arada 1 olan cts islem sonunda sifir oluyor.Bit banding bunun onune geciyor olarak anladim
Neden okuyup geri yazasınki? Bu çok özel bir register. Register kutucuğunda her bir bitin altına bak sade şekilde r/w yazmıyor
Diyelimki int geldi ve int rutinine girdin.
1. USART_SR registerini oku
Diyelimki CTS set olmuş bunu sıfırlamak istiyoruz.
2. USART_SR=0x1FF
-------------
Diyelimki int geldi ve int rutinine girdin.
1. USART_SR registerini oku
Diyelimki RXNE set olmuş bunu sıfırlamak istiyoruz.
2. USART_SR=0x3DF
Hepsi bu kadar.
Klasik anlamda değişkenlerde read modify write işlemleri yapabilirsin. Fakat
Eğer register rc_w0, rc_w1, t gibi özel yapıya sahipse bu durumda klasik anlamda modifikasyon değil ya dediğim gibi yada bitband işlem yapmalısın.
Bit banding işlemi sadece ve sadece STR yada LDR şekline tek cycle bir komut. Bu tip elamanter komutları interrupt zaten bölemez.
Alıntı yaptığın kişi yada ben bence olayın farkında değil.
Evet,o bitlere 1 yazmak bişeyi değiştirmiyor gene 0 ise sıfır oluyor sanırım sadece hw set edebiliyor,
Bence de haklısınız ,adam örnek vermiş ancak ya örneği ben anlamadım yada yanlış örnek vermiş...
Peki Bunalmiş hocam adamın örneğini ben değiştireyim ;
Programımızda sram de her programın kullancağı bir posta kutusu olsun.Basitlik açısından 1 word olsun.
Main içinde bu posta kutusunu kontrol edelim,ayrıca bazı bitleri set ederek kesme rutininde koşan programcıklara bilgi gönderelim.
2 adet kesme rutinimiz olsun,kesmelerde bu posta kutusunda belirli bitleri set edip main de çalışan programımızı uyaralım.
Şimdi mainde programımızın bir kısmında 1. kesmeyi kontrol edip dallanalım,
2. kısmında 2. kesmeyi kontrol edip dallanalım.
Bit band kullanmıyoruz,
Alıntı Yap
Posta kutusunu okuduk (başka rem bölgesine aktardık)
Maskeleyip 1.kesmenin ile ilgili biti kontrol ettik.
Kontrol ettiğimiz biti sıfırlamak için yine maskeleme yaptik ve tam geri yerine yazacakken 2. kesme gerçekleşti
2. kesmeye girdik ,
Posta kutumuzun ilgili bitini set edip geri kaldığımız yere döndük
Kaldığımız yerde eski maskeyi posta kutusuna yazdırıyorduk,eski maskede 2. kesmenin biti set edilmemişti
Doğal olarak eski maskeyi yazmay devam ettik ve yazdık .
2. kesmeyi kontrol eden yere geldik
2.kesme görünmüyor,kaçırdık.....
Senaryoda mutlaka hata vardır ,ancak anlamak adına soruyorum. Burda yapılabilecek posta kutusunu modifiye ederken interruptları kapamak.
Ancak bit band ile interrupt kapamaya gerek kalmadan işlem gerçekleşiyor olarak anladım.Doğrumudur ?
Senaryo biraz karışık olmuş. Doğru anladıysam
Bir memory alanı, ana kodumuz haricinde interrupt rutini tarafından da kullanılıyorsa
Bu alana ulaşmadan önce int yasaklanmalı alana ulaşılıp işimiz bittiğinde intlara izin verilmelidir.
Bu işlemi bit banding yapacaksan hiç bir sorun yok çünkü bit bandingde sadece ve sadece 1 bit le oynanır ve bu oynama esnasında olabilecek interruptlar yapılan işlemi kesemez.
Bit manuplasyonu yapan klasik uygulamada ise (oku modifiye et yaz) eğer modifiye edilen aynı alan int rutinince de değiştiriliyorsa o zaman önce int ı yasaklayıp modifikasyon yapıp bitiminde int'a geri izin vermek gerekir.
Alıntı yapılan: bunalmis - 03 Kasım 2011, 20:19:00
Senaryo biraz karışık olmuş. Doğru anladıysam
Bir memory alanı, ana kodumuz haricinde interrupt rutini tarafından da kullanılıyorsa
Bu alana ulaşmadan önce int yasaklanmalı alana ulaşılıp işimiz bittiğinde intlara izin verilmelidir.
Bu işlemi bit banding yapacaksan hiç bir sorun yok çünkü bit bandingde sadece ve sadece 1 bit le oynanır ve bu oynama esnasında olabilecek interruptlar yapılan işlemi kesemez.
Bit manuplasyonu yapan klasik uygulamada ise (oku modifiye et yaz) eğer modifiye edilen aynı alan int rutinince de değiştiriliyorsa o zaman önce int ı yasaklayıp modifikasyon yapıp bitiminde int'a geri izin vermek gerekir.
O zaman doğru anlamışım, ben bu bir bit uğruna yapılan işlemleri hiç sevmedim,masking banding neden koymamışlar direk komutunu,özellikle tek saat darbesinde gerçekleşmeyen işlemleri de hiç sevmem. 512 kb alan veriyorlar zaten 5-6 byte tı sadece bir biti set etmeye gidiyor .. :)
Alıntı yapılan: bunalmis - 03 Kasım 2011, 13:30:54
eemkutayın istediği Bitbanding doğasına aykırı kod örneği aşağıda.
unsigned short* Bit_Adr(int Wadr,char BitNum)
{
return((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2)));
}
int main()
{
unsigned short* P; A=0;
P=Bit_Adr((int)&GPIOD->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel
*P=1;
}
eemkutay ve Gerbaydan yazmalarını rica ettiğim programları başlığa koyarlarsa, bitbanding için yapacağım özel kodlama zaten yukarıdaki tartışmaya da son noktayı vuracak nitelikte olacaktır.
Sanırım sorumu anlamamışsın veya işine gelmemiş. Diyosun ki "bit dandik" tek saykılda çalışıyor bende sana gerçek register adreslerini kullanarak hızlı çalışmasını bana ispatla dedim. Aslında amacım kullanışsız olduğunu göstermekti. Yazdığın C kodu ve asm karşılığı aşağıda. Ben hız ve verimlilik göremedim. Altıüstü 2 tane biti set etmek için, verimli ve hızlı dediğin ve aşağıda sayısını saymaya üşendiğim asm'den mi oluşuyor.
Bu arada GpioD_Odr'nin adresini nereden aldın? Header'ı ben include etmek zorunda kaldım.
// Bu yazdığın bitbanding, bende performansını göreyim diye başka bir adres daha ekledim
#include "stm32f10x.h"
unsigned short* Bit_Adr(int Wadr,char BitNum)
{
return((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2)));
}
int main()
{
unsigned short* P;
P=Bit_Adr((int)&GPIOD->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel
*P=1;
P=Bit_Adr((int)&GPIOA->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel
*P=1;
}
// asm karşılığı
//////////////////////////////////////////////Bu kısım yazdığın fonksiyon///////////////////////////////////
21: {
0x080001A4 4602 MOV r2,r0
22: return((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2)));
0x080001A6 F04F4384 MOV r3,#0x42000000
0x080001AA EB031042 ADD r0,r3,r2,LSL #5
0x080001AE EB000081 ADD r0,r0,r1,LSL #2
23: }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////Burası main kısmı/////////////////////////////////////////////////////////////
26: int main()
0x080001B2 4770 BX lr
27: {
28: unsigned short* P;
29:
30:
0x080001B4 B510 PUSH {r4,lr}
31: P=Bit_Adr((int)&GPIOD->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel
0x080001B6 4808 LDR r0,[pc,#32] ; @0x080001D8
0x080001B8 2102 MOVS r1,#0x02
0x080001BA F7FFFFF3 BL.W Bit_Adr (0x080001A4)
0x080001BE 4604 MOV r4,r0
32: *P=1;
33:
0x080001C0 2001 MOVS r0,#0x01
0x080001C2 8020 STRH r0,[r4,#0x00]
34: P=Bit_Adr((int)&GPIOA->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel
0x080001C4 4805 LDR r0,[pc,#20] ; @0x080001DC
0x080001C6 2102 MOVS r1,#0x02
0x080001C8 F7FFFFEC BL.W Bit_Adr (0x080001A4)
0x080001CC 4604 MOV r4,r0
35: *P=1;
36:
0x080001CE 2001 MOVS r0,#0x01
0x080001D0 8020 STRH r0,[r4,#0x00]
37: }
/////////////////////////////////////////////////////////////////////////////////////////
eemkutay
bitbanding sana göre değil. Istedigin sartlarda sana avantaj sağlamaz. Cunku sen parametrik calisan kod istiyorsun.
Bitbanding bu amacla olusturulmamis. Istedigin programi tek cycle da isleyemeyecegini zaten basindan yazmistim. Bu yuzden sadece periperal adresler icin
bit adresinin nasil hesaplanacagini verdim. Bunu ise yarar bir programa donusturme kismini sana biraktim.
Benim soruma kodu yazdinmi?
Eger yazdiysan bitbanding avantajini hemen gosterecegim.
Silinebilir.
Tartışmanın kaynağı olan konu aşağıda.
Alıntı yapılan: eemkutay - 30 Ekim 2011, 23:06:21
Bit Banding'i keil ve iar'da denemiştim, zamanlama anlamında büyük bir avantaj getirmiyor. Maskele ile aynı sonuçları almıştım. Ama tabii belki sizi bit maskelemekten kurtarır fakat aynı şeyi güzel bir macro ile sizde yazabilirsiniz.
Şimdi olaya objektif yaklaşalım ve iki fonksiyon yazalım.
Bu fonksiyonların her biri parametre olarak register adresini, bit numarasını ve bitin alması gereken değeri istesin.
Fonksiyonlar verilen registerin verilen bit numarasındaki bitine verilen değeri atasın.
Tabiki birisi bitbanding işlemiyle, diğeri de klasik maskeleme yöntemiyle bu işi yapacak.
Bunun için aşağıdaki programı yazdım.
#include "STM32F4xx.h"
void SystemInit()
{
RCC->AHB1ENR |= 0x00000008; // GPIOD donanýmýnýn clock sinyalini uygulayalým
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
void BitChg1(int Wadr,char BitNum, char BitVal)
{
*((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2)))=BitVal;
}
void BitChg2(int Wadr,char BitNum, char BitVal)
{
*(unsigned short*)Wadr = ((*(unsigned short*)Wadr) & (~(1<<BitNum))) | (BitVal<<BitNum);
}
int main()
{
BitChg1((int)&GPIOD->ODR,12,1); // Bitbanding
BitChg2((int)&GPIOD->ODR,12,1); // Maskeleme
}
Kodları derleyip fonksiyonlarımızın asm çıktılarına bakarsak;
Bitbanding için aşağıdaki asm kodları;
10: void BitChg1(int Wadr,char BitNum, char BitVal)
11: {
0x08000282 B510 PUSH {r4,lr}
12: *((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2)))=BitVal;
0x08000284 F04F4484 MOV r4,#0x42000000
0x08000288 EB041340 ADD r3,r4,r0,LSL #5
0x0800028C F8232021 STRH r2,[r3,r1,LSL #2]
13: }
14:
0x08000290 BD10 POP {r4,pc}
Klasik maskeleme için ise aşağıdaki asm kodları elde ederiz.
15: void BitChg2(int Wadr,char BitNum, char BitVal)
16: {
0x08000292 B510 PUSH {r4,lr}
17: *(unsigned short*)Wadr = ((*(unsigned short*)Wadr) & (~(1<<BitNum))) | (BitVal<<BitNum);
0x08000294 8803 LDRH r3,[r0,#0x00]
0x08000296 F04F0401 MOV r4,#0x01
0x0800029A FA04F401 LSL r4,r4,r1
0x0800029E EA230304 BIC r3,r3,r4
0x080002A2 FA02F401 LSL r4,r2,r1
0x080002A6 EA430304 ORR r3,r3,r4
0x080002AA 8003 STRH r3,[r0,#0x00]
18: }
0x080002AC BD10 POP {r4,pc}
Aralarındaki farkı görmek için satır satır asm kodları sayınız. (Daha ileri gitmek isterseniz her kodun istediği clkları da hesaplayabilirsiniz.)
Üstelik Maskeleme yönteminde int enable ve int disable işlemini yapmadık. Bunu yapmadığımız takdirde bu fonksiyonun doğru çalışacağı garanti edilemez.
Bu örnek dahi bitbandingin avantajını göstermeye yetmiyorsa diyecek hiç bir şey bulamıyorum.
Öte yandan bir cycleda bir bitbanding yapmamı istiyorsanız lütfen ama lütfen sorduğum ve hala program olarak cevap vermediğiniz kod örneklerini yazınız.
#include <stm32f4xx.h>
#define BITB_A(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOA->ODR) << 5) + ((b) << 2)))
#define BITB_B(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define BITB_C(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOC->ODR) << 5) + ((b) << 2)))
#define BITB_D(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOD->ODR) << 5) + ((b) << 2)))
#define BITB_E(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOE->ODR) << 5) + ((b) << 2)))
void SystemInit(){
}
int main(void){
while(1){
BITB_A(0)=1;
BITB_B(1)=0;
BITB_C(2)=1;
BITB_D(3)=0;
BITB_A(0)=0;
BITB_B(1)=1;
BITB_C(2)=0;
BITB_D(3)=1;
}
}
Bunalmis hocam sizin kodlardan kopya çekerek yukarıdaki fonksiyonları yazdım,
Level1 ve sonrası optimizasyonlarda ilk adresleri ve 0,1 değerlerini yükleyerek 6 saykıl kaybediyor
sonra tek saykıl halinde dönmeye başlıyor, R12'e kadar önbelleği meşgul edemediğimden tam test yapamadım ama
max 3 saykıla kadar kullanabileceğimiz bir kısayol gibi gözüküyor şu anlık,
eğer işe yarar gözüküyorsa bir de siz inceleyebilir misiniz?
R12 ye kadar register işgal etmeye gerek yok.
Şimdi A registerinde 16 bit var. B de de C de de D de de.
Hiç ilave register kullanmadırmadan bunların her birinin her bir bitine 1 yada 0 atayabilirsin. Yeterki araya başka bir kod girme.
Zaten itirazlarının birisi bu. Araya kod girer diyorlar. Haklı olmak isterlerse haklılar.
İstediğim kodu yazacakları yok. Soru asağıdakiydi.
A[3] seklinde arrayim var.
A[0] ve A[1] in yuksek 4 biti sifirdir.
A[0]'nin dusuk bitleri, A3 A2 A1 A0
A[1]'nin dusuk bitleri, B3 B2 B1 B0 dir.
Program;
A[0] ve A[1] den alacagi bitleri A[2] icine A3 B0 A1 B2 A0 B1 A2 B3 siralamasiyla yazacaktir.
Uğraşmak istersen uğraş. Fakat bitbanding ile değil. Klasik usulle.
Bitbanding örneği ben yazdım cevap gelsin diye bekletiyorum.
Alıntı yapılan: bunalmis - 04 Kasım 2011, 04:13:01
A[3] seklinde arrayim var.
A[0] ve A[1] in yuksek 4 biti sifirdir.
A[0]'nin dusuk bitleri, A3 A2 A1 A0
A[1]'nin dusuk bitleri, B3 B2 B1 B0 dir.
Program;
A[0] ve A[1] den alacagi bitleri A[2] icine A3 B0 A1 B2 A0 B1 A2 B3 siralamasiyla yazacaktir.
Uğraşmak istersen uğraş. Fakat bitbanding ile değil. Klasik usulle.
int main(void){
union dizi{
volatile unsigned char byte;
struct{
volatile unsigned A0:1;
volatile unsigned A1:1;
volatile unsigned A2:1;
volatile unsigned A3:1;
volatile unsigned A4:1;
volatile unsigned A5:1;
volatile unsigned A6:1;
volatile unsigned A7:1;
}A;
struct{
volatile unsigned B0:1;
volatile unsigned B1:1;
volatile unsigned B2:1;
volatile unsigned B3:1;
volatile unsigned B4:1;
volatile unsigned B5:1;
volatile unsigned B6:1;
volatile unsigned B7:1;
}B;
};
union dizi A[3];
while(1){
A[2].byte=(A[0].A.A3<<7)|(A[1].B.B0<<6)|(A[0].A.A1<<5)|(A[1].B.B2<<4)|
(A[0].A.A0<<3)|(A[1].B.B1<<2)|(A[0].A.A2<<1)|(A[1].B.B3);
}
}
37: A[2].byte=(A[0].A.A3<<7)|(A[1].B.B0<<6)|(A[0].A.A1<<5)|(A[1].B.B2<<4)|
0x08000260 9800 LDR r0,[sp,#0x00]
0x08000262 9901 LDR r1,[sp,#0x04]
0x08000264 F3C000C0 UBFX r0,r0,#3,#1
0x08000268 EA4F10C0 LSL r0,r0,#7
0x0800026C F3C10100 UBFX r1,r1,#0,#1
0x08000270 EA401081 ORR r0,r0,r1,LSL #6
0x08000274 9900 LDR r1,[sp,#0x00]
0x08000276 F3C10140 UBFX r1,r1,#1,#1
0x0800027A EA401041 ORR r0,r0,r1,LSL #5
0x0800027E 9901 LDR r1,[sp,#0x04]
0x08000280 F3C10180 UBFX r1,r1,#2,#1
0x08000284 EA401001 ORR r0,r0,r1,LSL #4
0x08000288 9900 LDR r1,[sp,#0x00]
0x0800028A F3C10100 UBFX r1,r1,#0,#1
0x0800028E EA4000C1 ORR r0,r0,r1,LSL #3
0x08000292 9901 LDR r1,[sp,#0x04]
0x08000294 F3C10140 UBFX r1,r1,#1,#1
0x08000298 EA400081 ORR r0,r0,r1,LSL #2
0x0800029C 9900 LDR r1,[sp,#0x00]
0x0800029E F3C10180 UBFX r1,r1,#2,#1
0x080002A2 EA400041 ORR r0,r0,r1,LSL #1
0x080002A6 9901 LDR r1,[sp,#0x04]
0x080002A8 F3C101C0 UBFX r1,r1,#3,#1
0x080002AC EA400001 ORR r0,r0,r1
0x080002B0 F88D0008 STRB r0,[sp,#0x08]
0x080002B4 E7D4 B 0x08000260
bu kadar
sürüyor sürmüyor şimdi farkettim tamam doğruymuş uykusuzluk vurmaya başladı galiba :)
Kodlarin cok guzel sonuc cikartmis. Fakat bu sonuclara bakinca soruyu dogru sormadigimi farkettim. Cunku sorum sadece bit tasima seklinde olmus.
Boyle olunca da hic maskeleme yapmadan kodu yazma sansin dogmus. (Bu benim hatam)
Soruyu degistirmek istememin sebebi, bitband islemler sonucunda elde ettigim kodlarin, senin kodlarindan sadece 3 yada 4 satir daha kisa olusu.
Bu bitbanding icin ezici bir sonuc degil. Arada bariz fark olusturmak icin sorumda kucuk bir degisiklik yapacagim fakat su anda ben de cok uykusuzum yarin devam edelim.
(Yarin sorunun mevcut hali icin bendeki kodlari ya yazacagim.)
bunalmis hocam
bu tartışmaları takip etmelimiyiz? burda yazılan biçok şeyi anlayamadım çünkü
asm kodlar, bitler, bandingler havada uçuşuyor
düşük seviyedeki arkadaşlar olarak şimdilik pasmı geçiyoruz bu konuları? ileride tekrar değinecekmiyiz?
Alıntı yapılan: bunalmis - 04 Kasım 2011, 00:49:40
eemkutay
bitbanding sana göre değil. Istedigin sartlarda sana avantaj sağlamaz. Cunku sen parametrik calisan kod istiyorsun.
Bitbanding bu amacla olusturulmamis. Istedigin programi tek cycle da isleyemeyecegini zaten basindan yazmistim. Bu yuzden sadece periperal adresler icin
bit adresinin nasil hesaplanacagini verdim. Bunu ise yarar bir programa donusturme kismini sana biraktim.
Benim soruma kodu yazdinmi?
Eger yazdiysan bitbanding avantajini hemen gosterecegim.
Aşağıya yazdım , hemde low optimizasyon seviyesinde yazdım. Senin gibi 2 tane biti while içine alıp hazırlama kısımlarını while dışında bırakan level 3 optimizasyon kullanmadan. Topu topu 20 tane asm komutu yetti de arttı bile. Hemde yazdığım kodda tüm parametreler değiştirilebilir, anlaşılır , 32bit sayılarla uğraşmadan ve hızlı.
Şimdi yukarıda söylediğin gibi bana bitbanding'in avantajını hemen göster. (sözlerle değil asm ile)
// C file
struct XBits{
unsigned char Bit0:1;
unsigned char Bit1:1;
unsigned char Bit2:1;
unsigned char Bit3:1;
unsigned char Bit4:1;
unsigned char Bit5:1;
unsigned char Bit6:1;
unsigned char Bit7:1;
};
union RegsUni
{
unsigned char Byte;
struct XBits Bits;
};
#define Abits A[0]
#define Bbits A[1]
int main()
{
union RegsUni A[3];
while(1)
{
A[2].Byte=Abits.Bits.Bit3<<7|Abits.Bits.Bit1<<6|Abits.Bits.Bit0<<5|Abits.Bits.Bit2<<4|
Bbits.Bits.Bit0<<3|Bbits.Bits.Bit2<<2|Bbits.Bits.Bit1<<1|Bbits.Bits.Bit3;
}
}
//Asm file
main:
0x40: 0xb081 SUB SP, SP, #0x4
A[2].Byte=Abits.Bits.Bit3<<7|Abits.Bits.Bit1<<6|Abits.Bits.Bit0<<5|Abits.Bits.Bit2<<4|
Bbits.Bits.Bit0<<3|Bbits.Bits.Bit2<<2|Bbits.Bits.Bit1<<1|Bbits.Bits.Bit3;
??main_0:
0x42: 0xf89d 0x0000 LDRB.W R0, [SP]
0x46: 0xb2c0 UXTB R0, R0
0x48: 0x08c0 LSRS R0, R0, #3
0x4a: 0xf89d 0x1000 LDRB.W R1, [SP]
0x4e: 0xf3c1 0x0140 UBFX R1, R1, #1, #1
0x52: 0x0189 LSLS R1, R1, #6
0x54: 0xea51 0x10c0 ORRS.W R0, R1, R0, LSL #7
0x58: 0xf89d 0x1000 LDRB.W R1, [SP]
0x5c: 0xf011 0x0101 ANDS.W R1, R1, #1
0x60: 0xea50 0x1041 ORRS.W R0, R0, R1, LSL #5
0x64: 0xf89d 0x1000 LDRB.W R1, [SP]
0x68: 0xf3c1 0x0180 UBFX R1, R1, #2, #1
0x6c: 0xea50 0x1001 ORRS.W R0, R0, R1, LSL #4
0x70: 0xf89d 0x1001 LDRB.W R1, [SP, #0x1]
0x74: 0xf011 0x0101 ANDS.W R1, R1, #1
0x78: 0xea50 0x00c1 ORRS.W R0, R0, R1, LSL #3
0x7c: 0xf89d 0x1001 LDRB.W R1, [SP, #0x1]
0x80: 0xf3c1 0x0180 UBFX R1, R1, #2, #1
0x84: 0xea50 0x0081 ORRS.W R0, R0, R1, LSL #2
0x88: 0xf89d 0x1001 LDRB.W R1, [SP, #0x1]
0xda: 0xe7b2 B.N ??main_0 ; 0x42
ErsinErce'ye yazdığım, soruda değişiklik yapmam gerektiğini belirttiğim mesajı okumadınız mı?
Ayrıca daha üstündeki bitbanding ve maskelemeli klasik yöntem için verdiğim karşılaştırmalı program örneklerinin de avantajı anlaman için yeterli olacağını sanıyordum.
Alıntı yapılan: gerbay - 04 Kasım 2011, 11:57:34
önemli olan kodlama tekniğini iyi bilmek, "veri yapıları ve algoritmalar" konusuna hakim olmak.. kodlama tekniğiniz çok iyi ise, 2 cycle az olmuş çok olmuş artık bir önemi kalmadı..
Düşüncene aynen katılıyorum.
Bit banding olayını 2 yıl önce kendi testlerimle sonlandırmıştım zaten. Artık bit banding hakkında yazmıyacağım.
@eemkutay dur kaçma işin aslını yanlış öğrenmişsin ve konuyu 2 sene önce yanlış sonlandırmışsın.
@Gerbay (^@Gerbay), başlık cortex şamatası başlığı. Bu konuların tartışıldığı bir başka Türkçe sayfa biliyorsan yazmayalım.
eemkutay hocam yazdıklarımız neredeyse aynı ama sizinki nasıl bu kadar az yer kaplıyor merak ettim,
sizin kodlarıda derledim benimkiyle aynı sonuç çıkardı (optimizasyon seviyesi farketmiyor hep aynı kod çıkıyor),
acaba IAR'ın compiler'ı bu konuda daha mı iyi?
@Ersinerce
Soruda değişiklik yapmam gerekiyor demiştim.
Port adındaki 8 bitlik Portumuzun P7, P5, P3 ve P1 bitleri interrupt rutinleri tarafından update edilmektedir.
Geriye kalan P6, P4, P2 ve P0 bitlerini ise biz main rutininden biz update edeceğiz.
char A değişkenimizdeki verinin;
A7 biti Portun P6 bitine yüklenecek, P0 High ardından Low yapılacak Ardından A0 biti P2 bitine yüklenecek, P0 High ardından Low yapılacak Ardından A3 biti P4 bitine yüklenecek, P0 High ardından Low yapılacak
Bu program parçacığına uğraşırmısın?
Alıntı yapılan: bunalmis - 04 Kasım 2011, 12:30:02
@eemkutay dur kaçma işin aslını yanlış öğrenmişsin ve konuyu 2 sene önce yanlış sonlandırmışsın.
@Gerbay (^@Gerbay), başlık cortex şamatası başlığı. Bu konuların tartışıldığı bir başka Türkçe sayfa biliyorsan yazmayalım.
Bunalmış,
Kaçmak mı? Ben senin gibi değilim, ben haksız olduğuma inansaydım haklısın diyebilme erdemine sahibim. Ama sen bundan yoksunsun. Seni şahsen tanımıyorum ama forumda iyi tanıyorum. Hiçbirşeyi kabullenmeyen, öğrenmeye kapalı bir yapın var. Daha önceleri seninle asm ve c tartışmamız olmuştu. C'yi kötüleyip duruyordun, o zamanlar şimdiki gibi ns saniye hesabı yapıyordun. Ne oldu? Aradan zaman geçti daha yeni benim dediğime geldin. Şimdide aynısı olacak. Yakında C'de benim yazdığım gibi yazmayı öğreneceksin. Herzaman senin 3-5 adım önünde olacağım. Bu meslekte ve bu forumda tek çalışkan ve başarılı insan kendin sanıyorsun galiba.
Başlangıçta bitbanding için sen 1 cycle'da çalışıyor dedin, ben 3 dedim. Sonra baktın yanlışsın lafı çevirdin, "en iyi ihtimalle 1 cycle" "en kötü ihtimalle 3 cycle" demeye başladın. Maksat "evet haklısın diyememek". Sonra bazı arkadaşlar netten kaynak falan çıkardılar, bu defa maskelemeden daha verimli olur demeye başladın. Hala da konuşabiliyorsun ve bana kaçma gibi bir laf söylüyorsun.
Seninle bu konu hakkında konuşmam için önce yukarıda bana sorduğun soruyu bitbanding ile yaz ve asm sonucunu buraya koy ve benim yukarıda yazdığım programla karşılaştıralım. Hem C formatını hemde asm formatını. Bana sözlü olarak bişeyler söylemen anlamsız, asm sonuçlarına bakarım. Asm çıktıda ezici üstünlük sağla, sonra konuşma hakkın olsun.
Alıntı yapılan: ErsinErce - 04 Kasım 2011, 15:17:11
eemkutay hocam yazdıklarımız neredeyse aynı ama sizinki nasıl bu kadar az yer kaplıyor merak ettim,
sizin kodlarıda derledim benimkiyle aynı sonuç çıkardı (optimizasyon seviyesi farketmiyor hep aynı kod çıkıyor),
acaba IAR'ın compiler'ı bu konuda daha mı iyi?
@ErsinErce
Asm çıktısı olarak genelde yakın sonuçlar çıkarıyorlar ama sonuçta ikiside farklı profesyonel derleyici, asm çıktılarında biraz fark olması normal.
Ben j-linkle birlikte keil ve IAR kullanıyorum. Uzun programlarda da ikisini test ettim 40k'lık programda 1-2k fark oluyor. Benim karşılaştırdığım programda IAR biraz daha iyiydi ama her ikisinide kullanıyorum. Her ikisininde kendince iyi özellikleri var, keil'in ansi c formatına göre macro ve program yazımları daha esnek. Iar ise daha dikkatli program yazmayı gerektiriyor. Ansi C kurallarında tam uyum istiyor, yani kurallarda daha katı. Keil biraz kolaylıklar tanıyor, toleransı var.
@Eemkutay, Anlayana (http://tr.wiktionary.org/wiki/anlamak) sivrisinek (http://tr.wiktionary.org/wiki/sivrisinek) saz (http://tr.wiktionary.org/wiki/saz), anlamayana davul (http://tr.wiktionary.org/wiki/davul) zurna (http://tr.wiktionary.org/wiki/zurna) az (http://tr.wiktionary.org/wiki/az).
struct{
volatile unsigned P0:1;
volatile unsigned P1:1;
volatile unsigned P2:1;
volatile unsigned P3:1;
volatile unsigned P4:1;
volatile unsigned P5:1;
volatile unsigned P6:1;
volatile unsigned P7:1;
}Port __attribute__((at((unsigned long)&GPIOD->ODR)));
struct{
volatile unsigned A0:1;
volatile unsigned A1:1;
volatile unsigned A2:1;
volatile unsigned A3:1;
volatile unsigned A4:1;
volatile unsigned A5:1;
volatile unsigned A6:1;
volatile unsigned A7:1;
}A;
int main(void){
while(1){
Port.P6=A.A7;
Port.P0=1;
Port.P0=0;
Port.P2=A.A0;
Port.P0=1;
Port.P0=0;
Port.P4=A.A3;
Port.P0=1;
Port.P0=0;
}
}
36: Port.P6=A.A7;
0x0800027A 4917 LDR r1,[pc,#92] ; @0x080002D8
0x0800027C 4817 LDR r0,[pc,#92] ; @0x080002DC
0x0800027E 680A LDR r2,[r1,#0x00]
0x08000280 F3C213C0 UBFX r3,r2,#7,#1
0x08000284 6802 LDR r2,[r0,#0x00]
0x08000286 F3631286 BFI r2,r3,#6,#1
0x0800028A 6002 STR r2,[r0,#0x00]
37: Port.P0=1;
0x0800028C 6802 LDR r2,[r0,#0x00]
0x0800028E F0420201 ORR r2,r2,#0x01
0x08000292 6002 STR r2,[r0,#0x00]
38: Port.P0=0;
0x08000294 6802 LDR r2,[r0,#0x00]
0x08000296 F0220201 BIC r2,r2,#0x01
0x0800029A 6002 STR r2,[r0,#0x00]
39: Port.P2=A.A0;
0x0800029C 680A LDR r2,[r1,#0x00]
0x0800029E 6803 LDR r3,[r0,#0x00]
0x080002A0 F3620382 BFI r3,r2,#2,#1
0x080002A4 6003 STR r3,[r0,#0x00]
40: Port.P0=1;
0x080002A6 6802 LDR r2,[r0,#0x00]
0x080002A8 F0420201 ORR r2,r2,#0x01
0x080002AC 6002 STR r2,[r0,#0x00]
41: Port.P0=0;
0x080002AE 6802 LDR r2,[r0,#0x00]
0x080002B0 F0220201 BIC r2,r2,#0x01
0x080002B4 6002 STR r2,[r0,#0x00]
42: Port.P4=A.A3;
0x080002B6 680A LDR r2,[r1,#0x00]
0x080002B8 F3C203C0 UBFX r3,r2,#3,#1
0x080002BC 6802 LDR r2,[r0,#0x00]
0x080002BE F3631204 BFI r2,r3,#4,#1
0x080002C2 6002 STR r2,[r0,#0x00]
43: Port.P0=1;
0x080002C4 6802 LDR r2,[r0,#0x00]
0x080002C6 F0420201 ORR r2,r2,#0x01
0x080002CA 6002 STR r2,[r0,#0x00]
44: Port.P0=0;
0x080002CC 6802 LDR r2,[r0,#0x00]
0x080002CE F0220201 BIC r2,r2,#0x01
0x080002D2 6002 STR r2,[r0,#0x00]
0x080002D4 E7D3 B 0x0800027E
Böyle çıkıyor bunalmis hocam,
Alıntı yapılan: eemkutay - 04 Kasım 2011, 17:04:32
@ErsinErce
Asm çıktısı olarak genelde yakın sonuçlar çıkarıyorlar ama sonuçta ikiside farklı profesyonel derleyici, asm çıktılarında biraz fark olması normal.
Ben j-linkle birlikte keil ve IAR kullanıyorum. Uzun programlarda da ikisini test ettim 40k'lık programda 1-2k fark oluyor. Benim karşılaştırdığım programda IAR biraz daha iyiydi ama her ikisinide kullanıyorum. Her ikisininde kendince iyi özellikleri var, keil'in ansi c formatına göre macro ve program yazımları daha esnek. Iar ise daha dikkatli program yazmayı gerektiriyor. Ansi C kurallarında tam uyum istiyor, yani kurallarda daha katı. Keil biraz kolaylıklar tanıyor, toleransı var.
Anladım hocam teşekkürler,
IAR'da MISRA C denetleyicisi vardı hatırladığım kadarıyla, bir yandan iyi gibi aslında bug oluşmasının önüne geçilmek isteniyor.
Kodlarken ne tarz sorunlar çıkartığına dair bir fikir oluşturması için aklınızda kalan ufak bir kaç örnek varsa bilgilendirebilir misiniz hocam?
@Ersinerce,
Aralara birer tane de dint ve eint gibi fonksiyon koyman gerekmez mi?
Şöyle bir sorum var hocam, Interrupt Set-pending Registers sadece beklemede olduğunu mu gösteriyor yoksa beklemeye de alıyor mu?
Dokumandan anladığım kadarıyla; Register açıklamasında bekleyen interruptları gözleyebiliyorsun. İstersen int olmadığı halde int gelmiş gibi NVIC'ı dürtebiliyorsun.
İstersen ona hiç girme ve fonksiyon çağırarak int enable ve disable ediyormuş gibi yap.
Her defasında Port un 0 bitini 1 ardından da 0 yaparken araya minikte olsa bir delay koymamız gerektiğini böylece çok yüksek frekanslı clk üretmeyeceğimizi, bu delayler nedeniyle mainin hemen başında int disable, en sona da da int enable koymanın yakışı kalmayacağını, bu sebeple portta her bit modifikasyonunda int enable int disable yapmanın daha profosyonel fikir olduğunu hatırlatayım.
void SystemInit(){
}
volatile unsigned long intstate[2];
void dint(void){
intstate[0]=NVIC->ISER[0];
intstate[1]=NVIC->ISER[1];
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
}
void eint(void){
NVIC->IABR[0]=intstate[0];
NVIC->IABR[1]=intstate[0];
}
struct{
volatile unsigned P0:1;
volatile unsigned P1:1;
volatile unsigned P2:1;
volatile unsigned P3:1;
volatile unsigned P4:1;
volatile unsigned P5:1;
volatile unsigned P6:1;
volatile unsigned P7:1;
}Port __attribute__((at((unsigned long)&GPIOD->ODR)));
struct{
volatile unsigned A0:1;
volatile unsigned A1:1;
volatile unsigned A2:1;
volatile unsigned A3:1;
volatile unsigned A4:1;
volatile unsigned A5:1;
volatile unsigned A6:1;
volatile unsigned A7:1;
}A;
int main(void){
int i;
while(1){
dint();
Port.P6=A.A7;
Port.P0=1;
eint();
for(i=0;i<0x10;i++);
dint();
Port.P0=0;
Port.P2=A.A0;
eint();
for(i=0;i<0x10;i++);
dint();
Port.P0=1;
eint();
for(i=0;i<0x10;i++);
dint();
Port.P0=0;
Port.P4=A.A3;
eint();
for(i=0;i<0x10;i++);
dint();
Port.P0=1;
eint();
for(i=0;i<0x10;i++);
dint();
Port.P0=0;
eint();
for(i=0;i<0x10;i++);
}
}
5: void dint(void){
0x080001D0 4770 BX lr
6: intstate[0]=NVIC->ISER[0];
0x080001D2 4840 LDR r0,[pc,#256] ; @0x080002D4
0x080001D4 6802 LDR r2,[r0,#0x00]
0x080001D6 4940 LDR r1,[pc,#256] ; @0x080002D8
0x080001D8 600A STR r2,[r1,#0x00]
7: intstate[1]=NVIC->ISER[1];
0x080001DA 6842 LDR r2,[r0,#0x04]
0x080001DC 604A STR r2,[r1,#0x04]
8: NVIC->ICER[0]=0xFFFFFFFF;
0x080001DE F04F31FF MOV r1,#0xFFFFFFFF
0x080001E2 F8C01080 STR r1,[r0,#0x80]
9: NVIC->ICER[1]=0xFFFFFFFF;
0x080001E6 F8C01084 STR r1,[r0,#0x84]
10: }
11: void eint(void){
0x080001EA 4770 BX lr
12: NVIC->IABR[0]=intstate[0];
0x080001EC 493A LDR r1,[pc,#232] ; @0x080002D8
0x080001EE 680A LDR r2,[r1,#0x00]
0x080001F0 483A LDR r0,[pc,#232] ; @0x080002DC
0x080001F2 6002 STR r2,[r0,#0x00]
13: NVIC->IABR[1]=intstate[0];
0x080001F4 6809 LDR r1,[r1,#0x00]
0x080001F6 6041 STR r1,[r0,#0x04]
14: }
0x080001F8 4770 BX lr
45: Port.P2=A.A0;
0x080001FA 4C37 LDR r4,[pc,#220] ; @0x080002D8
44: Port.P0=0;
0x080001FC 4B38 LDR r3,[pc,#224] ; @0x080002E0
0x080001FE 1F24 SUBS r4,r4,#4
37: while(1){
38: dint();
39: Port.P6=A.A7;
40: Port.P0=1;
41: eint();
0x08000200 E055 B 0x080002AE
42: for(i=0;i<0x10;i++);
0x08000202 F1000001 ADD r0,r0,#0x01
0x08000206 2810 CMP r0,#0x10
0x08000208 DBFB BLT 0x08000202
43: dint();
44: Port.P0=0;
0x0800020A F7FFFFE2 BL.W dint (0x080001D2)
0x0800020E 6818 LDR r0,[r3,#0x00]
0x08000210 F0200001 BIC r0,r0,#0x01
0x08000214 6018 STR r0,[r3,#0x00]
45: Port.P2=A.A0;
0x08000216 6820 LDR r0,[r4,#0x00]
0x08000218 6819 LDR r1,[r3,#0x00]
0x0800021A F3600182 BFI r1,r0,#2,#1
0x0800021E 6019 STR r1,[r3,#0x00]
46: eint();
0x08000220 F7FFFFE4 BL.W eint (0x080001EC)
47: for(i=0;i<0x10;i++);
0x08000224 F04F0000 MOV r0,#0x00
0x08000228 F1000001 ADD r0,r0,#0x01
0x0800022C 2810 CMP r0,#0x10
0x0800022E DBFB BLT 0x08000228
48: dint();
0x08000230 F7FFFFCF BL.W dint (0x080001D2)
49: Port.P0=1;
0x08000234 6818 LDR r0,[r3,#0x00]
0x08000236 F0400001 ORR r0,r0,#0x01
0x0800023A 6018 STR r0,[r3,#0x00]
50: eint();
0x0800023C F7FFFFD6 BL.W eint (0x080001EC)
51: for(i=0;i<0x10;i++);
0x08000240 F04F0000 MOV r0,#0x00
0x08000244 F1000001 ADD r0,r0,#0x01
0x08000248 2810 CMP r0,#0x10
0x0800024A DBFB BLT 0x08000244
52: dint();
0x0800024C F7FFFFC1 BL.W dint (0x080001D2)
53: Port.P0=0;
0x08000250 6818 LDR r0,[r3,#0x00]
0x08000252 F0200001 BIC r0,r0,#0x01
0x08000256 6018 STR r0,[r3,#0x00]
54: Port.P4=A.A3;
0x08000258 6820 LDR r0,[r4,#0x00]
0x0800025A F3C001C0 UBFX r1,r0,#3,#1
0x0800025E 6818 LDR r0,[r3,#0x00]
0x08000260 F3611004 BFI r0,r1,#4,#1
0x08000264 6018 STR r0,[r3,#0x00]
55: eint();
0x08000266 F7FFFFC1 BL.W eint (0x080001EC)
56: for(i=0;i<0x10;i++);
0x0800026A F04F0000 MOV r0,#0x00
0x0800026E F1000001 ADD r0,r0,#0x01
0x08000272 2810 CMP r0,#0x10
0x08000274 DBFB BLT 0x0800026E
57: dint();
0x08000276 F7FFFFAC BL.W dint (0x080001D2)
58: Port.P0=1;
0x0800027A 6818 LDR r0,[r3,#0x00]
0x0800027C F0400001 ORR r0,r0,#0x01
0x08000280 6018 STR r0,[r3,#0x00]
59: eint();
0x08000282 F7FFFFB3 BL.W eint (0x080001EC)
60: for(i=0;i<0x10;i++);
0x08000286 F04F0000 MOV r0,#0x00
0x0800028A F1000001 ADD r0,r0,#0x01
0x0800028E 2810 CMP r0,#0x10
0x08000290 DBFB BLT 0x0800028A
61: dint();
0x08000292 F7FFFF9E BL.W dint (0x080001D2)
62: Port.P0=0;
0x08000296 6818 LDR r0,[r3,#0x00]
0x08000298 F0200001 BIC r0,r0,#0x01
0x0800029C 6018 STR r0,[r3,#0x00]
63: eint();
0x0800029E F7FFFFA5 BL.W eint (0x080001EC)
64: for(i=0;i<0x10;i++);
0x080002A2 F04F0000 MOV r0,#0x00
0x080002A6 F1000001 ADD r0,r0,#0x01
0x080002AA 2810 CMP r0,#0x10
0x080002AC DBFB BLT 0x080002A6
38: dint();
0x080002AE F7FFFF90 BL.W dint (0x080001D2)
39: Port.P6=A.A7;
0x080002B2 6820 LDR r0,[r4,#0x00]
0x080002B4 F3C011C0 UBFX r1,r0,#7,#1
0x080002B8 6818 LDR r0,[r3,#0x00]
0x080002BA F3611086 BFI r0,r1,#6,#1
0x080002BE 6018 STR r0,[r3,#0x00]
40: Port.P0=1;
0x080002C0 6818 LDR r0,[r3,#0x00]
0x080002C2 F0400001 ORR r0,r0,#0x01
0x080002C6 6018 STR r0,[r3,#0x00]
41: eint();
0x080002C8 F7FFFF90 BL.W eint (0x080001EC)
42: for(i=0;i<0x10;i++);
0x080002CC F04F0000 MOV r0,#0x00
0x080002D0 E797 B 0x08000202
0x080002D2 0000 MOVS r0,r0
0x080002D4 E100 B 0x080004D8
0x080002D6 E000 B 0x080002DA
Bu tarz birşey çıkıyor :o , bit işlemlerinde oluşan asm kodları hep aynı, dint ve eint içeriklerini de direk aralara yazıyım mı?
Çok kısa olarak Bit Banding nedir..?
Alıntı Yap
Bu tarz birşey çıkıyor (http://picproje.org/Smileys/default/shocked.gif) , bit işlemlerinde oluşan asm kodları hep aynı, dint ve eint içeriklerini de direk aralara yazıyım mı?
Benim mantığım her bir manüplasyonuna başlangıçta interruptın disable, manüplasyon bitiminde de enable edilmesi gerektiği söylüyor.
Fakat dersenizki ben kodların tepesinde int disable edeceğim, en sonunda da açacağım anlayış gösteririm. Fakat delayler uzun süreli ise intteruptın da bizim kodlarımıza göre önceliği olduğunu varsayarsak her kod arasında enable disable işleminin yapılması gerekir.
Alıntı yapılan: elek - 04 Kasım 2011, 18:58:22
Çok kısa olarak Bit Banding nedir..?
Yaşşa. Şimdi herkez söylesin kendi anladığını. Özellikle de eemkutay.
ben masumum yahu...
öğrenmek için sordum... :)
Bit banding, RAM ve Peripheral registerlerin bitlerine nokta atışı (bit bit) erişim demektir.
Alıntı yapılan: bunalmis - 04 Kasım 2011, 19:12:49
Benim mantığım her bir manüplasyonuna başlangıçta interruptın disable, manüplasyon bitiminde de enable edilmesi gerektiği söylüyor.
Fakat dersenizki ben kodların tepesinde int disable edeceğim, en sonunda da açacağım anlayış gösteririm. Fakat delayler uzun süreli ise intteruptın da bizim kodlarımıza göre önceliği olduğunu varsayarsak her kod arasında enable disable işleminin yapılması gerekir.
dediğiniz doğru hocam ama bu kadar eint dint yapana kadar başka bir çözüm aramak daha mantıklı
volatile unsigned long intstate[2];
struct{
volatile unsigned P0:1;
volatile unsigned P1:1;
volatile unsigned P2:1;
volatile unsigned P3:1;
volatile unsigned P4:1;
volatile unsigned P5:1;
volatile unsigned P6:1;
volatile unsigned P7:1;
}Port __attribute__((at((unsigned long)&GPIOD->ODR)));
struct{
volatile unsigned A0:1;
volatile unsigned A1:1;
volatile unsigned A2:1;
volatile unsigned A3:1;
volatile unsigned A4:1;
volatile unsigned A5:1;
volatile unsigned A6:1;
volatile unsigned A7:1;
}A;
int main(void){
int i;
while(1){
intstate[0]=NVIC->ISER[0];
intstate[1]=NVIC->ISER[1];
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
Port.P6=A.A7;
NVIC->IABR[0]=intstate[0];
NVIC->IABR[1]=intstate[0];
for(i=0;i<0x10;i++);
intstate[0]=NVIC->ISER[0];
intstate[1]=NVIC->ISER[1];
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
Port.P0=1;
NVIC->IABR[0]=intstate[0];
NVIC->IABR[1]=intstate[0];
for(i=0;i<0x10;i++);
intstate[0]=NVIC->ISER[0];
intstate[1]=NVIC->ISER[1];
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
Port.P0=0;
NVIC->IABR[0]=intstate[0];
NVIC->IABR[1]=intstate[0];
for(i=0;i<0x10;i++);
intstate[0]=NVIC->ISER[0];
intstate[1]=NVIC->ISER[1];
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
Port.P2=A.A0;
NVIC->IABR[0]=intstate[0];
NVIC->IABR[1]=intstate[0];
for(i=0;i<0x10;i++);
intstate[0]=NVIC->ISER[0];
intstate[1]=NVIC->ISER[1];
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
Port.P0=1;
NVIC->IABR[0]=intstate[0];
NVIC->IABR[1]=intstate[0];
for(i=0;i<0x10;i++);
intstate[0]=NVIC->ISER[0];
intstate[1]=NVIC->ISER[1];
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
Port.P0=0;
NVIC->IABR[0]=intstate[0];
NVIC->IABR[1]=intstate[0];
for(i=0;i<0x10;i++);
intstate[0]=NVIC->ISER[0];
intstate[1]=NVIC->ISER[1];
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
Port.P4=A.A3;
NVIC->IABR[0]=intstate[0];
NVIC->IABR[1]=intstate[0];
for(i=0;i<0x10;i++);
intstate[0]=NVIC->ISER[0];
intstate[1]=NVIC->ISER[1];
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
Port.P0=1;
NVIC->IABR[0]=intstate[0];
NVIC->IABR[1]=intstate[0];
for(i=0;i<0x10;i++);
intstate[0]=NVIC->ISER[0];
intstate[1]=NVIC->ISER[1];
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
Port.P0=0;
NVIC->IABR[0]=intstate[0];
NVIC->IABR[1]=intstate[0];
for(i=0;i<0x10;i++);
}
}
4: volatile unsigned long intstate[2];
0x080001D0 4770 BX lr
5: void dint(void){
0x080001D2 487D LDR r0,[pc,#500] ; @0x080003C8
6: intstate[0]=NVIC->ISER[0];
0x080001D4 6802 LDR r2,[r0,#0x00]
0x080001D6 497D LDR r1,[pc,#500] ; @0x080003CC
0x080001D8 600A STR r2,[r1,#0x00]
7: intstate[1]=NVIC->ISER[1];
0x080001DA 6842 LDR r2,[r0,#0x04]
0x080001DC 604A STR r2,[r1,#0x04]
8: NVIC->ICER[0]=0xFFFFFFFF;
0x080001DE F04F31FF MOV r1,#0xFFFFFFFF
0x080001E2 F8C01080 STR r1,[r0,#0x80]
9: NVIC->ICER[1]=0xFFFFFFFF;
0x080001E6 F8C01084 STR r1,[r0,#0x84]
10: }
11: void eint(void){
0x080001EA 4770 BX lr
12: NVIC->IABR[0]=intstate[0];
0x080001EC 4877 LDR r0,[pc,#476] ; @0x080003CC
0x080001EE 6802 LDR r2,[r0,#0x00]
0x080001F0 4977 LDR r1,[pc,#476] ; @0x080003D0
0x080001F2 600A STR r2,[r1,#0x00]
13: NVIC->IABR[1]=intstate[0];
0x080001F4 6800 LDR r0,[r0,#0x00]
0x080001F6 6048 STR r0,[r1,#0x04]
14: }
0x080001F8 4770 BX lr
43: Port.P6=A.A7;
44:
0x080001FA 4E74 LDR r6,[pc,#464] ; @0x080003CC
38: intstate[0]=NVIC->ISER[0];
39: intstate[1]=NVIC->ISER[1];
0x080001FC F04F20E0 MOV r0,#0xE000E000
0x08000200 1F36 SUBS r6,r6,#4
0x08000202 1D31 ADDS r1,r6,#4
0x08000204 4B73 LDR r3,[pc,#460] ; @0x080003D4
40: NVIC->ICER[0]=0xFFFFFFFF;
0x08000206 1742 ASRS r2,r0,#29
0x08000208 F8D04100 LDR r4,[r0,#0x100]
0x0800020C 600C STR r4,[r1,#0x00]
39: intstate[1]=NVIC->ISER[1];
40: NVIC->ICER[0]=0xFFFFFFFF;
0x0800020E F8D04104 LDR r4,[r0,#0x104]
0x08000212 604C STR r4,[r1,#0x04]
0x08000214 F8C02180 STR r2,[r0,#0x180]
41: NVIC->ICER[1]=0xFFFFFFFF;
42:
0x08000218 F8C02184 STR r2,[r0,#0x184]
43: Port.P6=A.A7;
44:
0x0800021C 6834 LDR r4,[r6,#0x00]
0x0800021E F3C415C0 UBFX r5,r4,#7,#1
0x08000222 681C LDR r4,[r3,#0x00]
0x08000224 F3651486 BFI r4,r5,#6,#1
0x08000228 601C STR r4,[r3,#0x00]
45: NVIC->IABR[0]=intstate[0];
0x0800022A 680C LDR r4,[r1,#0x00]
0x0800022C F8C04300 STR r4,[r0,#0x300]
46: NVIC->IABR[1]=intstate[0];
0x08000230 680C LDR r4,[r1,#0x00]
0x08000232 F8C04304 STR r4,[r0,#0x304]
47: for(i=0;i<0x10;i++);
0x08000236 2400 MOVS r4,#0x00
0x08000238 1C64 ADDS r4,r4,#1
0x0800023A 2C10 CMP r4,#0x10
0x0800023C DBFC BLT 0x08000238
48: intstate[0]=NVIC->ISER[0];
0x0800023E F8D04100 LDR r4,[r0,#0x100]
0x08000242 600C STR r4,[r1,#0x00]
49: intstate[1]=NVIC->ISER[1];
0x08000244 F8D04104 LDR r4,[r0,#0x104]
0x08000248 604C STR r4,[r1,#0x04]
50: NVIC->ICER[0]=0xFFFFFFFF;
0x0800024A F8C02180 STR r2,[r0,#0x180]
51: NVIC->ICER[1]=0xFFFFFFFF;
52:
0x0800024E F8C02184 STR r2,[r0,#0x184]
53: Port.P0=1;
54:
0x08000252 681C LDR r4,[r3,#0x00]
0x08000254 F0440401 ORR r4,r4,#0x01
0x08000258 601C STR r4,[r3,#0x00]
55: NVIC->IABR[0]=intstate[0];
0x0800025A 680C LDR r4,[r1,#0x00]
0x0800025C F8C04300 STR r4,[r0,#0x300]
56: NVIC->IABR[1]=intstate[0];
0x08000260 680C LDR r4,[r1,#0x00]
0x08000262 F8C04304 STR r4,[r0,#0x304]
57: for(i=0;i<0x10;i++);
0x08000266 2400 MOVS r4,#0x00
0x08000268 1C64 ADDS r4,r4,#1
0x0800026A 2C10 CMP r4,#0x10
0x0800026C DBFC BLT 0x08000268
58: intstate[0]=NVIC->ISER[0];
0x0800026E F8D04100 LDR r4,[r0,#0x100]
0x08000272 600C STR r4,[r1,#0x00]
59: intstate[1]=NVIC->ISER[1];
0x08000274 F8D04104 LDR r4,[r0,#0x104]
0x08000278 604C STR r4,[r1,#0x04]
60: NVIC->ICER[0]=0xFFFFFFFF;
0x0800027A F8C02180 STR r2,[r0,#0x180]
61: NVIC->ICER[1]=0xFFFFFFFF;
62:
0x0800027E F8C02184 STR r2,[r0,#0x184]
63: Port.P0=0;
64:
0x08000282 681C LDR r4,[r3,#0x00]
0x08000284 F0240401 BIC r4,r4,#0x01
0x08000288 601C STR r4,[r3,#0x00]
65: NVIC->IABR[0]=intstate[0];
0x0800028A 680C LDR r4,[r1,#0x00]
0x0800028C F8C04300 STR r4,[r0,#0x300]
66: NVIC->IABR[1]=intstate[0];
0x08000290 680C LDR r4,[r1,#0x00]
0x08000292 F8C04304 STR r4,[r0,#0x304]
67: for(i=0;i<0x10;i++);
0x08000296 2400 MOVS r4,#0x00
0x08000298 1C64 ADDS r4,r4,#1
0x0800029A 2C10 CMP r4,#0x10
0x0800029C DBFC BLT 0x08000298
68: intstate[0]=NVIC->ISER[0];
0x0800029E F8D04100 LDR r4,[r0,#0x100]
0x080002A2 600C STR r4,[r1,#0x00]
69: intstate[1]=NVIC->ISER[1];
0x080002A4 F8D04104 LDR r4,[r0,#0x104]
0x080002A8 604C STR r4,[r1,#0x04]
70: NVIC->ICER[0]=0xFFFFFFFF;
0x080002AA F8C02180 STR r2,[r0,#0x180]
71: NVIC->ICER[1]=0xFFFFFFFF;
72:
0x080002AE F8C02184 STR r2,[r0,#0x184]
73: Port.P2=A.A0;
74:
0x080002B2 6834 LDR r4,[r6,#0x00]
0x080002B4 681D LDR r5,[r3,#0x00]
0x080002B6 F3640582 BFI r5,r4,#2,#1
0x080002BA 601D STR r5,[r3,#0x00]
75: NVIC->IABR[0]=intstate[0];
0x080002BC 680C LDR r4,[r1,#0x00]
0x080002BE F8C04300 STR r4,[r0,#0x300]
76: NVIC->IABR[1]=intstate[0];
0x080002C2 680C LDR r4,[r1,#0x00]
0x080002C4 F8C04304 STR r4,[r0,#0x304]
77: for(i=0;i<0x10;i++);
0x080002C8 2400 MOVS r4,#0x00
0x080002CA 1C64 ADDS r4,r4,#1
0x080002CC 2C10 CMP r4,#0x10
0x080002CE DBFC BLT 0x080002CA
78: intstate[0]=NVIC->ISER[0];
0x080002D0 F8D04100 LDR r4,[r0,#0x100]
0x080002D4 600C STR r4,[r1,#0x00]
79: intstate[1]=NVIC->ISER[1];
0x080002D6 F8D04104 LDR r4,[r0,#0x104]
0x080002DA 604C STR r4,[r1,#0x04]
80: NVIC->ICER[0]=0xFFFFFFFF;
0x080002DC F8C02180 STR r2,[r0,#0x180]
81: NVIC->ICER[1]=0xFFFFFFFF;
82:
0x080002E0 F8C02184 STR r2,[r0,#0x184]
83: Port.P0=1;
84:
0x080002E4 681C LDR r4,[r3,#0x00]
0x080002E6 F0440401 ORR r4,r4,#0x01
0x080002EA 601C STR r4,[r3,#0x00]
85: NVIC->IABR[0]=intstate[0];
0x080002EC 680C LDR r4,[r1,#0x00]
0x080002EE F8C04300 STR r4,[r0,#0x300]
86: NVIC->IABR[1]=intstate[0];
0x080002F2 680C LDR r4,[r1,#0x00]
0x080002F4 F8C04304 STR r4,[r0,#0x304]
87: for(i=0;i<0x10;i++);
0x080002F8 2400 MOVS r4,#0x00
0x080002FA 1C64 ADDS r4,r4,#1
0x080002FC 2C10 CMP r4,#0x10
0x080002FE DBFC BLT 0x080002FA
88: intstate[0]=NVIC->ISER[0];
0x08000300 F8D04100 LDR r4,[r0,#0x100]
0x08000304 600C STR r4,[r1,#0x00]
89: intstate[1]=NVIC->ISER[1];
0x08000306 F8D04104 LDR r4,[r0,#0x104]
0x0800030A 604C STR r4,[r1,#0x04]
90: NVIC->ICER[0]=0xFFFFFFFF;
0x0800030C F8C02180 STR r2,[r0,#0x180]
91: NVIC->ICER[1]=0xFFFFFFFF;
92:
0x08000310 F8C02184 STR r2,[r0,#0x184]
93: Port.P0=0;
94:
0x08000314 681C LDR r4,[r3,#0x00]
0x08000316 F0240401 BIC r4,r4,#0x01
0x0800031A 601C STR r4,[r3,#0x00]
95: NVIC->IABR[0]=intstate[0];
0x0800031C 680C LDR r4,[r1,#0x00]
0x0800031E F8C04300 STR r4,[r0,#0x300]
96: NVIC->IABR[1]=intstate[0];
0x08000322 680C LDR r4,[r1,#0x00]
0x08000324 F8C04304 STR r4,[r0,#0x304]
97: for(i=0;i<0x10;i++);
0x08000328 2400 MOVS r4,#0x00
0x0800032A 1C64 ADDS r4,r4,#1
0x0800032C 2C10 CMP r4,#0x10
0x0800032E DBFC BLT 0x0800032A
98: intstate[0]=NVIC->ISER[0];
0x08000330 F8D04100 LDR r4,[r0,#0x100]
0x08000334 600C STR r4,[r1,#0x00]
99: intstate[1]=NVIC->ISER[1];
0x08000336 F8D04104 LDR r4,[r0,#0x104]
0x0800033A 604C STR r4,[r1,#0x04]
100: NVIC->ICER[0]=0xFFFFFFFF;
0x0800033C F8C02180 STR r2,[r0,#0x180]
101: NVIC->ICER[1]=0xFFFFFFFF;
102:
0x08000340 F8C02184 STR r2,[r0,#0x184]
103: Port.P4=A.A3;
104:
0x08000344 6834 LDR r4,[r6,#0x00]
0x08000346 F3C405C0 UBFX r5,r4,#3,#1
0x0800034A 681C LDR r4,[r3,#0x00]
0x0800034C F3651404 BFI r4,r5,#4,#1
0x08000350 601C STR r4,[r3,#0x00]
105: NVIC->IABR[0]=intstate[0];
0x08000352 680C LDR r4,[r1,#0x00]
0x08000354 F8C04300 STR r4,[r0,#0x300]
106: NVIC->IABR[1]=intstate[0];
0x08000358 680C LDR r4,[r1,#0x00]
0x0800035A F8C04304 STR r4,[r0,#0x304]
107: for(i=0;i<0x10;i++);
0x0800035E 2400 MOVS r4,#0x00
0x08000360 1C64 ADDS r4,r4,#1
0x08000362 2C10 CMP r4,#0x10
0x08000364 DBFC BLT 0x08000360
108: intstate[0]=NVIC->ISER[0];
0x08000366 F8D04100 LDR r4,[r0,#0x100]
0x0800036A 600C STR r4,[r1,#0x00]
109: intstate[1]=NVIC->ISER[1];
0x0800036C F8D04104 LDR r4,[r0,#0x104]
0x08000370 604C STR r4,[r1,#0x04]
110: NVIC->ICER[0]=0xFFFFFFFF;
0x08000372 F8C02180 STR r2,[r0,#0x180]
111: NVIC->ICER[1]=0xFFFFFFFF;
112:
0x08000376 F8C02184 STR r2,[r0,#0x184]
113: Port.P0=1;
114:
0x0800037A 681C LDR r4,[r3,#0x00]
0x0800037C F0440401 ORR r4,r4,#0x01
0x08000380 601C STR r4,[r3,#0x00]
115: NVIC->IABR[0]=intstate[0];
0x08000382 680C LDR r4,[r1,#0x00]
0x08000384 F8C04300 STR r4,[r0,#0x300]
116: NVIC->IABR[1]=intstate[0];
0x08000388 680C LDR r4,[r1,#0x00]
0x0800038A F8C04304 STR r4,[r0,#0x304]
117: for(i=0;i<0x10;i++);
0x0800038E 2400 MOVS r4,#0x00
0x08000390 1C64 ADDS r4,r4,#1
0x08000392 2C10 CMP r4,#0x10
0x08000394 DBFC BLT 0x08000390
118: intstate[0]=NVIC->ISER[0];
0x08000396 F8D04100 LDR r4,[r0,#0x100]
0x0800039A 600C STR r4,[r1,#0x00]
119: intstate[1]=NVIC->ISER[1];
0x0800039C F8D04104 LDR r4,[r0,#0x104]
0x080003A0 604C STR r4,[r1,#0x04]
120: NVIC->ICER[0]=0xFFFFFFFF;
0x080003A2 F8C02180 STR r2,[r0,#0x180]
121: NVIC->ICER[1]=0xFFFFFFFF;
122:
0x080003A6 F8C02184 STR r2,[r0,#0x184]
123: Port.P0=0;
124:
0x080003AA 681C LDR r4,[r3,#0x00]
0x080003AC F0240401 BIC r4,r4,#0x01
0x080003B0 601C STR r4,[r3,#0x00]
125: NVIC->IABR[0]=intstate[0];
0x080003B2 680C LDR r4,[r1,#0x00]
0x080003B4 F8C04300 STR r4,[r0,#0x300]
126: NVIC->IABR[1]=intstate[0];
0x080003B8 680C LDR r4,[r1,#0x00]
0x080003BA F8C04304 STR r4,[r0,#0x304]
127: for(i=0;i<0x10;i++);
0x080003BE 2400 MOVS r4,#0x00
0x080003C0 1C64 ADDS r4,r4,#1
0x080003C2 2C10 CMP r4,#0x10
0x080003C4 DBFC BLT 0x080003C0
0x080003C6 E71F B 0x08000208
yani, 0' ı 1 yapmak veya tersi....ya da okumak...
Alıntı yapılan: ErsinErce - 04 Kasım 2011, 17:24:07
Anladım hocam teşekkürler,
IAR'da MISRA C denetleyicisi vardı hatırladığım kadarıyla, bir yandan iyi gibi aslında bug oluşmasının önüne geçilmek isteniyor.
Kodlarken ne tarz sorunlar çıkartığına dair bir fikir oluşturması için aklınızda kalan ufak bir kaç örnek varsa bilgilendirebilir misiniz hocam?
Şuan örnekler tam aklımda değil ama inline kullanıma izin vermiyordu ve enumeration kullanımlarında keille uyuşmayan durumlar çıkmıştı. Keil rahatlıkla derlerken iar'da hata veriyordu. Sonra derleyiciye göre tanımlamalarla sorunu çözdüm.
@bunalmış
Hadi herkes kendi yoluna, bundan sonra benim nick'imi kapsayan yazılar yazma.
C ile ,(derleyici olarak fark etmez) , Sram deki herhangi bir baytın ,örnek olarak atıyorum 1. bayt olsun 0x1, 1. bitini maskeleme ile set eden kod bu mudur?
char a; // a'nın adresinin 0x1 olduğunu farz edelim
a|=1;
Kod buysa ,derleyicinin bu c kodu için üretebileceği en optimize asm kodu nedir? En optimize c kodu bu değilse nedir ve en optimize asm karşılığı nedir?
u
Alıntı yapılan: eemkutay - 04 Kasım 2011, 20:46:29
@bunalmış
Hadi herkes kendi yoluna, bundan sonra benim nick'imi kapsayan yazılar yazma.
Müsade et de buna ben karar vereyim. Hatalı sorduğumu belirttiğim ve ve ardından soruyu düzeltiğim son soruma enginnnnnn C bilginle bir el atarmısın?
Alıntı yapılan: elek - 04 Kasım 2011, 18:58:22
Çok kısa olarak Bit Banding nedir..?
Kolaylık,
bazı işlemler-durumlar için alternatif ,güvenilir ve hızlı bir yol.
Düz mantık ;
Adamlar hata yaptı m3 e koydu aynı adamlar kimsenin kullanmadığını bile bile(2-3 antika adam kullanıyor diye :) ) gene hata yapıp m4 de de koymuşlar,hemde donanımsal bişeyi...???
Yorumum; demek ki genel olarak interrup tu iptal etmeden bir biti özellikle ortak kullanılan sram alanı üzerindeki bir biti set yada reset etmek elzem olabiliyormuş ki adamlar bunu hw ye gömmüş...
Ayrıca dökümandan bulduğum bir örnekde bitband ile 80 ns de yaptığı işi diğer yöntemle 180 ns de yazmış ancak en optimize kod olduğundan konuya hakim olmadığımdan bişey diyemiyorum.
Bu arada sanırım güzel birşey buldum en azından keil için bit bandı daha konforlu kullanmaya yaradığını düşünüyorum.
@Eemkutay'ın yazdığı structure yapısına benzer biçimde,aynı konfor yakalanamayacağını düşünüyorum, bitbanding i kullanmaya yarıyor sanırım.
Alıntı Yaptypedef struct {
int i : 1;
int j : 2;
int k : 3;
} BB __attribute__((bitband));
BB bb __attribute__((at(0x20000004));
void foo(void)
{
bb.i = 1;
}
http://www.keil.com/support/man/docs/armccref/armccref_babcbgfc.htm (http://www.keil.com/support/man/docs/armccref/armccref_babcbgfc.htm)
Bunun örneğini yapıp kullanmaya çalışıcam...
Alıntı yapılan: mcan - 04 Kasım 2011, 21:00:11
C ile ,(derleyici olarak fark etmez) , Sram deki herhangi bir baytın ,örnek olarak atıyorum 1. bayt olsun 0x1, 1. bitini maskeleme ile set eden kod bu mudur?
char a; // a'nın adresinin 0x1 olduğunu farz edelim
a|=1;
Kod buysa ,derleyicinin bu c kodu için üretebileceği en optimize asm kodu nedir? En optimize c kodu bu değilse nedir ve en optimize asm karşılığı nedir?
ARM işlemcilerde optimizasyon tek bir komut için yapılmaz. Bir önceki satırda ne yaptık, şimdi ne yapacağım bir sonraki satırda hangi komutu işleteceğim sorularına göre yapılır.
a|=1; C komutu normalde 4 ASM komutu ister. Fakat peş peşe gelen C yada asm kodların durumuna göre bu bazen tek asm komutla dahi yazılabilir.
Alıntı yapılan: bunalmis - 04 Kasım 2011, 22:06:18
ARM işlemcilerde optimizasyon tek bir komut için yapılmaz. Bir önceki satırda ne yaptık, şimdi ne yapacağım bir sonraki satırda hangi komutu işleteceğim sorularına göre yapılır.Peş peşe gelen C yada asm kodların durumuna göre bu bazen tek asm komutla dahi yazılabilir.
wayyy ,neden? Bu işin pipeline ile alakası var mı? Belki alakası bile olmayabilir ama okuduğum şeyleri bağlantılamaya oturtmaya çalışıyorum. :o
Kodu denedim çalışıyor , kullanmak isteyenler için örnek olarak buraya koyuyorum.
Bitbanding hemende yarı structure konforu ile, yarı diyorum çünki 1 den fazla bite erişmek nasıl bişey olur yada 1 bitten daha büyük değişken tanımlarsak nasıl bir kayma olur bilemiyorum...
#include "STM32F10x.h"
#define BIT_LEVEL_SRAM(a,b) ((SRAM_BB_BASE + (a-SRAM_BASE)*32 + (b*4)))
#define BIT_LEVEL_PERI(a,b) ((PERIPH_BB_BASE + (a-PERIPH_BASE)*32 + (b*4)))
#define RCC_APB2ENR (RCC_BASE+0x018)
#define GPIO_C_ENABLE *((volatile unsigned int *)(BIT_LEVEL_PERI(RCC_APB2ENR,4)))
void delay(unsigned int);
static int ih;
int zg,ipb,ii;
typedef struct {
int Pin0 : 1;
int Pin1 : 1;
int Pin2 : 1;
int Pin3 : 1;
int Pin4 : 1;
int Pin5 : 1;
int Pin6 : 1;
int Pin7 : 1;
int Pin8 : 1;
int Pin9 : 1;
} BB __attribute__((bitband));
BB PortC __attribute__((at(GPIOC_BASE+0x0C)));
void TIM7_IRQHandler(void)
{
ih =!ih ;
while(TIM7->SR)
{
TIM7->SR = 0x0;
}
}
void SystemInit (void)
{
delay(0x880000);
GPIO_C_ENABLE = 1 ;
//RCC->APB2ENR |= 0x00000016; // GPIOD donanımının clock sinyalini uygulayalım
GPIOC->CRL = 0x37333333; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOC->CRH = 0x33333333;
RCC->CR |= 0x0010000; // HSE ON
RCC->CFGR = 0x001D0000; // PLL ayarla
RCC->CR |= 0x001000000; // PLL aç
FLASH->ACR = 0x32; // Flash gecikme ayarı
RCC->CFGR = 0x001D0702; // SİNYAL KAYNAĞI PLL APB1 HCLK/16
RCC->APB1ENR |= 0x00000020; //Timer7 ye clock verelim
TIM7->DIER = 0x1;
TIM7->PSC = 0x1FF; //182=B6 182*5= H393
TIM7->ARR = 0xFFFF;
TIM7->CR1 = 0x85;
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
}
void delay(unsigned int i)
{ unsigned int z;
for(z=0;z<i;z++);
}
int main()
{
while(1)
{
if(ih)
PortC.Pin5 = 1; //GPIOC->ODR= 0x20; // Ledler yansin
else
PortC.Pin9 = 1; //GPIOC->ODR= 0x200; // Ledler yansin
delay(0x40000);
GPIOC->ODR= 0x00000000; // Ledler sonsun
delay(0x40000);
}
}
Komutumuz "PortC.Pin5 = 1;" buna indirgendi...
@Eemkutay sizin derleyici hangisi? structure için isimden sonra nokta koyduğumda bana structure içerik seçeneklerini göstermiyor.
Alıntı yapılan: eemkutay - 04 Kasım 2011, 17:04:32
Bunalmış,
Kaçmak mı? Ben senin gibi değilim, ben haksız olduğuma inansaydım haklısın diyebilme erdemine sahibim. Ama sen bundan yoksunsun. Seni şahsen tanımıyorum ama forumda iyi tanıyorum. Hiçbirşeyi kabullenmeyen, öğrenmeye kapalı bir yapın var. Daha önceleri seninle asm ve c tartışmamız olmuştu. C'yi kötüleyip duruyordun, o zamanlar şimdiki gibi ns saniye hesabı yapıyordun. Ne oldu? Aradan zaman geçti daha yeni benim dediğime geldin. Şimdide aynısı olacak. Yakında C'de benim yazdığım gibi yazmayı öğreneceksin. Herzaman senin 3-5 adım önünde olacağım. Bu meslekte ve bu forumda tek çalışkan ve başarılı insan kendin sanıyorsun galiba.
Başlangıçta bitbanding için sen 1 cycle'da çalışıyor dedin, ben 3 dedim. Sonra baktın yanlışsın lafı çevirdin, "en iyi ihtimalle 1 cycle" "en kötü ihtimalle 3 cycle" demeye başladın. Maksat "evet haklısın diyememek". Sonra bazı arkadaşlar netten kaynak falan çıkardılar, bu defa maskelemeden daha verimli olur demeye başladın. Hala da konuşabiliyorsun ve bana kaçma gibi bir laf söylüyorsun.
Seninle bu konu hakkında konuşmam için önce yukarıda bana sorduğun soruyu bitbanding ile yaz ve asm sonucunu buraya koy ve benim yukarıda yazdığım programla karşılaştıralım. Hem C formatını hemde asm formatını. Bana sözlü olarak bişeyler söylemen anlamsız, asm sonuçlarına bakarım. Asm çıktıda ezici üstünlük sağla, sonra konuşma hakkın olsun.
Bitbanding'in, hangi durumda 1 cycle, hangi durumda N cycle isleyecegini bilmiyorsam yazmami istedigin asagida kodlardaki senaryoyu kurgulayabilirmiyim acaba?
(Simdiki ornekte de tek cycle'da bit banding yaptim. Yani, 8 bit icindeki her hangi bir biti tec cycle'da cekip cikarttim)
Ilk kez, bitbandingi tek cycle da yaptigimi telafuz ettigim mesaji asagiya alintiladim. Acaba bu adam orneginde ne yapmis ta tek cycle da bitbanding yaptigini iddia ediyor dedin mi acaba?
Alıntı yapılan: bunalmis - 02 Kasım 2011, 10:16:25
Linkini verdiğim programda init aşaması geçildikten sonra, bit atamalarını sadece tek makine cycle'ında yapıyor.
Örneğin 10 adet biti tek tek set yada reset edeceksen bu sadece 10 makine cycle'ı demek. Bundan daha hızlı bit manuplasyonu da olmaz. (Her clockta bir bit set yada reset)
Burada tek makine cycle'inda bit banding yaptigimi iddia ettigim ornege bir bak lutfen. Soz konusu mesajimda, [/color]init aşaması geçildikten sonra, bit atamalarını sadece tek makine cycle'ında yapıyor da demistim. Yani, while icinde 3..4 satirlik initialize islemi bittikten sonra dan da bahsetmisim.
Fakat bu vurgularimi gormemezlikten gelip hemen hemen her mesajinda (asagidaki mesajinda oldugu gibi)
"her sart ve kosulda, bitbangi 1 cycle da" yapabilecegimi iddia etmisim gibi sozlerimi genellemeye calisiyorsun.
Alıntı yapılan: eemkutay - 04 Kasım 2011, 00:25:37
..... Diyosun ki "bit dandik" tek saykılda çalışıyor bende sana gerçek register adreslerini kullanarak hızlı çalışmasını bana ispatla dedim.
Gordugun gibi soylemedigim ustelik tamamen sana ait sozleri sanki benim sozlerimmis gibi bana itham ediyorsun.
Senin butun derdin asagidaki iddiani gecersiz kilmis olmam.
Alıntı yapılan: eemkutay - 30 Ekim 2011, 23:06:21
Bit Banding'i keil ve iar'da denemiştim, zamanlama anlamında büyük bir avantaj getirmiyor. Maskele ile aynı sonuçları almıştım. Ama tabii belki sizi bit maskelemekten kurtarır fakat aynı şeyi güzel bir macro ile sizde yazabilirsiniz.
Gecmisteki mesajlarimda C ye cok atip tuttum, su anda C yi ovuyor da degilim. C diliyle kod da yazarim fakat C, kafamdan gecen herseyi ozgurce kodlamama izin vermiyor yada ben beceremiyorum. Asagidaki C'nin main fonksiyonuna yazdigim kodlari malesef C satirlarina dokemem. Bu kodlari urettirecek C kodlarini sanirim sen ileri C bilginle yazabilirsin.
Alıntı yapılan: eemkutay - 04 Kasım 2011, 11:02:16
Aşağıya yazdım , hemde low optimizasyon seviyesinde yazdım. Senin gibi 2 tane biti while içine alıp hazırlama kısımlarını while dışında bırakan level 3 optimizasyon kullanmadan. Topu topu 20 tane asm komutu yetti de arttı bile. Hemde yazdığım kodda tüm parametreler değiştirilebilir, anlaşılır , 32bit sayılarla uğraşmadan ve hızlı.
Şimdi yukarıda söylediğin gibi bana bitbanding'in avantajını hemen göster. (sözlerle değil asm ile)
Emredersin. C satirlarim asagida. :)
[/color]#include "STM32F4xx.h"
void SystemInit()
{
}
volatile unsigned char A[]={1,7,0};
int __asm main()
{
PUSH {R4-R9}
LDR R9,=__cpp((unsigned)&A)
MOV R1,#0x22000000
ADD R8,R1,R9,LSL #5
LDM R8!,{R0-R7}
LDM R8!,{R4-R7}
ORR R7,R2,LSL #1
ORR R7,R5,LSL #2
ORR R7,R0,LSL #3
ORR R7,R6,LSL #4
ORR R7,R1,LSL #5
ORR R7,R4,LSL #6
ORR R7,R3,LSL #7
STR R7,[R9,#2]
POP {R4-R9}
}
ASM ciktisi da asagida.
11: PUSH {R4-R9}
0x08000238 E92D03F0 PUSH {r4-r9}
12: LDR R9,=__cpp((unsigned)&A)
0x0800023C F8DF9034 LDR.W r9,[pc,#52] ; @0x08000274
13: MOV R1,#0x22000000
0x08000240 F04F5108 MOV r1,#0x22000000
14: ADD R8,R1,R9,LSL #5
0x08000244 EB011849 ADD r8,r1,r9,LSL #5
15: LDM R8!,{R0-R7}
0x08000248 E8B800FF LDM r8!,{r0-r7}
16: LDM R8!,{R4-R7}
0x0800024C E8B800F0 LDM r8!,{r4-r7}
17: ORR R7,R2,LSL #1
0x08000250 EA470742 ORR r7,r7,r2,LSL #1
18: ORR R7,R5,LSL #2
0x08000254 EA470785 ORR r7,r7,r5,LSL #2
19: ORR R7,R0,LSL #3
0x08000258 EA4707C0 ORR r7,r7,r0,LSL #3
20: ORR R7,R6,LSL #4
0x0800025C EA471706 ORR r7,r7,r6,LSL #4
21: ORR R7,R1,LSL #5
0x08000260 EA471741 ORR r7,r7,r1,LSL #5
22: ORR R7,R4,LSL #6
0x08000264 EA471784 ORR r7,r7,r4,LSL #6
23: ORR R7,R3,LSL #7
0x08000268 EA4717C3 ORR r7,r7,r3,LSL #7
24: STR R7,[R9,#2]
0x0800026C F8C97002 STR r7,[r9,#0x02]
25: POP {R4-R9}
0x08000270 E8BD03F0 POP {r4-r9}
Kriter olarak bindbanding kullanimini sart kostugun ve
asm kodlarin sayisina taktigin icin, sana 15 opcode luk + bitbanding calisan program yazdim. Buda senin ovundugun 20 satirlik koda gore %25 daha az satir demek. Kodlarim, bitbandingin ezici ustunlugunu ne kadar gosterir bilmiyorum fakat ezici ustunlugu gormek istersen son soruma cevap olacak kodlari yazmani istiyorum.
Tum bunlardan sonra, bir ozur hakettigimi dusunuyorum. Cunku, En tepeye yerlestirdigim alintinin iceriginde oldugu gibi dogrudan kisilere degil yanlis fikirlere saldirmamalisin.
Alıntı yapılan: mcan - 04 Kasım 2011, 22:11:48
vayyy ,neden? Bu işin pipeline ile alakası var mı? Belki alakası bile olmayabilir ama okuduğum şeyleri bağlantılamaya oturtmaya çalışıyorum. :o
Hayir bunun pipeline ile hic alakasi yok. ARM mimarisinde CPU registerleri cok fazla. Herhangi bir amaci gerceklestirecek tek satirlik kod yazilirken ihtiyac olunan degerler eger CPU registerlerinin icinde zaten hazirda varsa, bu deger tekrardan register icine kodla yerlestirilmez var olan registerler o anki komutun parametresi olarak kullaniliverir.
Ornegin
Bir onceki satirda y=A+B islemini yaptiysan, bir sonraki satirda da G=Y+B islemi yapacaksan
ilk satirda Y = A + B de , Y, A , B yi fakli registerlerde tutarsin. Ardindan gelen G = Y + B icin Y ve B yi yeniden registerlere yerlestirmeye calismaz zaten regisyerlerde hazir olan Y ve B yi toplayiverirsin.
Bu nedenle, registerler ne sakliyordu, simdi registerlere ne yuklemeliyim gelecekte ne saklamali, hangisi register icerigi feda edilmeli sorularinin cevabi ARM icin optimize kodlarin olusturulmasinda cok onemlidir. Malesef bunu asm yazimda tamamen siz kurgularken C derleyicisinin optimizasyon yetenegi belirler.
Bu nedenle C kodlarinin optimize edilmis ASM ciktilarina dikkat ederseniz, ornegin programin pek cok yerinde gecen Y=A+B islemine karsilik gelen asm kodlarin her defasinda farkli CPU registerleri uzerinden yurutuldugunu gorursunuz.
Bu nedenle Y=A+B bazen 1 cycle da bazen de 4 cycle da isletilir.
Ozellikle de ARM islemci icin, C de yazilan bir komut parcasinin kac cycle tutacagindan asla emin olamazsiniz. Zaten bitbanding konusunun uzamasina sebep olan yok 1 cycle di yok 3 cycle di tartismasinin altinda da benzer sebepler var.
Şimdi yukarıda yazdığın C programlama dili mi? Programı C içinde "asm bloğu" olarak yazıp buna C mi diyorsun? Eğer bu C programlama dili ise portable olması gerekir şimdi bunu GCC, iar, Raisonance'da derle veya arm veya arm cortex m3 olmayan başka bir işlemcide ama noktasına kadar değiştirmeden. Derlerseler sen haklısın diyeceğim ve özür dileceğim.
Benim istediğim cevap bu değil, doğrudan C keyword'leri ile ve bitbanding ile bana bu programı yaz.
Neyse gel tatliya baglayalim. Bitirelim bu konuyu. Ozur de beklemiyorum.
Verdigim ASM program kisaliginda sonuc uretecek seviyede C bilmiyorum. Fakat bu asm kodlar, en azindan cok eski zamanlardaki C-ASM tartismalarina yeterli cevap olmustur.
Kodlari bu haliyle Keil haricindeki diger derleyicilerde derlemeye kalkarsak sorun cikartabilir. Fakat sorunu cikartacak kisim, asm kodlar degil, __asm ve _CPP olan C tanimlayicilari olabilir. Belli basli platformlarda sorunsuz derlenebilmesi icin bir header dosyaya, derleyici IAR ise su eki kullan, Keil ise su eki kullan seklinde #ifdef ile tanimlamalar yapiliyor. Bu gune kadar hic bir zaman, tasinabilir kod yazimi amaci gutmedigimden verdigim koda da bu tur tanimlamalar eklemedim fakat istersen ugrasirim zor bir sey degil cunku.
Yeni tartismalar baslatmamasi icin hemen belirtmeliyim ki verdigim kodlari, hizli kossun diye degil sirf kisa olmasini istedigin icin bu sekilde yazdim.
@Bunalmis sizin bahsettiğinizi denemeye çalıştım ,evet sonuçler bu şekilde
Alıntı Yap 89: PortC.Pin5 = 1;
90: //else
0x080002CC F04F0001 MOV r0,#0x01
0x080002D0 4924 LDR r1,[pc,#144] ; @0x08000364
0x080002D2 F8C10188 STR r0,[r1,#0x188]
91: portc.Pin9 = 1;
0x080002D6 4824 LDR r0,[pc,#144] ; @0x08000368
0x080002D8 6800 LDR r0,[r0,#0x00]
0x080002DA F4207000 BIC r0,r0,#0x200
0x080002DE F5007000 ADD r0,r0,#0x200
0x080002E2 4921 LDR r1,[pc,#132] ; @0x08000368
0x080002E4 6008 STR r0,[r1,#0x00]
92: PortC.Pin5 = 1;
0x080002E6 F04F0001 MOV r0,#0x01
0x080002EA 491E LDR r1,[pc,#120] ; @0x08000364
0x080002EC F8C10188 STR r0,[r1,#0x188]
93: portc.Pin9 = 1;
0x080002F0 481D LDR r0,[pc,#116] ; @0x08000368
0x080002F2 6800 LDR r0,[r0,#0x00]
0x080002F4 F4207000 BIC r0,r0,#0x200
0x080002F8 F5007000 ADD r0,r0,#0x200
0x080002FC 491A LDR r1,[pc,#104] ; @0x08000368
0x080002FE 6008 STR r0,[r1,#0x00]
94: portc.Pin9 = 1;
0x08000300 4608 MOV r0,r1
0x08000302 6800 LDR r0,[r0,#0x00]
0x08000304 F4207000 BIC r0,r0,#0x200
0x08000308 F5007000 ADD r0,r0,#0x200
0x0800030C 6008 STR r0,[r1,#0x00]
95: PortC.Pin5 = 1;
0x0800030E F04F0001 MOV r0,#0x01
0x08000312 4914 LDR r1,[pc,#80] ; @0x08000364
0x08000314 F8C10188 STR r0,[r1,#0x188]
96: PortC.Pin5 = 1;
0x08000318 F8C10188 STR r0,[r1,#0x188]
Ard arda gelmedikçe fazla kısalma olmuyor ama ard- arda gelinc bit banding tek komuta ,maskeleme ise 5 komuta düşüyor....
Bitbanding ile maskeleme yöntemini karşılaştırmaya çalışıyorum.
Yazdığım kod budur
#include "STM32F10x.h"
#define BIT_LEVEL_SRAM(a,b) ((SRAM_BB_BASE + (a-SRAM_BASE)*32 + (b*4)))
#define BIT_LEVEL_PERI(a,b) ((PERIPH_BB_BASE + (a-PERIPH_BASE)*32 + (b*4)))
#define RCC_APB2ENR (RCC_BASE+0x018)
#define GPIO_C_ENABLE *((volatile unsigned int *)(BIT_LEVEL_PERI(RCC_APB2ENR,4)))
void delay(unsigned int);
static int ih;
int zg,ipb,ii;
typedef struct {
int Pin0 : 1;
int Pin1 : 1;
int Pin2 : 1;
int Pin3 : 1;
int Pin4 : 1;
int Pin5 : 1;
int Pin6 : 1;
int Pin7 : 1;
int Pin8 : 1;
int Pin9 : 1;
} BB __attribute__((bitband));
BB PortC __attribute__((at(GPIOC_BASE+0x0C)));
typedef struct {
int Pin0 : 1;
int Pin1 : 1;
int Pin2 : 1;
int Pin3 : 1;
int Pin4 : 1;
int Pin5 : 1;
int Pin6 : 1;
int Pin7 : 1;
int Pin8 : 1;
int Pin9 : 1;
} BM;
BM portc __attribute__((at(GPIOC_BASE+0x0C)));
void TIM7_IRQHandler(void)
{
ih =!ih ;
while(TIM7->SR)
{
TIM7->SR = 0x0;
}
}
void SystemInit (void)
{
delay(0x880000);
GPIO_C_ENABLE = 1 ;
//RCC->APB2ENR |= 0x00000016; // GPIOD donanımının clock sinyalini uygulayalım
GPIOC->CRL = 0x37333333; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOC->CRH = 0x33333333;
RCC->CR |= 0x0010000; // HSE ON
RCC->CFGR = 0x001D0000; // PLL ayarla
RCC->CR |= 0x001000000; // PLL aç
FLASH->ACR = 0x32; // Flash gecikme ayarı
RCC->CFGR = 0x001D0702; // SİNYAL KAYNAĞI PLL APB1 HCLK/16
RCC->APB1ENR |= 0x00000020; //Timer7 ye clock verelim
TIM7->DIER = 0x1;
TIM7->PSC = 0x1FF; //182=B6 182*5= H393
TIM7->ARR = 0xFFFF;
TIM7->CR1 = 0x85;
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
}
void delay(unsigned int i)
{ unsigned int z;
for(z=0;z<i;z++);
}
int main()
{
while(1)
{
//if(ih)
PortC.Pin5 = 1; //GPIOC->ODR= 0x20; // Ledler yansin
//else
portc.Pin9 = 1; //GPIOC->ODR= 0x200; // Ledler yansin
delay(0x40000);
GPIOC->ODR = 0x00; // Ledler sonsun
delay(0x40000);
}
}
Üretilen asm kod bu şekilde;
Alıntı Yap 89: PortC.Pin5 = 1; //GPIOC->ODR= 0x20; // Ledler yansin
90: //else
0x080002CC F04F0001 MOV r0,#0x01
0x080002D0 4916 LDR r1,[pc,#88] ; @0x0800032C
0x080002D2 F8C10188 STR r0,[r1,#0x188]
91: portc.Pin9 = 1; //GPIOC->ODR= 0x200; // Ledler yansin
0x080002D6 4816 LDR r0,[pc,#88] ; @0x08000330
0x080002D8 6800 LDR r0,[r0,#0x00]
0x080002DA F4207000 BIC r0,r0,#0x200
0x080002DE F5007000 ADD r0,r0,#0x200
0x080002E2 4913 LDR r1,[pc,#76] ; @0x08000330
0x080002E4 6008 STR r0,[r1,#0x00]
Şimdi kırmızı bit banding e ait olduğunu düşündüğüm kodlar ve mavi ise maskeleme yöntemi.
3 adet Kırmızı kod, 6 adet mavi kod var... Eğer ki pinlere sabit değilde değişken üzerinden veri aktarırsak; 4 adet Kırmızı koda karşılık 7 adet mavi kod oluşuyor.
@Eemkutay sizin anlatmak istediğinizi konuya hakim olmadığımdan tam anlayamadım.Koda bakarak yöntemler arasında en az 3 kod sayısınca farkın olduğunu düşünüyorum ,acaba bu fark derleyicinin optimizasyonunun düşük olduğundanmı yoksa arada hiç fark yok mu?
Gelecek kartlara 2x16 LCD bağladığımızda 3.3V ile 5V beslenen LCD yi sürebilirmiyiz. Yoksa data girişlerine pull up direnç mi takılması gerekli. Veya başka bir yol?
LCD, 3.3v sinyalleri kabul etmiyorsa, Rehhber sayda 148 den OTYPER registerinden outputlar openadrain olarak secilebiliyor. Hard sayfa 48'de de 5v tolaransli bacaklar belli. Bu durumda en kotu ihtimalle birer pull up direncle sorun cozulur gorunuyor. (Denemis degilim)
Alıntı yapılan: bunalmis - 05 Kasım 2011, 14:46:19
Neyse gel tatliya baglayalim. Bitirelim bu konuyu. Ozur de beklemiyorum.
Verdigim ASM program kisaliginda sonuc uretecek seviyede C bilmiyorum. Fakat bu asm kodlar, en azindan cok eski zamanlardaki C-ASM tartismalarina yeterli cevap olmustur.
Kodlari bu haliyle Keil haricindeki diger derleyicilerde derlemeye kalkarsak sorun cikartabilir. Fakat sorunu cikartacak kisim, asm kodlar değil, __asm ve _CPP olan C tanimlayicilari olabilir. Belli basli platformlarda sorunsuz derlenebilmesi icin bir header dosyaya, derleyici IAR ise su eki kullan, Keil ise su eki kullan seklinde #ifdef ile tanimlamalar yapiliyor. Bu gune kadar hic bir zaman, tasinabilir kod yazimi amaci gutmedigimden verdigim koda da bu tur tanimlamalar eklemedim fakat istersen ugrasirim zor bir sey değil cunku.
Yeni tartismalar baslatmamasi icin hemen belirtmeliyim ki verdigim kodlari, hizli kossun diye değil sirf kisa olmasini istedigin icin bu sekilde yazdim.
Bunalmış,
Senin iyiliğin için söylüyorum bunları: Herşeyin bir bedeli vardır. Eğer birşeyler kazanmak istiyorsan bişeyler kaybetmelisin. İşlemci zamanını kaybetmiyeceğim diye 2 cycle hesabı yaparsan kendi zamanını, ömrünü yersin. İleri de çok pişman olursun.
Asm - C tartışmasına gelince, aradan onca zaman geçmiş ve hala aynı şeyi söylüyormuşsun gibi davranıyorsun ama kendin değişmişsin kendinin haberi yok. C'ci olmuş çıkmışsın işte, herşey ortada.
Asm, C'den hız bakımında çok daha iyidir bu tartışmasız bunu herzaman söyledim ve ben eski bir asm programcısıyım. Fakat asm çalışırken hızlıyken, yazılması çok uzun zamanlar alan, karmaşık işleri yapmak çok zor olan bir programlama dilidir.
C ise, asm'ye çok yakın kod yazılabilecek tek programlama dilidir ve asm'ye göre büyük avantajları vardır. Şimdi sana bunları anlatmayayım zaten biliyorsundur. Benim haklı olduğumu da biliyorsun da mesele "tamam, haklısın diyememek".
Hala asm konusunda ısrarlıysan bana bir arm cortex m3 asm ile ethernet üzerinden stm32'ye program atılabilecek bir code yaz bakalım, kaç ayda yazacaksın.
Alıntı yapılan: fahri- - 05 Kasım 2011, 19:23:26
Gelecek kartlara 2x16 LCD bağladığımızda 3.3V ile 5V beslenen LCD yi sürebilirmiyiz. Yoksa data girişlerine pull up direnç mi takılması gerekli. Veya başka bir yol?
Genelde LCD TTL uyumlusu ise sürülür ve %90 öyle oluyor. STM32 serisinde portlar Pull-up ve pull-down yapılabiliyor içinde dahili 100k dirençleri var.
2x16 lcd sürmek için gereken bir dosyayı keile taşımayı düşünüyorum.Aklıma takılan soru şu Portd nin bir kısmını lcd için bir kaç pinini ise interrupt rutininde okuyacağım sensor için kullanıcam, acaba program yazarken bu gibi durumlarda kodu nasıl yazıyorsunuz önerebileceğiniz bir yol varmı?Lcd driverinin içinde her port ile işlem yapacağı zaman tüm kesmeleri pasif-aktif mi yapmalıyım ki çok hantal ve dandik bir yöntem olarak algılıyorum? Bit banding yöntemi atomiktir diye yazıyor bazı pinler(enable,rw,rs) için bu güzel gibi ancak data pinleri için kullanışsız gibi duruyor....
Problem şu ben lcd ile haberleşirken kesme gelmesi durumunda kesmeden döndükden sonra lcd haberleşmesinin çakılması ihtimali, yada yanlış data yazma ihtimali...
Alıntı yapılan: mcan - 05 Kasım 2011, 22:59:20
2x16 lcd sürmek için gereken bir dosyayı keile taşımayı düşünüyorum.Aklıma takılan soru şu Portd nin bir kısmını lcd için bir kaç pinini ise interrupt rutininde okuyacağım sensor için kullanıcam, acaba program yazarken bu gibi durumlarda kodu nasıl yazıyorsunuz önerebileceğiniz bir yol varmı?Lcd driverinin içinde her port ile işlem yapacağı zaman tüm kesmeleri pasif-aktif mi yapmalıyım ki çok hantal ve dandik bir yöntem olarak algılıyorum? Bit banding yöntemi atomiktir diye yazıyor bazı pinler(enable,rw,rs) için bu güzel gibi ancak data pinleri için kullanışsız gibi duruyor....
Problem şu ben lcd ile haberleşirken kesme gelmesi durumunda kesmeden döndükden sonra lcd haberleşmesinin çakılması ihtimali, yada yanlış data yazma ihtimali...
Merhaba,
Bunalmış'a anlatıyoruzda anlamıyor. Allah'tan anlayanlar çıkıyor. Aslında benim kullandığım mantık biraz faklı ama aşağıdaki ile rahatça kullanabilirsin.
union GpiodOdrRegUni{
vu32 Reg32;
struct{
vu32 lcdrw:1;
vu32 lcdrs:1;
vu32 lcddata:4;
.
.
vu32 Key:1;
}Bits;
};
union GpiodOdrRegUni *GPIOODRREG = (union GpiodOdrRegUni *)GPIOC_ODR_ADR;
union GpiodOdrRegUni *GPIOIDRREG = (union GpiodOdrRegUni *)GPIOC_IDR_ADR;
main içinde
// output için
GPIOODRREG->Bits.lcddata=0x2;
GPIOODRREG->Bits.lcdrs=1;
GPIOODRREG->Reg32=(u32)0x1234;
input için
if(GPIOIDRREG->Bits.Key == 0)
{
}
Lcd ve int. bişey olmaz, interrupt kapatırsan asıl bişeyler olabilir. Eğer hantal görüyorsan lcd haberleşmesini 3 wire ile spi üzerinden sürebilirsin(burada amaç datayı spı hattına attıktan sonra işlemci boş kalır ve port avantajın tabii ki).
LPCXpresso LPC1114 kiti 3.3V çıkışlarla ile direk 2x16 LCD sürüldü. Bu kitle de sürülür sanıyorum.
Alıntı yapılan: mcan - 05 Kasım 2011, 22:59:20
2x16 lcd sürmek için gereken bir dosyayı keile taşımayı düşünüyorum.Aklıma takılan soru şu Portd nin bir kısmını lcd için bir kaç pinini ise interrupt rutininde okuyacağım sensor için kullanıcam, acaba program yazarken bu gibi durumlarda kodu nasıl yazıyorsunuz önerebileceğiniz bir yol varmı?Lcd driverinin içinde her port ile işlem yapacağı zaman tüm kesmeleri pasif-aktif mi yapmalıyım ki çok hantal ve dandik bir yöntem olarak algılıyorum? Bit banding yöntemi atomiktir diye yazıyor bazı pinler(enable,rw,rs) için bu güzel gibi ancak data pinleri için kullanışsız gibi duruyor....
Problem şu ben lcd ile haberleşirken kesme gelmesi durumunda kesmeden döndükden sonra lcd haberleşmesinin çakılması ihtimali, yada yanlış data yazma ihtimali...
@mcan
Bitbanding uzerine onca konusmadan sonra, birden fazla bite ayni zamanda mudahale gerektiren (data pinleri gibi) uygulamalarda bitbandingine basvurmayi nasil aklindan gecirebilirsin anlamiyorum. Bit 1/8 byte anlamina geliyor değilmi. Data bus manuplasyonu icin coklu bit manuplasyonu yada byte banding istiyorsun.
Alıntı yapılan: eemkutay - 06 Kasım 2011, 08:50:17
Merhaba,
Bunalmış'a anlatıyoruzda anlamıyor. Allah'tan anlayanlar çıkıyor. Aslında benim kullandığım mantık biraz faklı ama aşağıdaki ile rahatça kullanabilirsin...
@eemkutay
Gene olayi bir yerlere cekmeye basladin. Bitbanding metodunu ne zaman, nerede ayni anda birden fazla bit degisimi icin ovdum? Sen de bit banding ile coklu bit manulasyonunu anlamamissin?
Istersen STM firmasina hata yaptiklarini, bitbanding donanimini cipe eklemeleleri gerektigini ve nedenlerini izah et, adamlar bosu bosuna yongada yer kaplayan bu modulu
koymasinlar. En azindan guc tuketimine ve cip maliyetine faydasi olsun.
Alıntı Yap
Lcd ve int. bişey olmaz, interrupt kapatırsan asıl bişeyler olabilir......
Bunu nasil izah edeceksin?
Alıntı yapılan: bunalmis - 06 Kasım 2011, 14:47:41
@mcan
Bitbanding uzerine onca konusmadan sonra, birden fazla bite ayni zamanda mudahale gerektiren (data pinleri gibi) uygulamalarda bitbandingine basvurmayi nasil aklindan gecirebilirsin anlamiyorum. Bit 1/8 byte anlamina geliyor değilmi. Data bus manuplasyonu icin coklu bit manuplasyonu yada
Aman yanlış anlaşılmasın bitbandinge başvurmak istemiyorum ,fakat bu konuda(birden çok bite aynı anda erişim) bitbanding ne kadar alakasızsa lcd driver dosyasının port pinlerini kulllanan her kesimine de interruptları açıp kapamak aynı şekilde alakasız görünüyor...Ancak şu var eğer ki gelen kesmeye vermem gereken cevap pinleri manuple etme hızımdan daha önemli ise hiç interrup aç kapa yapmadan bit bit her bitiçin bitband kullanılmaz mı? Giriş çıkıp portları için atomik başka komutlar var ancak söz konusu sram alanı ise başka komut göremedim.
Mesela
Alıntı Yapchar lcd_read_byte() {
char low,high;
set_tris_lcd(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}
Bu pic c kodunu arm işlemci için keilde tekrar yazıcam fakat aynı porttan interrup rutininde birde sensor haberleşmem var ,şimdi birbirlerini etkilemesinler diye lcd fonksiyonlarının içine sürekli interrupt açıp-kapamam çok hantal gibi görünüyor?Mesela örnekdeki kodda 6 yere aç kapa işlemi yazmam lazım yada sadece başa ya da sona yazsam bu seferde kesme uzun bir süre kapalı kalacak.
@Eemkutay structure yöntemi güzel fakat ,sonuçda maskeleme kullanmı yor mu? Eğer kullanıyorsa maskele atomik erişim olmayacağı için maskeleme esnasında gelen interrupt içerisinde aynı portta -adresde bit maskeleme yapıp interruptan geri döndüğümüzde main içindeki maskeleme sonucu yanlış olmayacak mıdır?Böylece interrupt içinde haberleştiğim sensör ile haberleşmemde aksamalar olabilir. Haberleşip interruptan çıkmadan işimi bitirirsem tamam sorun yok ancak diğer türlü problem var.
Donanımsal yada yazılımsal Debugger ile adım adım işlem yaparken interrup tetikleyebilirmiyiz? Eğer böyle bişey varsa yukarıda anlattığım durumu ispatlayabilir beraber inceleyebiliriz.
@mcan,
Profesyonel anlamda 20-30 ticari projelerim var ve otomotiv, endüstriyel, biomedikal vs. alanlarda ve sorunsuz çalışan projeler. Sense bana dandik lcd sorusu soruyorsun ve öyle değildir vs. diyorsun. Bildiğin gibi yap.
@bunalmış
Cortex m3 interrupt işte. Özelliklerini biliyorsan izaha gerek yok. Sen farklı kullanıyorsan öyle kullan.
Alıntı yapılan: eemkutay - 06 Kasım 2011, 22:42:21
@mcan,
Profesyonel anlamda 20-30 ticari projelerim var ve otomotiv, endüstriyel, biomedikal vs. alanlarda ve sorunsuz çalışan projeler. Sense bana dandik lcd sorusu soruyorsun ve öyle değildir vs. diyorsun. Bildiğin gibi yap.
@bunalmış
Cortex m3 interrupt işte. Özelliklerini biliyorsan izaha gerek yok. Sen farklı kullanıyorsan öyle kullan.
Forum da, nedenlerini aciklayamayacagin, soylediklerinin arkasinda duramayacagim boyundan buyuk sozler etmezsen sevinirim.
Bunalmis hocam Interrupt gelince işlemci içeriklerini saklıyor diyor aşağıdaki linkte ama M3-M4 için geçerli mi bilmiyorum
interrupttan dönünce yüklenmesi gereken değerler korunuyor olması lazım bu durumda,
o zaman enable disable yapmaya gerek kalmaması lazım, yanlış mı anladım yoksa?
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0211a/index.html
eğer otomatik olmuyorsa da her interrupt için hafızada bir yer ayırsak girerken değerleri burada saklasak çıkarken geri yüklesek
enable disable derdinden kurtulmuş oluruz diye düşünüyorum
bir de exceptionlar için bir app note buldum ileride lazım olacak kalsın =)
http://www.keil.com/appnotes/files/apnt209.pdf
@Ersinerce,
Sorun context saving islemi değil.
Interrupt rutini ile ana program ayni donanimin registerine erisiyorsa, ana program da bu donanimin registeri uzerinde yazilimsal olarak bit manuplasyonu yapiyorsa
bu durumda ana program, donanim registerine erismeden once interruptlari yasaklamali, isi bitince de interruptlara izin vermelidir.
Aksi takdirde hata olusabilir.
Ornegin ana program portun 0. bitine 1 yazmak istedi. Portu okudugunda portun 0 oldugunu ogrendi. (Prta dogrudan 1 yazamaz yazarsa tum ust bitler silinir)
Bu esnada da int geldi. porttan okudugu deger registerde ve donanim bunu sakladi.
Int rutinine gecildi.
Int rutini de portun 1. bitini 1 yapmak istesin.
Portu okudugunda 0 gorur. 1. bitini set eder 2 eder ve bunu porta yazar.
Interrupt rutininden ciktik ana programa donduk.
Ana program porttan okudugu degeri biliyor neydi 0.
Bunun 0. bitini 1 yapti ve porta yazdi. Su anda portta 1 yazili.
Halbuki portta 3 olmaliydi.
Eger int yasaklamasi yapilsaydi, ana program porta 1 yazacakti, interrupta izin verildiginde int gelecek ve 1. biti set edecekti
bu da portun 3 degerini almasi anlamina gelecekti.
Anladım hocam, o zaman kesme ile kullanılacak ortak yerlerde, bit işlemleri için Bitband yapısını kullanmak daha mantıklı
@ErsinErce,
Nasil dersen oyle yap. Ister bitbanding ile isini gor hic interruptlari engelleyecegim diye ugrasma,
ister interrupt dis/enb yaparak bitleri yazilimsal maskeleyerek kaydirarak oku yada degistir.
Bitbanding, hedef biti atomik olarak okuyabilmeyi, set yada reset edebilmeyi saglayan donanimsal bir ozellik.
Interruptlar dahi bu islemi bozamiyor cunku bu ise yarayan komut kesilemez tipte bir komut.
Bu komutun okuma islemi icin opcode'u LDR, yazma islemi icin opcode'u da STR ve her ikisi de tek cycle da isliyor.
Bu komutlarla okunan deger 0 yada 1 olabiliyor. Yazilirken de 0 yada 1 yazilabiliyor.
Kullanim amaci tek bir bite ulasmak.
Icimiz disimiz bitbanding oldu bence bu konuyu kapatalim artik.
Konuyu açmak için söylememiştim, pekiştirme amaçlıydı :-\
Bundan sonraki konumuz ne olacak hocam?
Alıntı YapIcimiz disimiz bitbanding oldu bence bu konuyu kapatalim artik.
evet hocam sonuna kadar katılıyorum
birde kitler nezaman gelir acaba bilgisi olan varmı
ayrı bir başlık açıyorum , "bit banding şamataları"...
M4 MCU x86 modunda direkt olarak LCD desteklemektedir. Sadece datasheet te belirtilen pinleri kullanmalıyız. 5V toleranslı portlar mevcuttur.
Alıntı yapılan: eemkutay - 06 Kasım 2011, 22:42:21
@mcan,
Profesyonel anlamda 20-30 ticari projelerim var ve otomotiv, endüstriyel, biomedikal vs. alanlarda ve sorunsuz çalışan projeler. Sense bana dandik lcd sorusu soruyorsun ve öyle değildir vs. diyorsun. Bildiğin gibi yap.
Ben aklıma takılanı okuduğum şeylerden yola çıkarak soruyorum,öyledir yada değildir demedim zaten okuduğumu doğru anladım mı anlamadım mı kontrol etmek için debugger ile gözlemlemek istedim, bu konuda yardımcı olabilirsen sevinirim.
Keilde simulator ile GPIOC üerinde bit mask ile işlem yaptığımda "General Purpose ı/o c (GPIOC )" ekranında programda biti set etmeme rağmen simulasyonda etmiyor,ancak gerçekde ediyor.
Bağlantıdaki j-tag adaptörünü alsam cortex-m4 içinde kullanabilirmiyim ,listede belirtmemişler.
http://www.ebay.com/itm/ULINK2-USB-JTAG-Emulator-ARM9-Cortex-Keil-Ulink-II-Debug-Adapter-ULINK-2-/220888291905?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item336df7da41#ht_4954wt_1039 (http://www.ebay.com/itm/ULINK2-USB-JTAG-Emulator-ARM9-Cortex-Keil-Ulink-II-Debug-Adapter-ULINK-2-/220888291905?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item336df7da41#ht_4954wt_1039)
Alıntı yapılan: mcan - 07 Kasım 2011, 19:18:21
Bağlantıdaki j-tag adaptörünü alsam cortex-m4 içinde kullanabilirmiyim ,listede belirtmemişler.
http://www.ebay.com/itm/ULINK2-USB-JTAG-Emulator-ARM9-Cortex-Keil-Ulink-II-Debug-Adapter-ULINK-2-/220888291905?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item336df7da41#ht_4954wt_1039 (http://www.ebay.com/itm/ULINK2-USB-JTAG-Emulator-ARM9-Cortex-Keil-Ulink-II-Debug-Adapter-ULINK-2-/220888291905?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item336df7da41#ht_4954wt_1039)
ULINK2 Debug Adapter Cortex M çekirdeklerini desteklemekte.
detaylar aşağıdaki klinkte mevcut. Bende de klon birtane var aldığım kartlardan birinin üzerindeki S-Link bağlantılarını ayırıp ULINK ile kullanacağım.
http://www.keil.com/ulink2/chips.asp
Alıntı YapULINK2 Debug Adapter Cortex M çekirdeklerini desteklemekte.
detaylar aşağıdaki klinkte mevcut. Bende de klon birtane var aldığım kartlardan birinin üzerindeki S-Link bağlantılarını ayırıp ULINK ile kullanacağım.
ulink in st link e gore avantajı kart uzerinde debug yapabilmekmi?
tam olarak farkı nedir acaba
cünkü ben stm32f100 kitimde debug yapabiliyorum avantajı nedir kafam karıştı,
birde bu ulink üzerinde 10 15 kablo baglantısı var bunlar neden bukadar fazla
STM32F kartimizda JTAG pinleri yok. Sadece SWD yapabiliriz buna ait donanim da zaten kart uzerinde mevcut.
JTAG ile de SWD ile de donanimsal olarak debug islemleri yapiyorsun. Ilk baslarda sadece JTAG vardi. Sonradan SWD eklendi diye biliyorum.
JTAG JTAG kurulusunun denetiminde SWD ise ARM firmasinin.
SWD nin tel sayisi acisindan avantaji var bunun disinda birinin digerine gore ne ustunlugu var bilmiyorum.
SWD JTAG'a kiyasla yavas olabilir.
Alıntı yapılan: bunalmis - 07 Kasım 2011, 00:48:51
@Ersinerce,
Sorun context saving islemi değil.
Interrupt rutini ile ana program ayni donanimin registerine erisiyorsa, ana program da bu donanimin registeri uzerinde yazilimsal olarak bit manuplasyonu yapiyorsa
bu durumda ana program, donanim registerine erismeden once interruptlari yasaklamali, isi bitince de interruptlara izin vermelidir.
Aksi takdirde hata olusabilir.
Ornegin ana program portun 0. bitine 1 yazmak istedi. Portu okudugunda portun 0 oldugunu ogrendi. (Prta dogrudan 1 yazamaz yazarsa tum ust bitler silinir)
Bu esnada da int geldi. porttan okudugu deger registerde ve donanim bunu sakladi.
Int rutinine gecildi.
Int rutini de portun 1. bitini 1 yapmak istesin.
Portu okudugunda 0 gorur. 1. bitini set eder 2 eder ve bunu porta yazar.
Interrupt rutininden ciktik ana programa donduk.
Ana program porttan okudugu degeri biliyor neydi 0.
Bunun 0. bitini 1 yapti ve porta yazdi. Su anda portta 1 yazili.
Halbuki portta 3 olmaliydi.
Eger int yasaklamasi yapilsaydi, ana program porta 1 yazacakti, interrupta izin verildiginde int gelecek ve 1. biti set edecekti
bu da portun 3 degerini almasi anlamina gelecekti.
Bunalmış, yokluğumda iyice sallamışsın, birincisi volatile kelimesini öğren ikincisi IDR ve ODR registerleri ne iş yapar onları öğren. Sanki tek register varmış gibi anlatmışsın ve portun type'ı volatile değilmiş gibi anlatmışsın.
Maskelersen de bişey olmaz, çünkü pratik olarak milyonlarca denenmiştir. Ben tüm register yapılarını daha öncede bahsettiğim gibi pointer structer yaptım ve istediğim bite erişebiliyorum. İstediğimi set edip reset yapıyorum. Her kartta bir tane stm32 içeren 10 ayrı kartla can bus ağı kurdum ve rastgele can interruptları geliyor ve çok sık şekilde, hiç bir sorun olmuyor olmazda. Çünkü portlar volatiledır ve maskeleme yapsanda bu işlemler Rx registerlerinde saklanır bunlar int. içine girdiğinde saklanır. Bu esnada porttan okusanda veya int içinde okuyup yazsanda eğer bit bazında test ediyorsan hiç bir sorun olmaz.
Yazdığım sorunu hiç anlamamış sırf cevap vermiş olmak için üfürmüşsün.
Hernekadar alıntı yaptığın yazımda port ifadesi kullanmış olsam da sözkonusu sorun sadece I/O portlar için değil registerlerin sülalesi için geçerli. Bu nedenle ODR ve IDR yi senden öğrenecek değilim. Volatile ile sorun arasında alaka kurman da çok ilginç.
Alıntı yapılan: bunalmis - 08 Kasım 2011, 17:09:50
Yazdığım sorunu hiç anlamamış sırf cevap vermiş olmak için üfürmüşsün.
Hernekadar alıntı yaptığın yazımda port ifadesi kullanmış olsam da sözkonusu sorun sadece I/O portlar için değil registerlerin sülalesi için geçerli. Bu nedenle ODR ve IDR yi senden öğrenecek değilim. Volatile ile sorun arasında alaka kurman da çok ilginç.
Ne dediğimi anlamamışsın ki ne alaka diyorsun, seninle uğraşarak zamanımı çarçur ediyorum. Sen şamatalarına devam et.
Arkadaşlar denemek isteyenler için
Alıntı Yap#include "STM32F10x.h"
#define BIT_LEVEL_SRAM(a,b) ((SRAM_BB_BASE + (a-SRAM_BASE)*32 + (b*4)))
#define BIT_LEVEL_PERI(a,b) ((PERIPH_BB_BASE + (a-PERIPH_BASE)*32 + (b*4)))
#define RCC_APB2ENR (RCC_BASE+0x018)
#define GPIO_C_ENABLE *((volatile unsigned int *)(BIT_LEVEL_PERI(RCC_APB2ENR,4)))
void delay(unsigned int);
//static int ih;
int zg,ipb,ii,i;
typedef struct CFM_{
char Mode0 : 2;
char Conf0 : 2;
} Pin_Setup;
Pin_Setup PortC_setup __attribute__((at(GPIOC_BASE+0x0C)));
typedef struct {
int Pin0 : 1;
int Pin1 : 1;
int Pin2 : 1;
int Pin3 : 1;
int Pin4 : 1;
int Pin5 : 1;
int Pin6 : 1;
int Pin7 : 1;
int Pin8 : 1;
int Pin9 : 1;
} BitBanding __attribute__((bitband));
BitBanding PortC __attribute__((at(GPIOC_BASE+0x0C)));
typedef struct {
int Pin0 : 1;
int Pin1 : 1;
int Pin2 : 1;
int Pin3 : 1;
int Pin4 : 1;
int Pin5 : 1;
int Pin6 : 1;
int Pin7 : 1;
int Pin8 : 1;
int Pin9 : 1;
} BitMask;
BitMask portc __attribute__((at(GPIOC_BASE+0x0C)));
void EXTI0_IRQHandler(void)
{
GPIOC->ODR |= 0x100; //pin8 set edildi
while(EXTI->PR)
{
EXTI->PR = 0x0;
}
}
void TIM7_IRQHandler(void)
{
PortC.Pin5 = !PortC.Pin5;
GPIOC->ODR |= 0x200;
while(TIM7->SR)
{
TIM7->SR = 0x0;
}
}
void SystemInit (void)
{
delay(0x880000);
GPIO_C_ENABLE = 1 ;
//RCC->APB2ENR |= 0x00000016; // GPIOD donanımının clock sinyalini uygulayalım
GPIOC->CRL = 0x37333334; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOC->CRH = 0x33333333;
RCC->CR |= 0x0010000; // HSE ON
RCC->CFGR = 0x001D0000; // PLL ayarla
RCC->CR |= 0x001000000; // PLL aç
FLASH->ACR = 0x32; // Flash gecikme ayarı
RCC->CFGR = 0x001D0702; // SİNYAL KAYNAĞI PLL APB1 HCLK/16
EXTI->IMR = 1;
EXTI->EMR = 1;
EXTI->FTSR = 1;
NVIC->ISER[0] = 0x40;
RCC->APB1ENR |= 0x00000020; //Timer7 ye clock verelim
TIM7->DIER = 0x1;
TIM7->PSC = 0x1FF; //182=B6 182*5= H393
TIM7->ARR = 0xFFFF;
TIM7->CR1 = 0x85;
NVIC->ISER[1] = 0x00800000; // NVIC de Timer 7 interrupta izin verelim
}
void delay(unsigned int i)
{ unsigned int z;
for(z=0;z<i;z++);
}
int main()
{
while(1)
{
GPIOC->ODR |= 0x200; // pin9 set ediliyor.
PortC.Pin5 = 1;
delay(0x40000);
GPIOC->ODR = 0x00; // Ledler sonsun
delay(0x40000);
}
}
Bu kodu alın (cortex m3 için)keil de derleyin,simulator ve debugger'ı açın resimde gösterdiğim adıma ok gelince yine resimdeki iki kutucuğu işaretleyip interrupt oluşmasını sağlayın,
[IMG]http://img217.imageshack.us/img217/3350/debugv.jpg[/img] (http://imageshack.us/photo/my-images/217/debugv.jpg/)
Uploaded with ImageShack.us (http://imageshack.us)
İnterruptu bitirip ana programa geri dönün.... Şimdi sadece pin 9 set edilmiş olucak oysa ki interrup içinde pin 8 i set etmiştik.
Anlatılmaya çalışılan bu, interrupt içinde set edilen pinler ana programa dönünce planlanan gibi kalmıyorlar.
@Eemkutay burada bir uygulama hatası varmı? Simulator ü yeni kullanmaya başladım, donanımsal debugger yok o sebeple gerçek kart üzerinde deneyemedim.
merhaba arkadaşlar sıkıcı tartışmalar ve bayram dolayısıyla ara verdigim calısmalara sogutmadan tekrardan başladım
hedefim suana kadar yazılmış tüm programların kıl tüy yününü debug penceresinden görebilmek!
buraya kadar güzel fakat takıldıgım yerler var yardımcı olursanız cok sevinirim..
çalıştığım kod bu!
Timer 7 ve interrupt kullanarak yanıp sönen led programı
// Programın başı
#include "STM32F4xx.h"
void SystemInit()
{
// Yukarıdaki örnek programdaki kodların aynısı
}
void TIM7_IRQHandler()
{
volatile short i;
static char LedFlag=0;
TIM7->SR=0; // Timer Int Flagý silelim
LedFlag=(LedFlag+1)&1;
if (LedFlag) GPIOD->ODR= 0x0000F000; // Ledler yansin
else GPIOD->ODR= 0x00000000; // Ledler sonsun
}
int main()
{
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =42000; // Prescaler deðerimiz 42000, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 84E6 / (42000) = 2000 Hz
TIM7->ARR =1000; // Counter, Decimal 1000 olunca basa donsun 0.5 sn demek
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
while(1)
{
}
}
// Programin sonu
sormak istedigim ise ben bütün registerleri kontrol etmek istedim gerçekten içlerine istedigimiz deger yazılıyormu diye sağ tıklayıp add to watch1 dedim hepsine
sonra programı adım adım işledim o satırlara kadar
fakat hiçbir register değer almadı hepsinde <cannot evaluate> diyor :S
mesela ben burda ledin yanıp sondugu anları hangi değeri "add to watch 1" diyerek izleyebilirim bunu anlayamadım
GPIOD->ODR= 0x0000F000; satırında-- "GPIOD" "ODR" diye watch ettim ama degerler gelmedi :(
yardımcı olursanız cok mutlu olurum
saygılar.
kitler ne zaman geliyor heyecanla bekliyorum :)
Alıntı yapılan: eemkutay - 08 Kasım 2011, 17:40:39
Ne dediğimi anlamamışsın ki ne alaka diyorsun, seninle uğraşarak zamanımı çarçur ediyorum. Sen şamatalarına devam et.
@eemkutay
lütfen burada bir şeyler öğrenmeye çalışıyoruz. eğer illa ben daha iyi biliyorum diyorsanız siz de ayrı bir hattan devam edin.
bunalmış hocamı yaptığı işten soğutmayın.
bizim zamanımız da en az sizinki kadar değerli. teşekkürler
(http://img80.imageshack.us/img80/377/whyec.jpg)
burada gostereyim abiler :D
osuruktan b=0 b=1 b=2 yazdım denemek için bu satırları atlıyor ama goründüğü gibi b değeri oylece kalıyor
ama aynı şeyi yukardıdaki "i" için yaptıgımda saydıgını gordüm!!
i de olan şey burdaki "b" de neden olmadı?
yada diğer registerlarda
Degiskeni global, statik yada volatile yapmayi deneyin.
int b;
b=1;
b=2;
b=3;
Gibi satirlar derleyici tarafindan kadirilip atilir ya b=3 birakilir ya da eger b hic bir yerde kullanilmiyorsa b yokmus gibi derlenir. Bu nedenle b yi gozleyemiyorsunuz.
gambit1244; sizin kit geldi mi?
kitlerden eline ulaşan var mı?
https://www.picproje.org/index.php/topic,36190.0.html
DENEME_M3.axf: Error: L6982E: AT section clean-main.o(.ARM.__AT_0x40011000) with base 0x40011000 limit 0x4001101c overlaps address range with AT section clean-main.o(.ARM.__AT_0x4001100C) with base 0x4001100c limit 0x40011010.
Bu uyariyi nasil gideririm.
Uyariyi gideremedim . Bilmek istedigim adresi ayni olan 2 degiskeni nasil tanimlariz?
Örneğin GPIOC nin 0.numaralı pinini bir bit field içinde tanımlıyoruz. geri kalan pinlerini başka bir bit field içinde tanımlamak istiyoruz. Struct ların adresleri aynı olmalı ancak yukarıdakı hatayı veriyor....
ARM Development Studio 5 icin ,anaktar, lisanz , kurek, seriyel ... elinde olan var mi ?
Burada bir emek var, bir uğraşı var.
Nazik olun beyler, ana karnında öğrenmediniz sizde, öğrenenlere engel olmayın.
Konu sahibine saygı gösterin biraz, gösteremiyorsanız gidin bilmem kaç alandaki projelerinize odaklanın, işe yarayın, işi engellemeyin.
Son olarak hocam, anlatımlarınız çok güzel, kartlar bizlere ulaştığında umarım bir üst vitese alıp devam edersiniz. Takipçiniziz.
Gelecek kit bilgisayara takıldığında Keil'in içindeki ST link driverini benim gibi kabul ettiremeyen olursa
http://www.st.com/internet/evalboard/product/251168.jsp adresinde Design Support başlığı altındaki ST-LINK/V2 USB driver for Windows 7, Vista and XP
driverını indirerek çalışır hale getirebilirler.
Bende internal command error veriyor,çözemedim gitti.Bazen de No ST Link Detected uyarısı veriyor.
arkadaşlar benim bir sorum olacak ben bu çipi bir projede kullanmak istiyorum yazdığım programı çipe nasıl atacam picdeki gibi programlayıcı mı kullanmak gerekiyor
Alıntı yapılan: bilal0052 - 07 Aralık 2011, 19:59:08
arkadaşlar benim bir sorum olacak ben bu çipi bir projede kullanmak istiyorum yazdığım programı çipe nasıl atacam picdeki gibi programlayıcı mı kullanmak gerekiyor
devrende seri port ile kullanmak için ISP kuracaksın yada chipin JTAG/SWD uçlarını sokete çıkartıp J-LINK, S-LINK ve ya ULINK ile programlayacaksın.
board üzerindeki çıkışı kullanarak başka çiplerimi programlıyoruz yoksa o çıkışı kullanarak board üzerindeki çipimi programlıyoruz birde usb boot loader kullanarak program yükleyebilirmiyiz
Discovery kartında jumperlar var. Bunlara dokunmazsan Discovery kartında bulunan çipi programlıyoruz.
Bu jumperların konumunu değiştirirsen ve kartın bir kenarında boşta duran SWD pinlerine birer kablo lehimler bu kabloları da kendi tasarladığın devrendeki işlemcinin SWD pinlerine bağlarsan artık kendi işlemcini programlar hale gelirsin.
peki hocam usb boot loader ile çipe program yükleyebilirmiyiz
Bu konuda bilgim yok. Fakat Rehber dokumaninda soyle bir aciklama var.
Embedded bootloader
The embedded bootloader mode is used to reprogram the Flash memory using one of the
following serial interfaces:
● USART1(PA9/PA10)
● USART3(PB10/11 and PC10/11)
● CAN2(PB5/13)
● USB OTG FS(PA11/12) in Device mode (DFU: device firmware upgrade).
The USART peripherals operate at the internal 16 MHz oscillator (HSI) frequency, while the
CAN and USB OTG FS require an external clock (HSE) multiple of 1 MHz (ranging from 4 to
26 MHz).
The embedded bootloader code is located in system memory. It is programmed by ST
during production. For additional information, refer to application note AN2606.
AN2606 asagida. Okumak lazim. PC tarafinda nasil bir yazilim gerekiyor vs bakmak lazim.
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00167594.pdf
AN3156 da asagida.
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00264379.pdf
tmm hocam boş zamanımda bu konu ile ilgileneceğim eğer işe yarar bişe bulabilirsem burda paylaşırım
STM32F407 kitde 2 gundur DMa ile memory den peripherala veri aktarimi yapmak icin ugrasiyorum. Fakat DMA garip davraniyor ve transfer edilmesi gereken veriden cok fazla sayida transfer yapiyor. (!!! 20 tane veri yerine 60 kusur bin tane !!!)
Deneme amaciyla SPI ve USART calismasi yaptim ancak her ikisinde de ayni sorun olustu. Sorun, Peripheral flow controller olarak peripheral secildiginde ortaya cikiyor. Tersi durumda (DMA flow kontrolu ustlenirse) hata yok ancak bu da isime yaramiyor.
Bu konuda calisma yapan oldumu. Diger STM ciplere register bazinda program yazip isleten varmi?
Alıntı yapılan: bunalmis - 11 Aralık 2011, 16:25:07
STM32F407 kitde 2 gundur DMa ile memory den peripherala veri aktarimi yapmak icin ugrasiyorum. Fakat DMA garip davraniyor ve transfer edilmesi gereken veriden cok fazla sayida transfer yapiyor. (!!! 20 tane veri yerine 60 kusur bin tane !!!)
Deneme amaciyla SPI ve USART calismasi yaptim ancak her ikisinde de ayni sorun olustu. Sorun, Peripheral flow controller olarak peripheral secildiginde ortaya cikiyor. Tersi durumda (DMA flow kontrolu ustlenirse) hata yok ancak bu da isime yaramiyor.
Bu konuda calisma yapan oldumu. Diger STM ciplere register bazinda program yazip isleten varmi?
Merhaba,
Aşağıya bir i2c için interruptlı dma rx, tx örneği ekledim inceleyip yaparsın. Bit bazında olduğu için kolay anlaşılır. DMA hazırlama kısmına bakarak yapabilirsin. DS1337 için kullandığım bir programdı.
void DMAChannel6_IRQHandler(void)
{
dma_ccr6.bits.EN=0;
dma_ifcr.bits.CTCIF6=1;
}
void DMAChannel7_IRQHandler(void)
{
dma_ccr7.bits.EN=0;
dma_ifcr.bits.CTCIF7=1;
i2c1_cr1.bits.STOP=1;
// event disable
i2c1_cr2.bits.ITEVTEN=0;
i2c_trans.bits.okundu=1;
}
void I2C1_ER_IRQHandler(void) // flagleri sil
{
i2c1_sr1.bits.OVR=0;
i2c1_sr1.bits.AF=0;
i2c1_sr1.bits.ARLO=0;
i2c1_sr1.bits.BERR=0;
}
void I2C_Config(void){
rcc_ahbenr.bits.DMAEN=1;
I2c_Init(); // i2c hazırla
I2C_RCV_DMA_INIT(); // rcv dma hazırla
I2C_TX_DMA_INIT(); // tx dma hazırla
RTC1337.ChipId=ds1337_id; // chip id yükle
RTC1337.DMAuse=idle; // boşta
RTC1337.State=idle; // boşta
}
/*8bit interface, memory'den peripheral'e */
void I2C_TX_DMA_INIT(void)
{
dma_cpar6.b32=(u32)I2C1_DR_ADR;
// gonderilen adres
dma_cmar6.b32=(u32)&RTC1337.WrBuffer[0];
dma_ccr6.bits.DIR=1; // Mem2Perip
// dma_cndtr6.b32=16; // 16 adet kayıt registeri
dma_ccr6.bits.MINC=1; // memory adresini arttır
dma_ccr6.bits.PL=3; // high piority
// dma/i2c event/error'lar enable ve priorityler 9
dma_ch6_int_set(pri_9);
i2c1_ev_int_set(pri_9);
i2c1_er_int_set(pri_9);
}
void I2C_RCV_DMA_INIT(void)
{
dma_cpar7.b32=(u32)I2C1_DR_ADR;
// alınacak adres
dma_cmar7.b32=(u32)&RTC1337.RdBuffer[0];
dma_ccr7.bits.DIR=0; // Per2Mem
// dma_cndtr7.b32=16; // 16 adet kayıt registeri
dma_ccr7.bits.MINC=1; // memory adresini arttır
dma_ccr7.bits.PL=3; // high piority
dma_ch7_int_set(pri_9);
i2c1_ev_int_set(pri_9);
i2c1_er_int_set(pri_9);
}
void RTCBufWr(u8 adres, u8 *ptrbuf, u8 datasayisi)
{
u8 i;
// i2c1_cr1.bits.PE=0; // I2c disable
RTC1337.State=ds1337_wr; // yazma
RTC1337.DMAuse=DMA_tx; // dma tx
RTC1337.WrBuffer[adres]=adres; // adres=0 datasayisi=3 ise RTC1337.WrBuffer[0]=0
datasayisi+=adres; // datasayisi=3
for(i=adres;i<datasayisi;i++) // 0-1-2,RTC1337.WrBuffer[1-2-3], ptrbuf+0=timeregs[0]'ı gösteriri
RTC1337.WrBuffer[i+1]=*(ptrbuf+i); // ptrbuf, Timeregs'i gösterir
dma_cmar6.b32=(u32)&RTC1337.WrBuffer[adres]; // 0-1-2-3 gönderilir
dma_cndtr6.b32=datasayisi+1; // ilk gönderilecek adr'de eklendi
dma_ccr6.bits.TCIE=1; // complete int
i2c1_cr2.bits.DMAEN=1; // DMA enable
i2c1_cr2.bits.ITEVTEN=1; // int enable
i2c1_cr1.bits.START=1; // start bit
}
void RTCBufRd(u8 adres, u8 datasayisi)
{
u8 c;
if(datasayisi==1) datasayisi++;
RTC1337.Rdadres=adres;
RTC1337.State=ds1337_rd;
RTC1337.DMAuse=DMA_tx;
i2c_trans.bits.okundu=0;
// alınacak adres
dma_cmar7.b32=(u32)&RTC1337.RdBuffer[adres];
dma_cndtr7.b32=datasayisi;
dma_ccr7.bits.TCIE=1;
i2c1_cr2.bits.LAST=1; // DMA'da son data için nack
i2c1_cr2.bits.DMAEN=1; // DMA enable
i2c1_cr2.bits.ITEVTEN=1; // int enable
i2c1_cr1.bits.START=1; // start bit
while(!i2c_trans.bits.okundu);
datasayisi+=adres;
for(c=adres;c<datasayisi;c++)
TimeRegs.Dizi[c]=RTC1337.RdBuffer[c];
}
Selamlar,
Bu gün bütün günümü yiyen bir olayı paylaşmak istiyorum.
Amacım spi ile iletişim kuran bir lcd kütüphanesini kopyalayarak spi kısmını özelleştirmekti.
Kendi port tanımlamalarım,delay fonksiyonum ile birleştirip denedim ve çalışmadı ,uğraş uğraş ... sonunda debugger ile bakmaya başladığımda kodun 1.2.3.4.5.6.7.8... diye gitmesini beklerken 1.56.57.2.45.58.3.4..7.8... gibi dallanarak gittiğini fark ettim ,oysa ki programın gidişatında bu sekil dallanmalar yoktu. Programı azalta azalta azalta buna indirgedim;
PortB.Output.Pin10 = 1;
PortB.Output.Pin10 = 0;
PortB.Output.Pin10 = 1;
PortB.Output.Pin10 = 0;
PortB.Output.Pin10 = 1;
PortB.Output.Pin10 = 0;
GPIOB->ODR |= 0x20;
GPIOB->ODR &= 0xFFFFFFDF;
GPIOB->ODR |= 0x20;
GPIOB->ODR &= 0xFFFFFFDF;
GPIOB->ODR |= 0x20;
GPIOB->ODR &= 0xFFFFFFDF;
Sonra debug ettiğimde debug "ok" u sadece baştan ikinci "PortB.Output.Pin10 = 0;" komutu işleyip sonra "GPIOB->ODR |= 0x20;" atlıyor.Her işlediği koda *1 yazıyor.Ancak arada ki kodlara hiç birşey yazmıyor .Zaten GPIO debug penceresinde de hiç birşey gözükmüyor...Eğer aralara delay(1) gibi bir fonksiyon atarsam hepsine *1 verip hepsini adım adım işliyor.Neyse ki daha sonra proje ayarlarından optimizasyonun level 3 de oldugunu gördüm onu default a çektim ancak gene sıkıntı yaşadım.Optimizasyon sıfır ile problemsiz çalıştı...
Sorularım şunlar ;
1-programın belli kesimleri için farklı farklı optimizasyon levelleri ayarlayabilirmiyiz.
2-Yüksek optimizasyon seviyelerinde verdiğim örnekdeki kodun herbir adımının çalışması için ne yapmak lazım?
3-default seviyesi seviye kaçtır?
4-Keilin kendi hazır kodunda bunu kullanıyor pin erisimi icin
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, u16 GPIO_Pin, BitAction BitVal)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_BIT_ACTION(BitVal));
if (BitVal != Bit_RESET)
{
GPIOx->BSRR = GPIO_Pin;
}
else
{
GPIOx->BRR = GPIO_Pin;
}
}
Bu kodu ard arda calıstırsam da degısık optımızasyon seviyelerinde sıkıntı yaratmıyor, bunun sebebi fonksiyon tipinde olup için de birazcık kod olması mı? Yani diğer bir deyişle benim araya koyduğum delay(1) gibi yayarmı sağlıyor.
Not : Port pinlerine erişim için tanımladığım structure içeriği ve kendisine "volatile" değimi eklediğimde optimizasyon seviyesi 3 olsa bile programım ve debugger ekranı çok güzel çalışıyor.
2 gundur ot yoldugum program parcacigi asagida. Hatayi hala bulamadim ve ayni seylere tekrar tekrar bakmaktan usandim.
Cok basit bir hata oldugundan eminim fakat goremiyorum.
#include "STM32F4xx.h"
char RxBuf[128];
char TxBuf[128];
int cntr=0;
unsigned char WAdr,RAdr;
/*********************************************************************************
CPU frekansi 168Mhz
AHB frekansi 84 Mhz
APB frekansi 42 Mhz
*********************************************************************************/
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim 168 Mhz
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000001F; // GPIO A,B,C,D,E clock'u aktif edelim
GPIOD->MODER = 0x55550000; // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
/*********************************************************************************
USART3 modulunu kullanarak asenkron haberlesme (Hata kontrolu yapilmiyor)
*********************************************************************************/
void USART3_IRQHandler()
{
volatile int Sts;
Sts=USART3->SR;
RxBuf[WAdr]=USART3->DR;
WAdr=(WAdr+1)&0x7F;
cntr++;
}
void UsartInit()
{
WAdr=0;RAdr=0;
// USART3 MODULUNU AKTIF HALE GETIRELIM
RCC->APB1ENR|=0x00040000; // USART3 Clk Enable (Rehber Sayfa 113)
RCC->APB1RSTR|=0x00040000; // USART3 Resetlendi
GPIOB->AFR[1]=0x07777700; // PB10..PB14 pinleri USART3 ile alakalandirildi (Hard Sayfa 49)
GPIOB->MODER|=0x2AA00000; // GPIOB 10..14 icin alternatif fonksiyon tanimi (Rehber Sayfa 148)
// USART3 MODULUNU AYARLAYALIM // 1 Start, 8 Data, 1 Stop, No parity (Default degerler)
RCC->APB1RSTR&=~0x00040000; // USART3 Reseti kaldiralim
USART3->BRR=0X1112; // 9600 Baud
USART3->CR1|=0x0000202C; // USART3 enable
USART3->CR3|=0x80; // DMA Transfer Enable (Transmit)
NVIC->ISER[1]|=0x80; // NVIC da USART3 interrupta izin verelim
}
// Rx ve TX pinlerini (GPIOB10 ve GPIOB11) birbirine baglarsaniz gonderdiginiz datalar geri gelecektir
int main()
{
volatile int i;
UsartInit();
// Bu programin yaptigi isi aciklayayim
// USART a veri gelirse bu veri int rutininde aliniyor ve rama yaziliyor.
// Alinan verilerin sayisini sayac degiskeninde gorebilirsiniz.
// DMA ise, Ramdan 20 adet veriyi tek tek USARTa yollluyor.
// Bu da demektir ki 20 adet veri yollanacak ve rx tx birbirine telle bagli oldugu icin
// 20 adet veri alinacak ve sayac degiskenimiz 20 ye kadar sayacak.
// Fakat DMA 20 gonderimde durmuyor. (Durmadigi icin DMA islemini baslatip, delay yapip ardindan ben durduruyorum)
// DMA i durdurdugumda 80 kusur byte yollanmis oldugunu goruyorum. Durdurmasam 60 kusur bin byte yollayacak.
RCC->AHB1ENR |= 0x00200000; // DMA1 clock'u aktif edelim
while(DMA1_Stream4->CR&1); // DMA1 nin isi varsa bitmesini bekleyelim
DMA1_Stream4->M0AR=(int)&TxBuf[0]; // Nereden okuyacagiz
DMA1_Stream4->PAR=(int)&USART3->DR;// Nereye yazacagiz
DMA1_Stream4->FCR&=~0xFFFFFF40;
DMA1_Stream4->CR=(DMA1_Stream4->CR & 0xF0100000)| 0x0E000460; // CH7 vs
for(i=0;i<128;i++) TxBuf=i+1;
DMA1_Stream4->NDTR=(DMA1_Stream4->NDTR & 0xFFFF0000)|20; // 20 adet veri tasiyacagiz
USART3->SR&=~0x40;
DMA1_Stream4->CR|=1; // Transferi baslat
// Bundan sonraki kodlar hatayi bulmak icin yazdigim kodlar
// 20 byte transfer ardindan DMA'in durmasi lazim ancak durmuyor
// Asagidaki delay 82 byte transferine neden oluyor Bu da ilginc !!!
for(i=0;i<0x1FFFFF;i++);
// 20 byte transfer tamamlandiginda DMA islemi durdurmasi lazim fakat durmuyor
// Biz durduralim
DMA1_Stream4->CR&=~1; // Transferi Durdur
// Simdi rami gozleyin ne gitmis ne gelmis vs
while(1);
}
Ustteki mesaji edit etmeme ragmen sistem israrla degisiklik yaptirmiyor. Yeniden yollamak zorunda kaldim. 2 gundur ot yoldugum program parcacigi asagida. Hatayi hala bulamadim ve ayni seylere tekrar tekrar bakmaktan usandim.
Cok basit bir hata oldugundan eminim fakat goremiyorum.
#include "STM32F4xx.h"
char RxBuf[128];
char TxBuf[128];
int cntr=0;
unsigned char WAdr,RAdr;
/*********************************************************************************
CPU frekansi 168Mhz
AHB frekansi 84 Mhz
APB frekansi 42 Mhz
*********************************************************************************/
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim 168 Mhz
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000001F; // GPIO A,B,C,D,E clock'u aktif edelim
GPIOD->MODER = 0x55550000; // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
/*********************************************************************************
USART3 modulunu kullanarak asenkron haberlesme (Hata kontrolu yapilmiyor)
*********************************************************************************/
void USART3_IRQHandler()
{
volatile int Sts;
Sts=USART3->SR;
RxBuf[WAdr]=USART3->DR;
WAdr=(WAdr+1)&0x7F;
cntr++;
}
void UsartInit()
{
WAdr=0;RAdr=0;
// USART3 MODULUNU AKTIF HALE GETIRELIM
RCC->APB1ENR|=0x00040000; // USART3 Clk Enable (Rehber Sayfa 113)
RCC->APB1RSTR|=0x00040000; // USART3 Resetlendi
GPIOB->AFR[1]=0x07777700; // PB10..PB14 pinleri USART3 ile alakalandirildi (Hard Sayfa 49)
GPIOB->MODER|=0x2AA00000; // GPIOB 10..14 icin alternatif fonksiyon tanimi (Rehber Sayfa 148)
// USART3 MODULUNU AYARLAYALIM // 1 Start, 8 Data, 1 Stop, No parity (Default degerler)
RCC->APB1RSTR&=~0x00040000; // USART3 Reseti kaldiralim
USART3->BRR=0X1112; // 9600 Baud
USART3->CR1|=0x0000202C; // USART3 enable
USART3->CR3|=0x80; // DMA Transfer Enable (Transmit)
NVIC->ISER[1]|=0x80; // NVIC da USART3 interrupta izin verelim
}
// Rx ve TX pinlerini (GPIOB10 ve GPIOB11) birbirine baglarsaniz gonderdiginiz datalar geri gelecektir
int main()
{
volatile int i;
UsartInit();
// Bu programin yaptigi isi aciklayayim
// USART a veri gelirse bu veri int rutininde aliniyor ve rama yaziliyor.
// Alinan verilerin sayisini sayac degiskeninde gorebilirsiniz.
// DMA ise, Ramdan 20 adet veriyi tek tek USARTa yollluyor.
// Bu da demektir ki 20 adet veri yollanacak ve rx tx birbirine telle bagli oldugu icin
// 20 adet veri alinacak ve sayac degiskenimiz 20 ye kadar sayacak.
// Fakat DMA 20 gonderimde durmuyor. (Durmadigi icin DMA islemini baslatip, delay yapip ardindan ben durduruyorum)
// DMA i durdurdugumda 80 kusur byte yollanmis oldugunu goruyorum. Durdurmasam 60 kusur bin byte yollayacak.
RCC->AHB1ENR |= 0x00200000; // DMA1 clock'u aktif edelim
while(DMA1_Stream4->CR&1); // DMA1 nin isi varsa bitmesini bekleyelim
DMA1_Stream4->M0AR=(int)&TxBuf[0]; // Nereden okuyacagiz
DMA1_Stream4->PAR=(int)&USART3->DR;// Nereye yazacagiz
DMA1_Stream4->FCR&=~0xFFFFFF40;
DMA1_Stream4->CR=(DMA1_Stream4->CR & 0xF0100000)| 0x0E000460; // CH7 vs
for(i=0;i<128;i++) TxBuf [ i ] =i+1;
DMA1_Stream4->NDTR=(DMA1_Stream4->NDTR & 0xFFFF0000)|20; // 20 adet veri tasiyacagiz
USART3->SR&=~0x40;
DMA1_Stream4->CR|=1; // Transferi baslat
// Bundan sonraki kodlar hatayi bulmak icin yazdigim kodlar
// 20 byte transfer ardindan DMA'in durmasi lazim ancak durmuyor
// Asagidaki delay 82 byte transferine neden oluyor Bu da ilginc !!!
for(i=0;i<0x1FFFFF;i++);
// 20 byte transfer tamamlandiginda DMA islemi durdurmasi lazim fakat durmuyor
// Biz durduralim
DMA1_Stream4->CR&=~1; // Transferi Durdur
// Simdi rami gozleyin ne gitmis ne gelmis vs
while(1);
}
Rehber Sayfa 177 de sorunumun sebebi anlatilmis.
Ben STM32 Kartımı çok önceden almıştım. Fakat işten güçten anca dün adam biraz ilgilenebildim. Oturdum HD44780 chipli 2x16 Lcd için kod yazdım. Dün elimde Lcd olmadığı için deneyemedim. Aslında bu gün de deniyemiyecektim ama Tesadüfen elime bir tane geçti. Denedim Tüm Fonksiyonlar çalışmakta.
Main.c;
#include "STM32F4xx.h"
#include "Delay.c"
#include "HD44780.c"
void SystemInit(void)
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55005555; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
GPIOB->MODER = 0x00000500; // GPIOB 4 ve 5 i çıkış yaptık.
GPIOA->OSPEEDR= 0x00000000; // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
GPIOB->OSPEEDR= 0x00000000; // AYnı şey GPIOB içinde geçerli
GPIOC->OSPEEDR= 0xFFFFFFFF;
GPIOD->OSPEEDR= 0xFFFFFFFF;
}
int main(void)
{
void SystemInit();
while(1)
{
Lcd_init();
Lcd_Imlec_Yok();
Lcd_Yaz(" PicProje"); Lcd_Git(2,6);
Lcd_Yaz("Emg81");
Delay_ms(2000);
// Bit Banding
GPIO_D(15)=1;
Delay_ms(1000);
GPIO_D(15)=0;
Delay_ms(1000);
GPIO_D(14)=1;
Delay_ms(1000);
GPIO_D(14)=0;
Delay_ms(1000);
}
}
Delay.c;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Kullanılışı;
// Delay_ms(100); // 100 msn Bekle.
// Delay_us(100); // 100 usn Bekle.
// Not CPU OSC = 168 mhz - 210 MIPS
#include "Delay.h"
void Delay_ms(unsigned long Bekle)
{
Bekle = Bekle * 21008; // mSn ye ye çevirdik. OSC 168Mhz de uçuyor.
while(Bekle>0){Bekle--;}
}
void Delay_us(unsigned long Bekle)
{
Bekle = Bekle * 21; // uSn ye ye çevirdik. OSC 168Mhz de uçuyor.
while(Bekle>0){Bekle--;}
}
Delay.h;
extern void Delay_ms(unsigned long Bekle);
extern void Delay_us(unsigned long Bekle);
HD44780.c;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// LCD data Portu GPIOD
// RS. GPIOB.4
// E. GPIOB.5 olarak kullanılmıştır.
//
// Kullanılışı;
// Lcd_init(); // 2x16 LCD yi kullanıma hazır hale getirir.
// Lcd_Veri(); // Lcd ye KOmut göndermek için kullanılır.
// Lcd_Git(1,2); // Lcd nin 1. satırının 2. sütununa imleci konumlandırır.
// Lcd_Yaz("Merhaba"); // Lcd ye Merhaba Stringini gönderir.
// Yaz(); // Bu kullanılmayacak.
// Lcd_Sil(); // Lcd yi silmek için kullanılır.
// Lcd_Imlec_Var(); // İmleç YanSön Moduna sokar.
// Lcd_Imlec_Yok(); // İmleç i yok eder.
//
//
#include "hd44780.h"
void Lcd_init(void)
{
GPIOD->MODER = 0x55005555; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
GPIOB->MODER = 0x00000500; // GPIOB 4 ve 5 i çıkış yaptık.
GPIOA->OSPEEDR= 0x00000000; // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
GPIOB->OSPEEDR= 0x00000000; // AYnı şey GPIOB içinde geçerli
GPIO_B(4)=0; GPIO_B(5)=0; // Genel
GPIOD->ODR= 0x00000000; // Temizlik
Delay_ms(20);
Lcd_Veri(0x30); // Lcd Reset
Lcd_Sil();
Lcd_Veri(56); // 2 satır kullanacağımızı yazdık
Lcd_Veri(15); // Display i aç
Lcd_Veri(0x06); // Kursör 1 artan modda.
Lcd_Sil(); // Lcd yi temizle
}
void Lcd_Veri(unsigned char veri)
{
GPIO_B(4)=0; Delay_ms(10);
GPIOD->ODR = veri;
GPIO_B(5)=1; Delay_ms(10); GPIO_B(5)=0;
}
void Lcd_Git(unsigned char p1,unsigned char p2)
{
if (p1==1) Lcd_Veri(0x80+(p2-1));
else Lcd_Veri(0xC0+(p2-1));
}
void Lcd_Yaz(unsigned char *lcd_data)
{
Delay_ms(10);
while(*lcd_data) Yaz(*lcd_data++);
}
void Yaz(unsigned dat)
{
GPIO_B(4)=1; Delay_ms(10);
GPIOD->ODR = dat;
GPIO_B(5)=1; Delay_ms(10); GPIO_B(5)=0;
}
void Lcd_Sil(void)
{
Lcd_Veri(1);
Delay_ms(10);
}
void Lcd_Imlec_Yok(void)
{
Lcd_Veri(0x0C);
Delay_ms(10);
}
void Lcd_Imlec_Var(void)
{
Lcd_Veri(0x0F);
Delay_ms(10);
}
HD44780.h;
#define GPIO_A(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOA->ODR) << 5) + ((b) << 2)))
#define GPIO_B(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_C(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOC->ODR) << 5) + ((b) << 2)))
#define GPIO_D(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOD->ODR) << 5) + ((b) << 2)))
#define GPIO_E(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOE->ODR) << 5) + ((b) << 2)))
#define GPIO_F(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOF->ODR) << 5) + ((b) << 2)))
#define GPIO_G(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOG->ODR) << 5) + ((b) << 2)))
#define GPIO_I(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOI->ODR) << 5) + ((b) << 2)))
extern void Lcd_Veri(unsigned char veri);
extern void Lcd_Git(unsigned char p1,unsigned char p2);
extern void Yaz(unsigned dat);
extern void Lcd_Yaz(unsigned char *lcd_data);
extern void Lcd_Sil(void);
extern void Lcd_Imlec_Var(void);
extern void Lcd_Imlec_Yok(void);
Resim1;
[IMG]http://img849.imageshack.us/img849/5027/adsz1xu.jpg[/img] (http://imageshack.us/photo/my-images/849/adsz1xu.jpg/)
Resim2;
[IMG]http://img269.imageshack.us/img269/707/adsz2vq.jpg[/img] (http://imageshack.us/photo/my-images/269/adsz2vq.jpg/)
Kartlar yavaştan yavaştan alıcılarına ulaşmaya başladığına göre bundan sonraki çalışma şekli için bazı yönlendirmelerde bulunacağım.
https://www.picproje.org/index.php/topic,35896.0.html (https://www.picproje.org/index.php/topic,35896.0.html) linkinde yeterince örnek program parçacığımız birikti.
Bunları sıra ile ele almanızı istiyorum.
Bunun için rehber dokumanı açip, örnek programdaki satırları teker teker inceleyip neden bu satırda bu registere bu sayısal değer yüklenmiş sorusunun cevabını anlamanızı istiyorum.
Yaklaşık 15 adet programı satır satır anladığınızda olay bitmiştir. 15 program bittiğinde programlarınızı ister kütüphane fonksiyonları ile ister registerler üzerinden örneklerdeki gibi yazın. Fakat bu ilk 15 program, ARM işlemcileri anlamak adına hayati derecede önemli.
Anlamadığınız tek bir satır dahi kalmamalı ve anlamadığınız satırları muhakkak sormalısınız. Deneyimli arkadaşlar da işin içine girince sorularınız çok kısa zamanda cevaplanacaktır.
Rehber dokumani elinizden eksik etmeyin. Unutmayın. İlmin babası sualdir fakat, Rehber dokümana bakmadan hiç kafa yormadan da sakın soru sormayın.
hocam kitim elime geçmedi fakat, bu kit ile programlayabileceğimiz MCUlar neler ? Picten kurtulmak istiyorum:)
SWD çıkışından S-LINK in desteklediği tüm Cortex-M mcu ları programlaya biliyorsun.
Bende NXP LPC1768 kit var üzerine ST Cortex-M cuc ile SWD koymuşlar. bu kittekinin aynı.
Alıntı yapılan: bunalmis - 16 Aralık 2011, 18:58:27
Kartlar yavaştan yavaştan alıcılarına ulaşmaya başladığına göre bundan sonraki çalışma şekli için bazı yönlendirmelerde bulunacağım.
https://www.picproje.org/index.php/topic,35896.0.html (https://www.picproje.org/index.php/topic,35896.0.html) linkinde yeterince örnek program parçacığımız birikti.
Bunları sıra ile ele almanızı istiyorum.
Bunun için rehber dokumanı açip, örnek programdaki satırları teker teker inceleyip neden bu satırda bu registere bu sayısal değer yüklenmiş sorusunun cevabını anlamanızı istiyorum.
Yaklaşık 15 adet programı satır satır anladığınızda olay bitmiştir. 15 program bittiğinde programlarınızı ister kütüphane fonksiyonları ile ister registerler üzerinden örneklerdeki gibi yazın. Fakat bu ilk 15 program, ARM işlemcileri anlamak adına hayati derecede önemli.
Anlamadığınız tek bir satır dahi kalmamalı ve anlamadığınız satırları muhakkak sormalısınız. Deneyimli arkadaşlar da işin içine girince sorularınız çok kısa zamanda cevaplanacaktır.
Rehber dokumani elinizden eksik etmeyin. Unutmayın. İlmin babası sualdir fakat, Rehber dokümana bakmadan hiç kafa yormadan da sakın soru sormayın.
Bülent abi benim verilen 15 programla herhangi bir sorunum yok. Benim daha çok C ile belli başlı sorunlarım var.
Yukarıda verdiğim kodları yazabilecek kadar C bilmekteyim. Yoksa İşlemci yapısı ve donanımlarının kullanılması hakkında pek sıkıntım yok.
Soruları nereye soracağız ?
Mesela C ile ilgli şuan 50 tane soru sorabilirim.
Bu zamana kadar temel C ile ilgili tum sorunlarin halledilmemesinden korkuyordum. Sorulariniz icin C dilinde samatalar bolumumuz var.
Temel C ile sorunum yok İleri C ile sorunlarım var.
web üzerinde Standar C ile ilgili biraz yazı buldum. olanları toplayıp PDF yapacağım yarın yada en geç pazar paylaşırım.
Alıntı yapılan: EMG81 - 16 Aralık 2011, 21:01:18
Temel C ile sorunum yok İleri C ile sorunlarım var.
Tamam orda sorabilirsin. Ileri seviye sorularini merak ettim.
Mesela anlıyamadığım bikaç program satırı paylaşayım. (bu satırları bikaç mesaj yukarıdan çaldım.)
DMA1_Stream4->PAR=(int)&USART3->DR;// Nereye yazacagiz // DMA1_Stream4 ın PAR registerına USART3->DR ne yapılmış ? "(int)&" C dilinde ne işlem yapmakta?
DMA1_Stream4->FCR&=~0xFFFFFF40; // "&=~" bu işlem C dilinde neler yapar ?
&=~ işlemi
&= şeklinde yada =~ şeklinde kullanmış idim. ama tümleşik olarak ilk kez görüyorum.
(int)& bunu ilk kez şuan görüyorum.
A&=~B demek
A = A AND (NOT B) demek.
A registerinde bazi bitlerin degerini degistirmek istemiyoruz fakat bazilarini sifir yapmak istiyoruz diyelim.
Ornegin 16 bitlik registerin en buyuk 4 bitini 0 yapmak isteyelim.
A = A & 0x0FFF yazabiliriz.
Fakat bunun yerine A = A & (~0xF000) da yazabiliriz. Ikisi de ayni isi yapar.
Maske degerini 1 secmek hosuna gidiyorsa ~0xF000 kullanirsin.
Bu konuyu zamaninda ele almistik. https://www.picproje.org/index.php/topic,35908.0.html (https://www.picproje.org/index.php/topic,35908.0.html) Ne zaman OR ne zaman AND? Basligina bakmamissin.
---------------
Bir degiskenin onune & isareti getirirsen bu degiskenin adresinin kullanilacagini soyler.
Ornegin A=&B; A pointerine B nin adresini atar. (Burada A pointer olmak zorunda)
Eger A pointer değil bir degiskense yada bir registerse fakat buna B nin adresini atamak istiyorsak
bu durumda (int) onekeini getiririz. Bu, &B adresinin integer bir degiskene yuklenecegi anlamina gelir.
-----------------------
Aslinda C derleyicinin kurallarini koyanlara kiziyorum. Esitligin sol tarafi pointer ise &B yi ata. Fakat esitligin sol tarafi pointer değilse esitligin soltarafinin tipi neyse ona cevir ata neden bu isi bana birakiyorsunuz. Eger ben ozellikle tip degistirmek istiyorsam (int) yazayim bu kabul.
bunalmis hocam, sizde C dilini yazanlara kizacaginiza Cnin object'ine uygun D diye bir dil yazin, bu problemleri halledin diyecektimki D dilinin zaten yazildigini hatirladim, o zaman sizede E dilini yazmak kaliyor. :P
Alıntı Yapinanın onlar da en az sizin kadar bu konuları düşünmüşlerdir bunun standardını belirlerken..
Kesinlikle oyle. Bu islere bir kisi değil kurul karar veriyordur. Fakat mantik ne merak ediyorum.
Kizdigimi soyledigim ornekte haksizmiyim.
A unsigned integer bir degisken olsun. Islemcimizin adres busi da unsigned int degerlerle ifade ediliyor olsun.
B ister char ister unsigned char ister short ister unsigned short olsun.
A=&B yazmamda ne sakinca olabilir? Adamlar illa A=(unsigned int)&B yazmami istiyorlar. Gerekce ne? Neyi dusunmusler.
A=&B + 1 yazmamda ne sakinca var?
Gecenlerde benzer bir konu konusmustuk.
A 64 bit degiskense, B 32 bit degiskense
A = B * 3 islemi otomatik olarak 64 bit sonuc uretecek sekilde A ya atanmali. Ama illede digerlerini de 64 bite zorla deniyor.
Kardesim ben 32 bit A degiskenine B*3 islemini atacaksam tamam o zaman int on eki ile zorlayayim.
Bu sorunun kesin cevabi olmali.
@bunalmis hocam bahsettiginiz konu "type conversion" bahsine girer ve degisik dillerde implicit ve explicit type conversion/casting diye bakmaniz lazim.
Maalesef bu konuda tek bir genel/kabul edilen kurallar yoktur. Ne yaptiginizi bilerek Cde tanimli olan sekil bazen unintiutive (sezgisel olmayan) durumlara sebep olabilir.
implicit type conversion in c diye bakabilirsiniz.
Alıntı yapılan: bunalmis - 16 Aralık 2011, 21:23:20
A&=~B demek
A = A AND (NOT B) demek.
A registerinde bazi bitlerin degerini degistirmek istemiyoruz fakat bazilarini sifir yapmak istiyoruz diyelim.
Ornegin 16 bitlik registerin en buyuk 4 bitini 0 yapmak isteyelim.
A = A & 0x0FFF yazabiliriz.
Fakat bunun yerine A = A & (~0xF000) da yazabiliriz. Ikisi de ayni isi yapar.
Maske degerini 1 secmek hosuna gidiyorsa ~0xF000 kullanirsin.
Bu konuyu zamaninda ele almistik. https://www.picproje.org/index.php/topic,35908.0.html (https://www.picproje.org/index.php/topic,35908.0.html) Ne zaman OR ne zaman AND? Basligina bakmamissin.
---------------
Bir degiskenin onune & isareti getirirsen bu degiskenin adresinin kullanilacagini soyler.
Ornegin A=&B; A pointerine B nin adresini atar. (Burada A pointer olmak zorunda)
Eger A pointer değil bir degiskense yada bir registerse fakat buna B nin adresini atamak istiyorsak
bu durumda (int) onekeini getiririz. Bu, &B adresinin integer bir degiskene yuklenecegi anlamina gelir.
-----------------------
Aslinda C derleyicinin kurallarini koyanlara kiziyorum. Esitligin sol tarafi pointer ise &B yi ata. Fakat esitligin sol tarafi pointer değilse esitligin soltarafinin tipi neyse ona cevir ata neden bu isi bana birakiyorsunuz. Eger ben ozellikle tip degistirmek istiyorsam (int) yazayim bu kabul.
Evet. C şamatalarını ilk 2 sayfasına kadar takip edebilmiştim. Sonrada farklı konulara yönelip başlığı unutmuşum. Sonuna kadar okudum, uyguladım. Şu an Birçok soru işaretim yok olmuş durumda. Fakat her an birşeyler sorabilirim. Temkinli olmak lazım. :)
Toplayıp bir döküman haline gitirdiğim web sitesinden alınma notlar
STANDART C PROGRAMLAMA DİLİ -------> http://hotfile.com/dl/137716505/ee6424a/STANDART_C.rar.html
Selamlar ,Benim basim nette buldugum dosyalari derlemek-denemek ile dertte.
Sorun şu dosyalar derlenmiyor, sebebine gelince netten öğrenebildiğim kadarıyla cmsis ve eski dosyalar olarak buldum .
Mesela stm32f10x_conf.h dosyası 2007 tarihli ancak benim örneklerimizde kullandığım stm32f10x.h dosyası 10/15/2010 tarihli ve sürekli tanımlama hataları alıyorum... Keili tekrar mı kurmam gerek yada keildeki kütüphaneleri nasıl update ederim? Keil'e bir update kurmamız mı gerekiyor?
St nin sitesinde standart preph. lib buldum ,bununla deneyeceğim bakalım nasıl olacak.
rvmdk klasorleri altında keil için kod template leri vardır. oraya gerçek çalışmanızın bulunduğu main.c klasöründe bulunan bütün dosyaları source klasörüne atın. header dosyaları da varsa keil içinde ekleyin. çalıışması gerekir...
mesela stm32f10x_usart.h dosyasını projeye eklediğimizde stm32f10x_usart.c dosyasını projeye nerede dahil ediyor anlamadım?
resimdeki mdk arm template klasörüdür. orda main.c ile işaretlenen boşluğa örnek olarak alacağınız klasördeki bütün dosyaları copy paste yapın üstüne yazabilirsiniz dosyaların.
(http://b1112.hizliresim.com/s/l/169rp.jpg)
keil de ilgili template aşağıdaki gibi görüncektir.orda stdperiphdriver altında usart.c olarak bahsettiğiniz bütün fimware dosyaları mevcut.
(http://b1112.hizliresim.com/s/l/169x4.jpg)
sonra keil de main.c çift tıklayın stm32f4xx_conf.h dosyasını açın
/* Uncomment the line below to enable peripheral header file inclusion */
#include "stm32f4xx_adc.h"
#include "stm32f4xx_can.h"
#include "stm32f4xx_crc.h"
#include "stm32f4xx_cryp.h"
#include "stm32f4xx_dac.h"
#include "stm32f4xx_dbgmcu.h"
#include "stm32f4xx_dcmi.h"
#include "stm32f4xx_dma.h"
#include "stm32f4xx_exti.h"
#include "stm32f4xx_flash.h"
#include "stm32f4xx_fsmc.h"
#include "stm32f4xx_hash.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_i2c.h"
#include "stm32f4xx_iwdg.h"
#include "stm32f4xx_pwr.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_rng.h"
#include "stm32f4xx_rtc.h"
#include "stm32f4xx_sdio.h"
#include "stm32f4xx_spi.h"
#include "stm32f4xx_syscfg.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_wwdg.h"
#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
kullanmadığınız firmware için include başına yorum işareti ekletin /*
Ben özel olarak template kullanmak istemiyorum, teplate de herşey düzgün çalışıyor benim anlamak istediğim o template de bazı püf noktalar var. Mesela stm32f10x_usart.c doyasının projeye nerede include edildiğini anlayamadım. stm32f10x_usart.h dosyasının içinde çağırılmıyor.Aksine stm32f10x_usart.c dosyasının içinde stm32f10x_usart.h dosyası çağırılıyor-ekleniyor. Template de ayrı bir grup oluşturup bunun içine tüm .c dosyalarını atmışlar ancak ben o şekilde bir proje oluşturursam bir sürü hata alıyorum..
Ben hata almadım hiç yine de biryerlerde sorunlar vardır muhakkak.ancak template kullanıp gerekli modifikasyonları yaparak ilerliyorum buşekilde debug compile aşamasında hata vermiyor hiç.
Eğer stm32f10x_usart.c dosyasını projeye include ettiği noktayı yakalarsan senden ricam buraya yazabilirmisin.
Bence stm32f4xx_conf.h dosyasındaki
#include "stm32f4xx_usart.h"
satırından projeye dahil oluyor.
O dosyanın içine baktım #include "stm32f10x.h" satırından başka herhangi bir include bulamadım.
Kite program yüklemede bazı sorunlar yaşıyorum:
Yeni yüklediğim programı debug yapmazsam kite yüklenmiyor :
Kite program yüklerken load dediğimde program yükleniyor gözüküyor. Kiti resetlediğimde ne yeni program nede eski program çalışmıyor. beslemeyi söküp taktığımda eski program çalışmaya başlıyor.
Ancak yeni programı yükleyip debug işlemi yaparsam yeni program çalışmaya başlıyor. Reset sonrası veya power off-on sonrası yeni program çalışmaya devam ediyor.
https://www.picproje.org/index.php/topic,35896.0.html linkindeki örnek programlar ile kitimi denemey başladım. Yeni proje oluşturup örnek kodları derliyorum. https://www.picproje.org/index.php/topic,35719.0.html linkinde anlatıldığı gibi debug işlemi için gerekli ayarları yapıyorum.
Load dediğimde "No ULINK Device found" uyarısını alıyorum. Project/Options for Target 'Target1' menüsünden Utilities sekmesi altında "ST-Link Debugger"seçmem gerekiyor. Bunuşekildemi olması lazım?
STM ile çalışırken malesef ancak Debug moduna geçersen program yükleniyor.
https://www.picproje.org/index.php/topic,35719.0.html (https://www.picproje.org/index.php/topic,35719.0.html) lınkinde aşağıdaki görüntünün olduğu kısma bir daha göz at.
U-Link ile ilgili mesaj gelmemesi gerekiyor.
(http://www.cncdesigner.com/STM/SWD.JPG)
İlk olarak bu gösterdiğiniz ayarlamayı yapıyorum amam yeterli olmuyor. Project/Options for Target 'Target1' menüsünden Utilities sekmesi altında "ST-Link Debugger" seçmem gerekiyor.
Arkadaşlar kitteki pinleri misal BBoard üzerine taşımak için tekli bir tarafı dişi bir tarafı erkek kablo nasıl buluruz acaba ? Varmıdır hazır ürünler..
Geçen gün ebay'de görmüştüm, 50-60 tane header'lı kablo birkaç dolardı.
(http://www.elecfreaks.com/store/images/product_images/Prototyping/cable%20&%20wire/wire15-40pin-mm-jumper-01.jpg)
Bunun gibi birşey. Gözüne çarpan olursa haber versin. Konya sokakta vs...
Alıntı yapılan: GreeN - 20 Aralık 2011, 17:50:57
Bunun gibi birşey. Gözüne çarpan olursa haber versin. Konya sokakta vs...
Daha önce Sparkfun'dan (Türkiye'de Robit) 10'ar adet erkek-erkek, erkek-dişi, dişi-dişi olarak almıştım, şimdi 100 lük paketler halinde satılıyor gördüğüm kadarıyla :
http://www.robitshop.com/Jumper-Wires-Premium-6-MM-Pack-of-100,PR-1603.html
Düzeltme:
10 luk ve 50 lik paketleri de varmış.
Erkek - Dişi : http://www.robitshop.com/Premium-Jumper-Wire-50-Piece-Rainbow-Assortment-M-F-3,PR-939.html
Erkek pin header bir parça kablo ve makaron ile kendi kablomu yapıyorum.
(http://s12.postimg.cc/5btbvplax/DSCN8719.jpg) (http://postimg.cc/image/5btbvplax/)
Pin header sistemin çok kullanışlı olmadığını düşünerek kit üzerinde modifikasyon yaptım.
Erkek pinleri sökerek dişi kulandım. Kartın alt tarafında kısadevre oluşmasın diye yükseltmek için kartın alt tarafındaki Jp2 ve Jp3 jumperlerını sökmedim. Micro ubs soketi altındaki gnd bağlantısına 90 derecelik erkek pin header lehim yaparak bir destek oluşturdum.
(http://s11.postimg.cc/4a12crf2n/DSCN8720.jpg) (http://postimg.cc/image/4a12crf2n/)
(http://s9.postimg.cc/aod7nu9uz/DSCN8721.jpg) (http://postimg.cc/image/aod7nu9uz/)
Alıntı yapılan: NecroCapo - 20 Aralık 2011, 18:09:33
Daha önce Sparkfun'dan (Türkiye'de Robit) 10'ar adet erkek-erkek, erkek-dişi, dişi-dişi olarak almıştım, şimdi 100 lük paketler halinde satılıyor gördüğüm kadarıyla :
http://www.robitshop.com/Jumper-Wires-Premium-6-MM-Pack-of-100,PR-1603.html
Düzeltme:
10 luk ve 50 lik paketleri de varmış.
Erkek - Dişi : http://www.robitshop.com/Premium-Jumper-Wire-50-Piece-Rainbow-Assortment-M-F-3,PR-939.html
İşte bu eyvallah.
@Cenkun çok güzel olmuş .
Benim kitlerdeki MEMS sensörler neden 2 kitte de aynı tepkiyi vermiyor.Yani LED'lerin yanma durumu 2 kitte de aynı konumlar için geçerli değil.Birisinde kartı fazla devirmek gerekiyor vs. Sebebi ne olabilir ? Kodlar aynı değil mi?
Alıntı yapılan: silvercopper - 21 Aralık 2011, 01:31:44
Benim kitlerdeki MEMS sensörler neden 2 kitte de aynı tepkiyi vermiyor.Yani LED'lerin yanma durumu 2 kitte de aynı konumlar için geçerli değil.Birisinde kartı fazla devirmek gerekiyor vs. Sebebi ne olabilir ? Kodlar aynı değil mi?
butona bastığınız konumdaki noktayı sıfır baz alarak ona göre ledleri yakıyor
Hee, şu ezbere iş yapmam yok mu bir gün başımı belaya sokacak.Kartı sabitleyip butona bastım,sorun kalmadı.
Alıntı yapılan: cenkun - 20 Aralık 2011, 18:31:42
Pin header sistemin çok kullanışlı olmadığını düşünerek kit üzerinde modifikasyon yaptım.
Erkek pinleri sökerek dişi kulandım. Kartın alt tarafında kısadevre oluşmasın diye yükseltmek için kartın alt tarafındaki Jp2 ve Jp3 jumperlerını sökmedim. Micro ubs soketi altındaki gnd bağlantısına 90 derecelik erkek pin header lehim yaparak bir destek oluşturdum.
(http://s11.postimg.cc/4a12crf2n/DSCN8720.jpg) (http://postimg.cc/image/4a12crf2n/)
(http://s9.postimg.cc/aod7nu9uz/DSCN8721.jpg) (http://postimg.cc/image/aod7nu9uz/)
güzel olmuş.
No ULINK Device found
debug yapmak istediğimde bu uyarıyı alıp da çözümünü bulan var mı acaba.
options for target debug menu den use stlink debugger seçilecek.
(http://b1112.hizliresim.com/s/p/17yv2.jpg)
Kartı ilk USB taktığınızda sürücü yüklemeye çalıyor ve başarısız oluyor ise ST-LINK sürücüsünü el ile yüklemek gerek mektedir.
http://www.st.com/internet/evalboard/product/219866.jsp adresinden gerekli sürücü temin edilebilir.
[IMG]http://img585.imageshack.us/img585/7747/50841265.jpg[/img]
cevaplar için teşkkürler.debugger kısımında stlink seçili. kartı balayınca donanında stlink dongle da çıkıyor.
no ULINK device found dan sonra "flash download failed- target DLL has been cancelled" hatasını da veriyor. 64 bit win7 den kaynaklı olabilir mi? aygıt yöneticisinde hiç bir sorun gözükmüyor.
Option for target da hem debug hem de utilities menülerinde ST-Link Debugger seçmeniz gerekiyor.
sağolasın bunalmış hocam gene hallettin.
örnek uygulamalardan ikincisi de bir sıkıntı var.
// RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
kod bloğunda örnek programda aşağıdaki gibi yazılmış yukarıdaki gibi düzeltince program işliyor. Aşağıdaki gibi kaldığında OSC oturtma ve kurtarma rutini satırını geçemiyor.
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
Her iki kod da çalışıyor.
2. programda (butona basınca yanan led uygulaması) çalışmadığını söylediğiniz programı derleyip debug penceresinde F5 e basın.
Daha sonra kart üzerindeki mavi butona basın ledlerin yanması gerekir.
İlk kodlarda aşağıdaki satır kullanılırken;
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
Daha sonraları dokumanlarda PLL girişinin 2Mhz olmasının jitter açısından daha iyi olduğu okununca aşağıdaki satır kullanılmaya başlandı.
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
Buton uygulamasını yüklemiştim , çalışıyor .
Alıntı yapılan: bunalmis - 21 Aralık 2011, 17:27:05
Her iki kod da çalışıyor.
2. programda (butona basınca yanan led uygulaması) çalışmadığını söylediğiniz programı derleyip debug penceresinde F5 e basın.
Daha sonra kart üzerindeki mavi butona basın ledlerin yanması gerekir.
İlk kodlarda aşağıdaki satır kullanılırken;
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
Daha sonraları dokumanlarda PLL girişinin 2Mhz olmasının jitter açısından daha iyi olduğu okununca aşağıdaki satır kullanılmaya başlandı.
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
@bunalmis hocam sonradan farkettim , "jittter" PLL'nin kayması gibi birşey mi ?
".... PLL girişinin 2Mhz olmasının jitter açısından daha iyi olduğu...." yoksa diğer çevre birimler üzerinde etkisinden mi bahsetmek istediniz.
Bir yerde DAC - jitter ile alakalı birşey okumuştum. Özel bir terim mi , genel bir ifademi merak ettim.
Diyelimki PLL 100Mhz e set edildi fakat PLL 100Mhz e kitlenmeyip 99, 100, 101, 100, 99, 101 gibi sürekli geziniyorsa bu jitter olarak bilinir. Gerçi PLL ne yapılırsa yapılsın muhakkak küçükte olsa bir jitter olur fakat bu rahatsız edici düzeyde olmamalıdır.
Debug yaptığımda OSC oturtma ve kurtarma rutini satırını geçemediğini fark ettim.
benzer bir durum LEDleri flash yapan programda da oldu. ilk derlediğimde yine OSC oturtma ve kurtarma rutini satırını da kaldı. Bahsettiğim satırları değiştirip clear traget yapıp tekrar derledim yine çalışmadı. Değişkliği iptal Bahsettiğim satırları eski haline değiştirip clear traget yapıp tekrar derledime bu sefer çalıştı.
Sıkıntını ne olduğunu anlamadım. Tekrar bir daha kontrol edeyim.
Kitin driver ını bu linkten indirebilirsiniz
http://www.st.com/stonline/stappl/resourceSelector/app?page=resourceSelector&doctype=DEVICE_PROGRAMMER&ClassID=1782
(http://www.upload-pics.com/image-host/dsc07224.jpg) (http://www.upload-pics.com/?v=dsc07224.jpg)
(http://www.upload-pics.com/image-host/dsc07225.jpg) (http://www.upload-pics.com/?v=dsc07225.jpg)
(http://www.upload-pics.com/image-host/dsc07226.jpg) (http://www.upload-pics.com/?v=dsc07226.jpg)
kiti koruma için altına 5 mm plexiglass kestirdim ve dişi head pin taktım bence süper oldu
Güzel olmuş da şimdi ben böyle bir modifikasyon yapmaya kalksam heba etmek için en az 10 tane kit lazım bana ;D
İyi geceler zabun92,
Birşey merak ettim, bu "dişi head pin taktım" kısmını nasıl yaptınız.
Erkek pinleri söktünüz mü tamamen, yoksa uçları kesip kısaltınız mı?
Zira sökmek çok zahmetli gözüküyor.
tamamen söktüm bir tarafından ısıtıp diğer tarafından kargabunun ile çıkardım
GND pinlerini sökerken çok zorlandım neden böyle oldu hiç anlamadım 9 tane gnd pini var
Alıntı yapılan: zabun92 - 23 Aralık 2011, 01:28:10
tamamen söktüm bir tarafından ısıtıp diğer tarafından kargabunun ile çıkardım
GND pinlerini sökerken çok zorlandım neden böyle oldu hiç anlamadım 9 tane gnd pini var
ısının bakır yüzey üzerinde hızla yayılması buna etken olabilir mi? GND bakırları kastım. :)
olabilir ama o kadar hızlı yayılacağını zannetmiyorum
Keil'i Linuxta kullanan var mı ?
Ubuntu kullanıyorum ve Keil 4.22.22 sürümünü yükledim (wine ile çalıştırıyorum). Herşey sorunsuz, kod yazıyorum, başarıyla compile ediyorum, fakat programlamak istediğimde "No ST-Link detected" mesajı alıyorum.
Daha önceden ufak tefek programlarla eski M3 cortex STM32 VL Discovery kitime axf'yi haricen atabiliyordum, fakat bir süre sonra sanıyorum bootloader uçtu. Bu yüzden, bilmediğim programları da kullanmak istemiyorum. Linux için önerebileceğiniz bir program var mı ?
yapacağınız şey önce televizyon anten kablolarının dışındaki ağ gibi olan malzemeyi alıyoruz. güzelce pastaya buluyoruz. ardından lehimini almak istediğimiz yerin üzerine getiriyoruz. ardından güzelce havyayı lehimleri üzerine alıncaya kadar ağ olarak tabir ettiğim çoklu kablonun üzerinde gezdiriyoruz. yavaş yavaş lehimi üzerine almaya başlaycaktır. tertemiz oluncaya kadar bu işleme devam ediyoruz. eğer işlem tam olarak bitmemişse biraz bekliyoruz. pinleri yeniden pense ile tutup havyayla ısıtarak yavaşça çekiyoruz. kolay gelsin.
Alıntı yapılan: NecroCapo - 23 Aralık 2011, 10:10:44
Keil'i Linuxta kullanan var mı ?
Ubuntu kullanıyorum ve Keil 4.22.22 sürümünü yükledim (wine ile çalıştırıyorum). Herşey sorunsuz, kod yazıyorum, başarıyla compile ediyorum, fakat programlamak istediğimde "No ST-Link detected" mesajı alıyorum.
Daha önceden ufak tefek programlarla eski M3 cortex STM32 VL Discovery kitime axf'yi haricen atabiliyordum, fakat bir süre sonra sanıyorum bootloader uçtu. Bu yüzden, bilmediğim programları da kullanmak istemiyorum. Linux için önerebileceğiniz bir program var mı ?
ST linki kurdunuz mu? Eğer kurmadıysanız böyle bi hata vermesi normal.
Alıntı yapılan: yamak - 23 Aralık 2011, 12:45:57
ST linki kurdunuz mu? Eğer kurmadıysanız böyle bi hata vermesi normal.
st-link_v2_usbdriver.exe'yi kurdum wine üzerinden. Fakat stm32_st-link_utility.exe wine'da çalışmıyor, yükleme esnasında "1607: Unable to install InstallShield Scripting Runtime" hatası verip kapanıyor.
Şu an ben de denedim olmuyo. Olmamasının nedeni bence st-link kurmamıza rağmen ubuntunun kiti donanım olarak tanıyamaması.
Alıntı yapılan: yamak - 23 Aralık 2011, 14:50:31
Şu an ben de denedim olmuyo. Olmamasının nedeni bence st-link kurmamıza rağmen ubuntunun kiti donanım olarak tanıyamaması.
Elemanın birisi St-link v2 için (bizim kitte bu kullanılıyor) programlayıcı yapmış.
http://forum.chibios.org/phpbb/viewtopic.php?f=8&t=211
Yükledim, öncelikle connect diyerek St-Link'e bağlandım :
Alıntı Yap6 Device descriptions loaded.
Searching Device...
ST Link V2 found!
Fetching version...
Changing mode to SWD...
Fetching mode...
Mode: Debug
Fetching status...
Status: Core Halted
Fetching MCU Info...
Daha sonra "Receive" diyerek kitte default olarak yüklü gelen kodun yedeğini alıp yedek.axf olarak kaydettim. Daha sonra Keil'de derlediğim blink.axf dosyasını "Send" ile gönderdim. Fakat ledlerde hiçbir değişiklik olmadı. Daha sonra yedek.axf yi "Send" ile gönderdiğimde; kit bana ilk geldiği şekildeki gibi ledler sırayla yanıp sönüyor.
Bu sefer de Keil'de derlediğim koddan (veya ayarlarından) şüphelendim. Sorunun bu qstlink2 programından mı, yoksa benim Keil'den mi olduğunu test etmem için;
Elinde led yakıp söndürecek hazır derlenmiş dosyası olan varsa, gönderebilir mi acaba ?
Atollic ile keil karşılaştırılırsa hangisi fonksiyonel ve kolay
Bugüne kadar BASIC yada ASM ile kod yazan arkadaşlardan kitleri ellerine ulaşmış olanlara sormak istiyorum.
Ne durumdasınız? Kartla ne gibi çalışmalar yaptınız? Keilde neler yapabiliyorsunuz? En azından 10 kişiden cevap alabilirmiyim?
Zaten eskiden beri C kullanan arkadaşlar, sizlerin durumu ne?
defter kitap açık sınavlar gözümü korkuttu ama hazırım :)
bugüne kadar ki konularda sorun yok hocam haftaya kartım gelince de;
SPI, DMA&SPI, Interrupt&DMA&SPI ve I2C türevlerinin denemelerini yapmayı planlıyorum
Ben eskiden beri hi tech c kullanıyordum. Ancak c ye öyle çok hakim değildim, konuları yakından takip ediyorum. Özellikle structure anlatımı oldukça iyi oldu benim için. Arm mimarisine alışkın olmadığım için verdiğiniz örnek programları dikkatle inceliyorum. Sizinde dediğiniz gibi rehber ve hard dökümanlarını inceleyince zaten neyi neden yaptığınız anlıyorum ama sıfırdan örnek programlara bakmadan program yaz deseniz yazamam yada çok zorlanırım herhalde. Ama zamanla bunun gerçekleşeceğine inanıyorum. Keil ve debug konusunda bir sıkıntım yok. Teşekkürler.
bunalmış hocam.
GPIOx_OSPEEDR resette sadece B portu için 0x0000 00C0 diğerleri için 0x0000 0000 değerinde.
siz tüm bitleri set ediyorsunuz. 16 bitlik port için her bir bitin 4 farklı alabileceği değerden 11=100MHz i seçiyorsunuz. 30pf da diyor tabiii. bu kristal ile 30pf kullanıldığında anlamına mı geliyor.
System clock (SYSCLK) selection
After a system reset, the HSI oscillator is selected as the system clock. When a clock source
is used directly or through PLL as the system clock, it is not possible to stop it.
sistem 16MHz Rc osilatör ile çalışıyor.
RCC-CFRG reset değeri 0x0000 0000 ile çalışacağıncan AHB ve APB ler için presecale yok. Hepsi 16MHz de çalışır.
PORTlarda AHB den çalıştığına göre onlarda 16MHz de olmazmı.
GPIOD->OSPEEDR= 0xFFFFFFFF bunu yapmanın bir anlamı varmı?
[IMG]http://img688.imageshack.us/img688/2840/adszbnv.jpg[/img] (http://imageshack.us/photo/my-images/688/adszbnv.jpg/)
yüklerken burada kilitleniyor yanıt vermiyor iki tane pc var ikisinde de kilitleniyor sebebi ne olabilir?
İndirdiğiniz dosyanın md5'i aşağıdaki ile aynı mı?
MD5 = 85b75d91d6c30cd29e946c630a173440
Alıntı yapılan: mozkan87 - 24 Aralık 2011, 13:01:15
İndirdiğiniz dosyanın md5'i aşağıdaki ile aynı mı?
MD5 = 85b75d91d6c30cd29e946c630a173440
MD5 ne, Nereden bakıyoruz
MD5 genellikle büyük boyutlu dosyalarda doğrulama amaçlı kullanılan bir hash yöntemidir yani kısaca her dosyaya özgü bir kod diyebiliriz. Hashtab (http://www.implbits.com/hashtab.aspx) diye bir eklenti var ücretsiz. Daha sonra dosyanın üzerinde özellikler deyince dosya hashleri sekemsinden bakabilirsiniz. Kolay gelsin.
4.23 versiyonu indirip kurar iken bu sorun ile karşılaşanlar, tekrar indirsin.
Bende benzeri durum ile karşılaştım.
Az önce indirdim kurdum ve ilçladım sorun yok eski ilaç sorunsuz çalışıyor.
Alıntı yapılan: MC_Skywalker - 24 Aralık 2011, 13:23:06
4.23 versiyonu indirip kurar iken bu sorun ile karşılaşanlar, tekrar indirsin.
Bende benzeri durum ile karşılaştım.
sağolun hocam şimdi indiriyorum
Keil in hazir prototiplerinde c dosyalarini grup icine atip bir sekilde projeye dahil ediyorlar #include kullanmadan , nasil yapiliyor anlayamadim hala, grup yaypip icine c dosyasi atarsam onlarida ana dosya gibi derlemeye kalkiyor tabi bir suru problem cikiyor. Ancak kendi template sinde hic bir problem yok.
Olayı uzun bir zamandan sonra çözebilidim.Keilde grup içine eklediğimiz .c uzantılı dosyalar include demesek bile derleniyor. .h uzantılı dosyalarda .c uzantılı dosyalardan kullanacağımız fonksiyonların prototiplerini bildiriyoruz.
Ayrıca önemli bir nokta ve benim takıldığım nokta .c dosyalarında bazı h dosyaları yeniden çağırılıyor örnek stm32f10x.h gibi ve bu .h dosyalarında bazı şeyleri belirlemiş olmanız gerekiyor mesela STM32F10X_LD_VL tanımı gibi.Bu tanımı #define STM32F10X_LD_VL şeklinde main.c de yaparsanız özellikle st nin hazır kütüphanelerini kullanırken problem çıkıyor.Çünki main.c ayrı derleniyor , diğer .c dosyaları ayrı derleniyor. Ve diğer .c uzantılı dosyalar derlenirken sizden STM32F10X_LD_VL gibi bir tanımı yapmadığınızı söyleyip tanım istiyor ve program derlenmiyor....Çözüm target options a tıklayıp c/c++ lanında bu genel preprocessor leri tanımlamak....Bayadır anlayamıyordum sonunda çözdüm.
ben bir defa indirdim kurdum indirdiğim gün hevesle kod derledim debug yaptım.
ertesi gün keil hata verdi.
kaldırıp yeniden kurayım dedim zabun92nin sorunu bendede oldu
yeniden indirdim yine aynı.
:'(
daha başlamadan çuvalladık :)
Alıntı yapılan: zabun92 - 24 Aralık 2011, 23:23:01
daha başlamadan çuvalladık :)
üstat hiç sorma hevesim gursağımda kaldı resmen
maddi darboğazdan bir kurtulursam bu pcye çekiçle dalacam o kadar olur
allahtan bascomavr yi çalıştırıyor. onunla iyi kötü bişiler yapıyorum. çok fazla pratik yapmaya ihtiyacım var.
forumda kodlar havada uçuşuyor ben kaz gibi bakıyorum :'(
Sorun nedir? Keil calismiyormu?
çalışmıyor hocam hatta hata mesajına burada paylaşmıştım konularda çok mesaj var kayboldu gitti.
yeniden kurayım dedim kurulum esnasında zabun92 nin yaşadığı sorunu yaşıyorum
1 şubata kadar bu keil sorunu aşamazsam kitimi iş yerimden kiti heba etmeyecek birine bagışlamayı düşünüyorum.
Bir ara arkadaslar sorun yasamis bunun uzerine birileri kurulum dosyasini bir yerlere yuklemisti. Bir de ordan indirmek lazim. Neresi hatirlamiyorum.
Virus tarayici vs varsa belki gecici olarak devre disi birakmak ise yarayabilir.
Alıntı yapılan: ilhan_mkp - 25 Aralık 2011, 00:21:23
çalışmıyor hocam hatta hata mesajına burada paylaşmıştım konularda çok mesaj var kayboldu gitti.
yeniden kurayım dedim kurulum esnasında zabun92 nin yaşadığı sorunu yaşıyorum
1 şubata kadar bu keil sorunu aşamazsam kitimi iş yerimden kiti heba etmeyecek birine bagışlamayı düşünüyorum.
1) Kurulum dosyanız doğru inmiş mi bunu kontrol ettiniz mi?
2) Hangi versiyon için deniyorsunuz? Kullandığınız işletim sistemi nedir?
3) Kullanıcı hesabı denetimi açık mı?
4) Kurulumu başlatırken sağ tıklayıp yönetici olarak çalıştır deyipte denediniz mi?
5) Güvenlik programı kurulu mu, kurulu ise devre dışı bırakıp kurmayı denediniz mi?
bunları bir kontrol edip tekrar bilgilendirirseniz daha net çözümler sunabiliriz. Kolay gelsin.
Alıntı yapılan: mozkan87 - 25 Aralık 2011, 00:32:34
1) Kurulum dosyanız doğru inmiş mi bunu kontrol ettiniz mi?
2) Hangi versiyon için deniyorsunuz? Kullandığınız işletim sistemi nedir?
3) Kullanıcı hesabı denetimi açık mı?
4) Kurulumu başlatırken sağ tıklayıp yönetici olarak çalıştır deyipte denediniz mi?
5) Güvenlik programı kurulu mu, kurulu ise devre dışı bırakıp kurmayı denediniz mi?
bunları bir kontrol edip tekrar bilgilendirirseniz daha net çözümler sunabiliriz. Kolay gelsin.
1 kurulum dosya doğru inmiş çünkü bir defa kurup çlıştırdım debug bile yaptım burda sorun yok
2 keil uvision4 xp pro
3 bu konuda hiç bir fikrim yok ???
4 hayır (bu win7de gereken bir durum değilmi?)
5 kurulu değil
kurulu olan programın verdiği hata
microsoft c++ runtime library (pencere başlığı)
runtime error!
program:c:\keil\uv4\uv4.exe
r6002
-floating point support not loadet
Google da runtime error! keil\uv4\uv4.exe yazınca bayağı bir şey çıktı.
http://www.google.com/#sclient=psy-ab&hl=tr&source=hp&q=runtime+error!+keil\uv4\uv4.exe&pbx=1&oq=runtime+error!+keil\uv4\uv4.exe&aq=f&aqi=&aql=&gs_sm=e&gs_upl=22905l25360l2l26493l4l4l0l0l0l0l176l552l0.4l4l0&bav=on.2,or.r_gc.r_pw.,cf.osb&fp=c8c1f1356caff84a&biw=1600&bih=761 (http://www.google.com/#sclient=psy-ab&hl=tr&source=hp&q=runtime+error%21+keil%5Cuv4%5Cuv4.exe&pbx=1&oq=runtime+error%21+keil%5Cuv4%5Cuv4.exe&aq=f&aqi=&aql=&gs_sm=e&gs_upl=22905l25360l2l26493l4l4l0l0l0l0l176l552l0.4l4l0&bav=on.2,or.r_gc.r_pw.,cf.osb&fp=c8c1f1356caff84a&biw=1600&bih=761)
Aşağıdaki linkten c++ redistrubite indirip kurabilirmisiniz. 3 soru zaten XP için değil vista ve win7 ile gelen bir özellik.
http://www.microsoft.com/download/en/details.aspx?id=5555
üstat kurdum tık yok aynı hatayı veriyor
Hocam bu hata sadece keil'e ait bir hata değil c++ altyapısını kullanan bütün programlar bu hatayı verbilir hatta nette biraz araştırdım bunun sebebinin virüs olduğunu söylemişler. Aynı sizdeki durum onlardada olmuş önceden düzgün çalışan program sonradan "c++ runtime error r6002 floating point support not loaded" hatasını vermiş. Çözüm olaraktabilgisayarda bulunan bütün diskleri formatlayın demişler. Sadece c'yi formatlamak sorunu çözmüyor diye yazmışlar. Kusura bakmayın elimden gelen bunlar. Kolay gelsin.
üstat ne kusuru gecenin bu saati zaman ayırdığın için ben teşekkür ederim bir şekilde çözücem pcde bir çok sorun var yenisine sağlık ;D
keil i kurdum şimdide bu hatayı veriyor
[IMG]http://img580.imageshack.us/img580/4474/adszaf.jpg[/img] (http://imageshack.us/photo/my-images/580/adszaf.jpg/)
Gecmiş olsun keil çalışmış.
Programın en sonuna gelip entere bas. Yazdığın her programda bunu alışkanlık haline getir.
Bir daha derle.
GPIOD hatasını vermemesi gerekiyordu.
sağolun hocam
http://www.cncdesigner.com/STM/Ornek.JPG
bu resimdeki program çalıştı ama bu yazılım çalışmadı
enter a bastım yine aynı hata veriyor :(
Alamsız bir terslik var.
Programın en sonundaki } olan kisma gel } dahil alttaki // Programin sonu vs herseyi sil.
Sonra} yaz ve entere bas.
Ardindan F7 ile derle. En azindan warning yok olsun.
yardımlarınız için teşekkür ederim hocam sorunu çözdüm pc nin şarjı bitip kapanmasaydı deli olacaktım :D
merhabalar discovery kitin içindeki default programın bir özeliiği de micro usb takılırsa mouse olarak kullanılabiliyormuş, okudğum kadarıyla.
o kablom şimdi olmadığı için bunu deneyemedim.
şimdi "bunalmış" hocanın ilk programlarını denemek istiyorum.
ileriki zamanda bu mouse programını tekrar yüklemek istersem nerden bulabilirim
[IMG]http://img859.imageshack.us/img859/5574/imag0336w.jpg[/img] (http://imageshack.us/photo/my-images/859/imag0336w.jpg/)
Yardımlarınız için teşekkür ederim hocam
Değerli arkadaşlar,
STM32F4 Discovery kitten bir arkadaşım aracılığıyla temin etmiştim. Kit elime cuma gün geçti. Bülent hocamın bütün derslerini takip etmiştim ve örnek programların çoğunu Keil'de yazıp çalıştırdım.
Bu arada dün ikinci usb kabloyu şaşırtıcı şekilde Muğla'da temin edip (şaşırtıcı çünkü burada tek elektronik malzeme satan yer var ve orada lcd'yi falan bırakın 7 segment display bile bulamayabiliyoruz ) cursoru hareket ettiren demoyu deneyebildim. Eğer becerebilirsem videosunu da çekip ekleyeceğim merak edenler için.
Ben heyecanla Bülent hocanın örnekleri denerken demo yazılımı silmiştim tabi. Tekrar gerekince epey aradım ve foruma da baktım ama bulamadım yada ben göremedim. Gerekenler için nereden bulabileceğinizi de ben yazayım:
Bu adresten: http://www.st.com/internet/evalboard/product/252419.jsp (http://www.st.com/internet/evalboard/product/252419.jsp), Design support kısmından en alttaki firmware dosyasını indirirseniz bu dosya içerisinde Project/Demonstration/MDK-ARM klasöründe Keil projesi olarak bulabiliyorsunuz. Derleyip debug yapınca ilk elimize gelen kitteki demo yazılımı yüklenmiş oluyor.
Selamlar...
arkadaşlar program yazmaya bugün fırsatım oldu, sizlerden geri kalmıs olabilirm.
hocamızn vermiş oldugu led yakma programını denemek istedim fakat 0 hata 1 uyarı veriyor
şu program;
#include "STM32F4xx.h"
void SystemInit()
{
RCC->AHB1ENR |= 0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
int main()
{
while(1)
{
GPIOD->ODR= 0x0000F000; // Ledler yansin
GPIOD->ODR= 0x00000000; // Ledler sonsun
}
}
bildirimde şu şekilde ;
Build target 'Target 1'
compiling led.c...
led.c(17): warning: #1-D: last line of file ends without a newline
linking...
Program Size: Code=396 RO-data=408 RW-data=0 ZI-data=1632
"led.axf" - 0 Error(s), 1 Warning(s).
nerede yanlış yapıyorum??
tamam hocam denedim oldu :) ilk basta uyarı verdi daha sonra 0 0 oldu analamdım neden oldu. hocam bir sorum daha olcaktı. programı çalıstırdım keilden rest atıp çalıstırıyorum fakat kart üzerindeki reset butonuna bastıgımda ledler kısık yanık şekilde kalıyor nedeni ne olabilir?
kartla debug işlemi esnasında interrupt enable için kullanılan bir registerın içeriğini nasıl görebilirim. o satırda bir break point koysam. f5 ile run edip orda beklediğinde f11 le o satırı işletince registerın içeriğini nerden izleyebilirim. mesala register EXTI_IMR.
sorumun cevabını buldum sanırım.
program normalde led yak ve söndür işlemi yapıyor,
debug üzerinden tek tek komut işlettigimiz için yakma ve söndürmeyi görüyoruz, birde programda while komutunda breakpoin konuldugu için programdan reset yaptıgımda burada bekeleme yapıyor fakat kart üzerinden reset yaptıgım zaman dogrudan döngüye girip ledleri yakıp söndüreme işlemi yapıyor ve bu yüzdende ledlerrin hepsi kısık yanık kalıyor.
Alıntı Yapkartla debug işlemi esnasında interrupt enable için kullanılan bir registerın içeriğini nasıl görebilirim. o satırda bir break point koysam. f5 ile run edip orda beklediğinde f11 le o satırı işletince registerın içeriğini nerden izleyebilirim. mesala register EXTI_IMR.
peripherals kısmından mı izleniyor acaba.
Alıntı yapılan: Tlepsh - 25 Aralık 2011, 20:56:08
Değerli arkadaşlar,
STM32F4 Discovery kitten bir arkadaşım aracılığıyla temin etmiştim. Kit elime cuma gün geçti. Bülent hocamın bütün derslerini takip etmiştim ve örnek programların çoğunu Keil'de yazıp çalıştırdım.
Bu arada dün ikinci usb kabloyu şaşırtıcı şekilde Muğla'da temin edip (şaşırtıcı çünkü burada tek elektronik malzeme satan yer var ve orada lcd'yi falan bırakın 7 segment display bile bulamayabiliyoruz ) cursoru hareket ettiren demoyu deneyebildim. Eğer becerebilirsem videosunu da çekip ekleyeceğim merak edenler için.
Ben heyecanla Bülent hocanın örnekleri denerken demo yazılımı silmiştim tabi. Tekrar gerekince epey aradım ve foruma da baktım ama bulamadım yada ben göremedim. Gerekenler için nereden bulabileceğinizi de ben yazayım:
Bu adresten: http://www.st.com/internet/evalboard/product/252419.jsp (http://www.st.com/internet/evalboard/product/252419.jsp), Design support kısmından en alttaki firmware dosyasını indirirseniz bu dosya içerisinde Project/Demonstration/MDK-ARM klasöründe Keil projesi olarak bulabiliyorsunuz. Derleyip debug yapınca ilk elimize gelen kitteki demo yazılımı yüklenmiş oluyor.
Selamlar...
cevabın için çok teşekür ederim Tlepsh.
sağolasın.
selamlar...
ST firması neden şu register'lara kolay erişilebilecek şekilde header dosyaları oluşturmamış ki sanki... Bahsettiğim şu linkteki gibi header'lar (MPC565 mikrodenetleyicisi için)
http://etidweb.tamu.edu/ftp/ENTC369/Code/MPC555/Include%20Files/m_mios.h
Alıntı yapılan: CoşkuN - 27 Aralık 2011, 13:23:36
ST firması neden şu register'lara kolay erişilebilecek şekilde header dosyaları oluşturmamış ki sanki... Bahsettiğim şu linkteki gibi header'lar (MPC565 mikrodenetleyicisi için)
http://etidweb.tamu.edu/ftp/ENTC369/Code/MPC555/Include%20Files/m_mios.h
hocam onlar var..
Alıntı yapılan: memo333 - 27 Aralık 2011, 13:38:37
hocam onlar var..
Bak buna çok sevinirim gerçekten, nerede?
STnin kendi yayınladığı STLIB var.
link:
http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4_dsp_stdperiph_lib.zip
Bunu indirip örneklere bakabilirsiniz.
Zamanım olursa bunlarla ilgili dersnotu tarzı birşeyler yayınlamak istiyorum..
Alıntı yapılan: memo333 - 27 Aralık 2011, 15:03:46
STnin kendi yayınladığı STLIB var.
link:
http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4_dsp_stdperiph_lib.zip
Bunu indirip örneklere bakabilirsiniz.
Zamanım olursa bunlarla ilgili dersnotu tarzı birşeyler yayınlamak istiyorum..
Bunu biliyorum. Bahsettiğim şey örnekte verdiğim dosyadaki gibi resigter'ların bitlerine erişim için struct ve union'larla oluşturulmuş header dosyaları... Böylelikle yine register'larla yapılan işlemler daha kolay bir şekilde (kütüphane fonksiyonları olmadan) gerçekleştirilebilir.
Alıntı yapılan: CoşkuN - 27 Aralık 2011, 15:19:09
Bunu biliyorum. Bahsettiğim şey örnekte verdiğim dosyadaki gibi resigter'ların bitlerine erişim için struct ve union'larla oluşturulmuş header dosyaları... Böylelikle yine register'larla yapılan işlemler daha kolay bir şekilde (kütüphane fonksiyonları olmadan) gerçekleştirilebilir.
"stm32f4xx.h" dosyasında birşeyler var ama tam olarak istediğiniz gibi bişey mi denemek lazım. belki sadece bu dosya ile dediğiniz gibi registerlara ulaşılabilir.
İşlemcinin saat frekansı ayarlama işlemleri oldukça karmaşık gibi görünebiliyor başlangıçta. Bu ayarları kolaylıkla yapabilmek için bir araç da varmış, uygulama dökümanıyla birlikte
http://www.st.com/internet/mcu/product/252140.jsp
sayfasında Configuration Utilities bölümünde
"Clock configuration tool for STM32F40x/41x microcontrollers"
Alıntı yapılan: CoşkuN - 28 Aralık 2011, 10:35:55
İşlemcinin saat frekansı ayarlama işlemleri oldukça karmaşık gibi görünebiliyor başlangıçta. Bu ayarları kolaylıkla yapabilmek için bir araç da varmış, uygulama dökümanıyla birlikte
http://www.st.com/internet/mcu/product/252140.jsp
sayfasında Configuration Utilities bölümünde
"Clock configuration tool for STM32F40x/41x microcontrollers"
http://www.st.com/internet/com/SOFTWARE_RESOURCES/TOOL/DEVICE_PROGRAMMER/stm32_programming_solutions.pdf
Alıntı yapılan: CoşkuN - 28 Aralık 2011, 10:35:55
İşlemcinin saat frekansı ayarlama işlemleri oldukça karmaşık gibi görünebiliyor başlangıçta. Bu ayarları kolaylıkla yapabilmek için bir araç da varmış, uygulama dökümanıyla birlikte
http://www.st.com/internet/mcu/product/252140.jsp
sayfasında Configuration Utilities bölümünde
"Clock configuration tool for STM32F40x/41x microcontrollers"
yani bu:
http://www.st.com/internet/com/SOFTWARE_RESOURCES/TOOL/CONFIGURATION_UTILITY/stm32f4_clockconfig.zip
stm32f4 lere peripheral-peripheral dma neden koymamışlar ki? :)
o da olmayıversin hocam ;D
Olurmu ya o kadar para verdik ;D denemek için lpc mi alcaz.
lpc de varmıymış hocam. varsa ben bunu bir ekmek arası yapayım. ;D gözüme çok batıyor. çalıştıramıyom zaten. lpc alalım bir de ;D
bunalmış hocamın memoryden memory ye dma kaullanarak veri transferi yapma örneği nde 37. satır for döngüsü
"main.c(37): error: #137: expression must be a modifiable lvalue" hatası sizde de veriyormu veya veren varmı.?
galiba o satırda source[ i ] =i şeklinde olucak.
arkadaslar, bulent hocamızın kit için verdıgı programlarda. ilk olan debug ile programı satır satır işleten programı denedim çalıştırdım.
2. verdıgı user butonu ile led yakma programını yazıp derledim, debug sayfasına gectıgımde herhagi bir degişim olmuyor kitte. yanı program yüklenmedi sanırım? nereyi atlıyorum? ledler kısık bir şekilde yanık sadece.
debug ettikten sonra run ediyormusunuz.
evet reset atıyorum sonrada run edıyorum programda sorunsuz gorunuyor fakat kartta bi tepki yok ve debug işlemi yaptım esnada bilgi ledi kırmızı yanmaya devm ediyor yeşil olmuyor. ilk programda yeşil oluyordu debug esnasında
debug sayfasında su eklde hata yazıyor;
Load "C:\\Documents and Settings\\emrah\\Desktop\\arm prg\\userled\\user led.AXF"
*** error 65: access violation at 0x0000000C : no 'read' permission
*** error 65: access violation at 0x0000000C : no 'read' permission
hocam run edince while(1) bloğuna girmesi gerekiyo. girmiyor mu. içeri girince if satırında dururken butona basılı tutun f11 e basıp satırı işletin yanması lazım.
options for target dubg ve utilities menülerinde stlink seçili olmalı. onlardan olabilir. settings leri de swd olmalı
evet orayı kontrol ettm. her programda oranın ayarlanacagını bilmiyordum hocam şimdi oldu. sagolun
bişiy değil hocam. benimde gözüme çarptı o. sanki her farklı proje çalıştırınca o ayarlar değişiyor gibi geldi. bir daha denemek lazım değişiyor mu diye.
Her Yeni Projede (New Project) O Ayarların Yapılması gerekir.
öyleymiş hocam şimdi açtım yeni bir proje.
Alıntı yapılan: CoşkuN - 28 Aralık 2011, 10:35:55
İşlemcinin saat frekansı ayarlama işlemleri oldukça karmaşık gibi görünebiliyor başlangıçta. Bu ayarları kolaylıkla yapabilmek için bir araç da varmış, uygulama dökümanıyla birlikte
http://www.st.com/internet/mcu/product/252140.jsp
sayfasında Configuration Utilities bölümünde
"Clock configuration tool for STM32F40x/41x microcontrollers"
benim excelde çalışmadı
Çalışması için excel in macro sunu etkinleştireceksiniz.
2010 yüklü makro vs denedim olmadı. office tekrar yükleyeceğim.
Alıntı yapılan: muhittin_kaplan - 29 Aralık 2011, 15:59:54
2010 yüklü makro vs denedim olmadı. office tekrar yükleyeceğim.
Bende önce makroyu orta düzeyde güvenliğe çek dedi, yaptım. Şimdi de VBA ıvır zıvırını yükle diyor. Ofis CD sini arıyorum.
FLASH->ACR = 0x00000705; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55) Yazmamız gereken asıl kod bu fakat çipte bug var
FLASH->ACR = 0x00000605; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55) Mecburen bunu yazacağız.
bu satırları anlamaya çalıştım anlayamadım.
flash_acr kaydedicisisnin 12,11,10,9,8,7 bitlerinin şamatasını yapabilir misiniz.
data instruction cache nedir?
teşekürler
Yazmaçlara direk değerleri yazayım dedim ama çok uğraştırıyor bu meret, direk kodları verecek bir wizard yapmak şart gibi
ya da sağlam bir structure yapısı kurmak lazım :o
bu kodlar 2 saatimi aldı :(
GPIOA->AFR[0] = 0x55500000;
GPIOA->AFR[1] = 0x600AAAA0;
GPIOB->AFR[0] = 0x77666000;
GPIOB->AFR[1] = 0x55550507;
GPIOC->AFR[0] = 0x00005000;
GPIOC->AFR[1] = 0x000CCCCC;
GPIOD->AFR[0] = 0x00000C00;
GPIOD->AFR[1] = 0x00077077;
GPIOA->MODER = 0xAAA8A800;
GPIOB->MODER = 0xAA61AA95;
GPIOC->MODER = 0x02AA4585;
GPIOD->MODER = 0x569A5165;
GPIOE->MODER = 0x55555550;
Bende yeni incelemeye başladım kartı. GPIOlar için kitleme mekanizması olduğunu söylüyor. Yapılan konfigürasyon reset gelene kadar korunur diyor. Bunun mantığı nedir, yanlışlıkla değiştirmeyi önlemek için mi?
Birde MCO1/MCO2 çıkışlarının kapatamıyor muyuz? Yazmaçlarını incelerken kapatma seçeneğini göremedim. Bu pinlerden sürekli saat çıkışı olmak zorunda mı?
Bülent Hocanın SystemTick örneğinde
#define STK_CTRL (*((volatile unsigned int*) 0xE000E010))
Bir Atama Yapılış.
Önce Burada ne yapılmaya Çalışılmış (Neden Volatile Yapılmış? Neden Pointer Tanımlama Yapılmış? neden int* yapılmış )
Aslında Hepsinden önemlisi 0xE000E010 adresini nereden almış (rehber ve hard a baktım.)
Evet GPIO kilitlendiginde CPU resetleninceye kadar bazi GPIO registerleri bir daha degistilemiyor. Amac, bilincli yada bilincsiz portlari kurcalamayi onlemek.
RTOS yapilasri icin guzel bir ozellik.
Alternate function olarak MCO pinlerini kullanip kullanmamak senin elinde.
Bu konuda asagidaki ornegimize bakabilirsin.
https://www.picproje.org/index.php/topic,35896.msg256592.html#msg256592
Alıntı yapılan: muhittin_kaplan - 01 Ocak 2012, 16:00:34
Bülent Hocanın SystemTick örneğinde
#define STK_CTRL (*((volatile unsigned int*) 0xE000E010))
Bir Atama Yapılış.
Önce Burada ne yapılmaya Çalışılmış (Neden Volatile Yapılmış? Neden Pointer Tanımlama Yapılmış? neden int* yapılmış )
Aslında Hepsinden önemlisi 0xE000E010 adresini nereden almış (rehber ve hard a baktım.)
Aslinda bu atamaya gerek yoktur. Yanlis hatirlamiyorsam System Tick registerlerini mevcut header dosyalarda bulamamistim. Bende arayip bulmak yerine
programin tepesinde tanimlayiverdim.
Peki Bu Adresi nereden Buldunuz Hocam.
ben Kendim Yapmaya çalışsa idim Bulamayacaktım yada örnekten alacaktım ve sorgulayamacaktım
Anladım hocam teşekkür ederim.
Alıntı yapılan: muhittin_kaplan - 01 Ocak 2012, 16:15:18
Peki Bu Adresi nereden Buldunuz Hocam.
ben Kendim Yapmaya çalışsa idim Bulamayacaktım yada örnekten alacaktım ve sorgulayamacaktım
System TICK registerleri istisna registerlerden, bu bir cevre birimi degil CPU cekirdegi registerleri. Dolayisi ile diger firmalarin dokumanlarindan yararlanip buldum. ST ninde dokumani vardir fakat ara ki bulasin.
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
bu nasıl bir tanımlamadır UL neki ?
Bu arada hocam hala stytem tick adresinin ne olduğunu
hocam o "unsigned long" olmasın?
Alıntı yapılan: fryrmnd - 01 Ocak 2012, 21:01:13
hocam o "unsigned long" olmasın?
Aynen öyle. Derleyici optimizasyon ile tanımlanan değeri silip atmasın diye, daha doğrusu bize o değer int olarak lazım olduğu halde derleyici bunu char yada daha düşük boyutlu bir değere çevirmemesi için UL ekleniyor. Aynı şekillde ULL Unsigned Long Long içinde kullanım var.
Core_Cm4.h dosyasının içerisinde geçiyor bunlar. Ssytem tick (st nin verdiği sample) incelerken neredeyse tümünü CMSIS ile yaptıklarını gördüm. karmaşık geldi.
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SysTick CMSIS SysTick
Type definitions for the Cortex-M System Timer Registers
@{
*/
/** \brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439c/BABCIIIA.html
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/Bhccjgga.html
10 dakikayı geçti bakınıyorum ama bunalmış hocamın 32 bit hesaplayıcı hangi başlıktaydı bulamadım. bilen varsa bir zahmet linki verebilir mi?
calc.exe yi bende aradım bulamadım.
http://hotfile.com/dl/139398863/84d000e/Calc.rar.html
hocam teşekkür ederim . masaüstünü toplarken kaybetmişim. bakınıp duruyom yok. görmeyince görmüyor ya.
ok
Evet forumda aradım bende bulamadım google yine buldu alternatif link aşağıda :)
www.cncdesigner.com/STM/Calc.rar
----------------------------------------------------------------------------------
Arkadaşlar
Keil in 4.21 versiyonunda STM32F407VG bulamadım bu ilaçlı olandı yenilerin ilaçlı olanı var mı?
Nihayet biraz boş zaman buldum. Karta örnek program yüklemek istedim. @bunalmıs hocamın son eklediği accelerometer kullanan örneği aldım.
@ bunalmıs Programın aşağıdaki bölümünde dikkatsizlik kaynaklı bir hata var sanırım.
void Write(char Adr,unsigned char Data)
{
GPIOE->BSRRH=0x0008; // LIS302DL CS=0
SPI1->DR=((Adr&0x3F)<<|Data;
while(!(SPI1->SR&2));
GPIOE->BSRRL=0x0008; // LIS302DL CS=1
}
Şu şekilde düzelttim. Derleme hatası almadım ama program çalışmadı.
SPI1->DR registerinin 16 bit olduğunu varsayarak bu değişikliği yaptım.
Datasheet i incelemedim.
void Write(char Adr,unsigned char Data)
{
GPIOE->BSRRH=0x0008; // LIS302DL CS=0
SPI1->DR=((Adr&0x3F)<<8)|Data;
while(!(SPI1->SR&2));
GPIOE->BSRRL=0x0008; // LIS302DL CS=1
}
zakbay cortexm4 sayfalarının (hangisi olduğnu hatırlamıyorum) birinde winamp adında bi ilaç var versiyon 4 . 2 2 için kullandım problem yok aratabilirsin.
5. Sayfa
https://www.picproje.org/index.php/topic,35780.60.html
Klein 8 ve ) yanyana gelince yok oluyor. Bu sorun diğer kodlarda da karşınıza çıkabilir.
Daha önce konuşuldu çözüm olarak gülümseme kullanma kutusunu tıkla dendi fakat unutuyorum.
:) Evet benim da başıma gelmişti. Ben de unutmuşum.
Kodları halen çalıştıramadım.
Debug ediyorum.
Döngüye giriyor. Demekki "Who_Am_I" cevabı geliyor.
Ama "Status" registeri hep 0 döndürüyor. LIS302DL Bozuk olabilir diye diğer kartları denedim. Onlarda da durum aynı.
Bir de debug ederken Hardware monitörden SPI1'i izlemeye aldığımda
while(!(SPI1->SR&1));
döngüsünde takılıp kalıyor. Eğer monitörü kapatırsam döngüyü geçiyor.
Bu durum benim de başıma geldi. Hatta bugün bir arkadaş maille aynı durumdan bahsetmiş.
Kodlarda bazen çalışamama gibi bir sorun var o zaman. Fakat kodları ben çalışıtırdım. Öte yandan bahsettiğiniz sorun aynen başıma gelmişti.
Bu durumda init edilmesi gereken bir değişken vs olabilir. Yada gözden kaçan bir başka durum.
Akşam ben de bakayım.
Biraz daha kurcaladım.
SPI CTRL1 registerine yazamıyor.
Write kodunu adım adım işletirsem yazma gerçekleşiyor. Sonrasında sorun yok.
Ekleme:
Kodu aşağıdaki şekilde düzeltince halloldu.
SPI TX Empity bayrağı muhtemelen TX bitince değil , Data donanıma gönderilince çekiliyor. Bu yüzden Gönderme daha tamamlanmadan okuma yaptığımız için sorun oluyor. TX Empity yerine BSY bayrağını kontrol edersek sorun yok.
void Write(char Adr,unsigned char Data)
{
GPIOE->BSRRH=0x0008; // LIS302DL CS=0
SPI1->DR=(unsigned short) (((Adr&0x3F)<<8 )|Data);
while(!(SPI1->SR&0x80));
GPIOE->BSRRL=0x0008; // LIS302DL CS=1
}
Malesef düzeldiğini sanmıştım ama düzelmemiş. Kartın enerjisini kesmeyi unuttuğum için register değeri saklı kalmış.
[/color]
Ancak bu şekilde çözüm bulabildim. Neden haberleşmenin bitmesini beklemiyor anlamış değilim. Datasheet'e gömülmek gerekecek sanırım.
void delay(unsigned int time){
while(time--);
}
void Write(char Adr,unsigned char Data)
{
GPIOE->BSRRH=0x0008; // LIS302DL CS=0
SPI1->DR= (unsigned short)(((Adr&0x3F)<<8)|Data);
while(!(SPI1->SR&2 ));
delay(10000);
GPIOE->BSRRL=0x0008; // LIS302DL CS=1
}
vs1003 ile uğraşırken bu soruna bende denk geldim
çözüm alma işleminin bitmesini beklemek, kullandığım kod;
void putc_spi2(unsigned char c){
while(!(SPI2->SR&0x02));
SPI2->DR=c;
while(!(SPI2->SR&0x01));
c=SPI2->DR; /* OVR hatası almamak için gelen bilgiyyi oku*/
}
unsigned char getc_spi2(unsigned char c){
while(!(SPI2->SR&0x02));
SPI2->DR=c;
while(!(SPI2->SR&0x01));
return SPI2->DR;
}
Problemin kaynagi oldukca basitmis ama kok sokturdu.
TXE flagi, Transmit bitti değil, TxBuffer bosaldi anlamina geliyor. Programda, bufferin bosaldigini gorur gormez cipi, CE bacagindan pasif hale getiriyoruz. Halbuki bu esnada Tx Bufferdaki bilgi shift registere alinmis ve yollanmaya baslamisti. CE pasif edilince o anda gonderilmekte olan veri yarida kesilmis daha acik ifadeyle transmit islemi iptal edilmis oluyor.
TXE ye değil BSY flagina bakmaliydik. Write rutinini asagidaki gibi duzeltirseniz sorun kalmayacak.
TXE flagi, makineli tufek gibi ardarda veri yollarken ise yarar.
void Write(char Adr,unsigned char Data)
{
GPIOE->BSRRH=0x0008; // LIS302DL CS=0
SPI1->DR=((Adr&0x3F)<< 8) |Data;
while(SPI1->SR&0x40);
GPIOE->BSRRL=0x0008; // LIS302DL CS=1
}
TXE ile BSY arasindaki farki gormek icin blok semada timing diagrama bakin Rehber 672.
Peki bu hatali kodu neden ornek programlara ekledim?
Yazdigim kodlari isletirken aslinda bir tuhaflik vardi. Kodlar uzerinde ufak degisiklikler yapip debug ettigime daha acik ifade ile F11 ile adim adim yuruttugumde
kodlar calisti. Aslinda SPI a data yukleyen satiri F11 ile yuruttugumde bir alt satirdaki TXE flagi setmi diye ikinci kez F11 e bastigimda data coktan gitmis oluyordu.
F5 ile kodu kosturunca da program dogru calisiyor gorunuyordu. Bende kodun duzene girdigini dusunup yayinladim.
Program bir kez calistiktan sonra karti reset butonu ile resetlesem bile MEMS cipi resetlenmediginden bufferina yazilmis olan veri. daha sonraki yazma cabalarimizla
degismediginden (cunku programin yazma rutini hatali) daha sonraki F5 (run) islemi kodlarin duzgun calistigi yanilgisina neden oluyordu. Halbuki karti resetlemek
yerine kartin usb kablosunu sokup taksaydim kodlarda hata oldugunu anlayacaktim.
Aslini sorarsaniz programdaki bu mantik hatasi guzel bir ornek oldu.
Dün BSY bayrağına bakmıştım. Hatta BSY bayrağına bakınca sorun düzeldi diye yazdım. Ama sonra sorunun düzelmediğini görüp yazdıklarımın üzerine çizik atmıştım. BSY bayrağı bende neden sorunu çözmedi bir bakayım.
Alıntı YapEkleme:
Kodu aşağıdaki şekilde düzeltince halloldu.
SPI TX Empity bayrağı muhtemelen TX bitince değil , Data donanıma gönderilince çekiliyor. Bu yüzden Gönderme daha tamamlanmadan okuma yaptığımız için sorun oluyor. TX Empity yerine BSY bayrağını kontrol edersek sorun yok.
Ekleme:
Son kodunuzda BSY bayrağına değil OVR bayrağına bakmışsınız hocam.
İkinci ekleme:
BSY bayrağı ile tekrar denedim malesef sorun halen düzelmedi.
Sizin kodunuzdaki gibi OVR bayrağını da denedim yine olmadı.
Sorunun TX bitmeden çipi pasif yapmak olduğu kesin. Ama BSY neden çözemedi anlamadım.
Evet 0x40 yerine 0x80 olmalıydı yanlış yazmışım. Fakat işin kötüsü kodda da 0x40 yazdım. Bu durumda kodda 0x80 yazıp tekrar denemek gerekiyor. OVR flağına bakmışım. Program 0x40 ile çalışıyor olsa da bu kabul edilir bir çözüm değil. Çünkü tek write yaptığımız için sorunsuz çalışıyor.
Kötü olan şu ki; Bende OVR bayrağına bakmak da bir çözüm getirmedi. Aynı şekilde BSY de işe yaramıyor.
İlginç bir şey dün gece defalarca denediğim kod şimdi çalışmıyor. Üstelik her defasında kartın enerjisinide kesiyordum.
Yalnız işyerinde kodları buradaki sayfadan copy past ile aldım. Acaba gene kodlarda bazı karakterler mi uçtu. Evdeki kodu tekrar denemem gerekecek.
Hocam reference manual sayfa 665 Receive sequence bölümüne bakarak yukarıdaki kodu eklemiştim
ayrıda sayfa 672 deki figure 248 de bakarsanız daha net görülüyor ama 16 bit aktarım için durum nasıl tam incelemedim
hatta 1.kenar 2.kenar farkı gözetmeksizin kullanmak için kodu şu şekilde değiştirirsek tam olacak gibi
void putc_spi2(unsigned char c){
while(!(SPI2->SR&0x02));
SPI2->DR=c;
while(!(SPI2->SR&0x01));
while(SPI2->SR&0x01);
c=SPI2->DR; /* OVR hatası almamak için gelen bilgiyi oku*/
}
Alıntı yapılan: ErsinErce - 05 Ocak 2012, 17:42:07
hatta 1.kenar 2.kenar farkı gözetmeksizin kullanmak için kodu şu şekilde değiştirirsek tam olacak gibi
void putc_spi2(unsigned char c){
while(!(SPI2->SR&0x02));
SPI2->DR=c;
while(!(SPI2->SR&0x01));
while(SPI2->SR&0x01);
c=SPI2->DR; /* OVR hatası almamak için gelen bilgiyi oku*/
}
Buradaki sorun şu:
SR&0x01 Status 0. biti. Bu bit de RX bayrağı. Tx döngüsünün sonunu beklemek için RX bayrağını okumak bana anlamlı gelmedi.
Diğer sorun ise :
kodun başında TX_Empity bayrağını okumak. TX tamponu boş ama SPI RX durumundaysa bu bayrak çekilir alttaki kodlar işletilir. Kaldı ki Veri TX donanımına gönderilir gönderilmez bu bayrak çekiliyor zaten.
Bir başka mesele de peşpeşe yapılan RXNE kontrolü.
while(!(SPI2->SR&0x01));
while(SPI2->SR&0x01);
Diyelim ki program ilk satırda biraz bekledi.
RXNE 1 oldu ve döngüden çıkıldı.
Peşindeki döngü RXNE 1 olduğu sürece işletilir. Bizim RXNE bayrağımız 1 olduğuna göre program burada takılır kalır.
hocam numarasını verdiğim şekile bakarsanız bu bayrak normalde 0 son bit alınırken 1 olup daha sonra tekrar 0 oluyor
gönderim sırasında alma bayrağını kontrol etmek spi için mantıklı çünkü çift yönlü alışveriş söz konusu ve master olarak saat darbesini biz çıkartıyoruz
şuan vs1003 sorunsuz bir şekilde çalışıyor, yaklaşık 20K veri yolluyorum
debug yaparken o satırları atlatmak lazım tabi
Okurken tamam. ama yaz dediğimizde karşıdaki adam bize yazdım ya da yazdığım veri şu gibi bir bilgi göndermiyor ki. Bu yüzden yazma sonunda RX bayrağını kontrol etmek anlamsız.
Böyle düşünüyor olmama rağmen yine de kodunu denedim. düşündüğüm gibi
while(!(SPI1->SR&0x1));
while((SPI1->SR&0x1));
ikinci while satırında takıldı kaldı.
Ekleme :
İkinci while satırını kaldırınca kod çalışıyor. Hem de çalışması gerektiği gibi. Ama yine de aklıma yatmadı.
REF Manuel'e göre BSY bayrağı ile RXNE bayrağı aynı anda çekiliyor. Bu durumda RXNE ile çalışıp BSY ile çalışmaması çok saçma.
Ya da Manuel'de banim kaçırdığım birşey var.
karşıdan gelen anlamlı bir veri olmasa bile bu bit 8.bit okunduğunda(yazılma tamamlandığında) (8.clock gönderildiğinde)aktif oluyor
BSY NSS bitine göre hareket ediyor olabilir Chip Select işini donanıma bırakmadığımızdan bu bitini kontrol etmek sorun çıkartıyor olabilir
bende de 2 while çalışmıyormuş program atamamışım pardon =/
tek while ile düzgün çalışıyor
hocam affınıza sığınarak SPI hakkında bir açıklama yapmak istiyorum
SPI da yazma veya okuma diye bir kavram yok aslında yazmaçların aktarımı söz konusu
her clk darbesinde bitler bir yazmaçtan diğerine aktarılıyor, bu yüzden okuma işlemi tamamlandığında veri aktarımı tamamlanmıştır diyorum
(http://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/SPI_8-bit_circular_transfer.svg/500px-SPI_8-bit_circular_transfer.svg.png)
Ek: 16 bit modunda 16.bitte mi aktif oluyor birazdan test edeceğim
Sayfa 678'de BSY bayrağının kullanılması ile ilgili kuralları açıklamış. Her iletişimde kullanmayın TXE ve RXNE bayrağını kullanın diye de not düşmüş.
Bu programdaki kullanım şekli anlatılan prosödüre aykırı değil ama yine de olmuyor.
@ErsinErce
Evet MOSI/MISO döngüsüne dikkat etmemiştim. RXE kullanmak mantıklı görünüyor. Zaten SPI1'i monitör ettiğimde bariz biçinde değişen tek bayrağın RXE olduğu görülüyor.
RXNE SPIx->DR yi okuma ile sıfırlanıyormuş, 2.while da çakılma sebebimizi de öğrendim,
BSY sürekli veri aktarımında hep aktif olduğundan dediğiniz gibi kullanımı sakıncalı hocam
BSY'i ancak ayarladığımız clk frekansının bitiminde kontrol edersek işimize yarar olduğundan işimize pek yaramıyor
ayrıca not düşelim Full dublex çalışırken bu bayrakları kontrol etmek lazım, sadece gönderim ya da sadece alım yapacaksak (o şekilde ayarladıysak)
sayfa 679daki SPI Disable anlatımına dikkat etmek lazım tabi SPI'ı kapatma kısmını yapmadan ;)
16 bit olayını test edemedim malesef gölge registerlar kullanıldığından dışardan gözlemlemek gerekecek galiba
Iki gundur baska isler nedeniyle sabahliyorum ve kafami toplayip soruna tam egilemedim. SPI init den itibaren tum register atamalarina tekrardan bakmak gerekecek.
Rehberde BSY flagini surekli test etmekten kacinin once TXE ye bakin soonra busy ye bakin gibisinden uyari gordum.
Hocam kodlarınızı inceliyordum da kafama takılan anlayamadıgım bir yer var.
İzah edebilirmisiniz.
GPIOE->BSRRH=0x0008; // LIS302DL CS=0
Hocam burda E portunun 3. bitini High (Set) yapması gerekmiyormu. Sizin acıklamanızda 0 (sıfır) oldugunu yazmıssınız.
GPIOE->BSRRL=0x0008; // LIS302DL CS=1
Hocam burda E portunun 3. bitini High (Low) yapması gerekmiyormu. Sizin acıklamanızda 1 (High) oldugunu yazmıssınız.
BSRRH: GPIOx port bit set/reset high register
BSRRL : GPIOx port bit set/reset low register
Bu registerin calışma mantıgı nasıl?
Teşekkürler
bende inceledim.
Orada CS0 yada CS1 yazmasının sebebi 32f400 e bağlı olan ivmeölçerin CS girişinin değiştirilmesidir.
O giriş ile
0 da I2C 1 ile SPI mode seçiliyormuş.
Bunalmış Hocam neden ivmeölçerin SPI/I2C seçimini değiştiriyoruz ? Devamlı SPI da kalsa ?
Buradaki H ve L lojik Hi ve lojik Lo ifade etmiyor.
BSRR registeri 32 bitlik kaydedici. H üst 16 bitlik bölümü L de düşük 16 bitlik bölümü ifade ediyor.
BSRRL'nin bir bitini set ettiğinizde o portun ilgili pini Set ediliyor.
aynı şekilde BSRRH nin bitini set edince port Reset oluyor.
yok denemediğim kalmadı.
Rehber 679 da Disable SPI da bazı sıralamalar vermiş. Denedim Olmadı.
Yine Debug da Çalışıyor ama Enerjiyi kesip tekrar verdiğimde çalışmıyor.
Alıntı yapılan: muhittin_kaplan - 06 Ocak 2012, 00:39:49
Bunalmış Hocam neden ivmeölçerin SPI/I2C seçimini değiştiriyoruz ? Devamlı SPI da kalsa ?
O pin hem I2C seçimihem de SPI CS pini. eğer aynı hatta birden fazla SPI aygıt varsa okuma/yazma yapmak istediğimiz çipi aktif etmek için CS pinini Low yapmamız gerekiyor. Aynı zamanda CS pinini HI yaptığımızda çipin haberleşmesini de resetlemiş oluyoruz. Eğer CS hep aktif kalırsa
çip sürekli veri okunacak veya yazılacakmış gibi davranıp bizim verdiğimiz adres dizisini register adresi gibi kabul edebilir.
Ama akselerometre çipinde hem I2C hem de SPI olduğu için adam pin sayısından kazanmak için o pini hem SPI CS hem de I2C seçim pini olarak tasarlamış.
Alıntı yapılan: muhittin_kaplan - 06 Ocak 2012, 02:12:35
yok denemediğim kalmadı.
Rehber 679 da Disable SPI da bazı sıralamalar vermiş. Denedim Olmadı.
Yine Debug da Çalışıyor ama Enerjiyi kesip tekrar verdiğimde çalışmıyor.
Şimdi denedim bir sorun yok. SPI disable yapınca SPI çalışmayı durduruyor. son okudupumuz veri ne ise ledler o şekilde kalıyor.
void SPI_Disable(void){
while(!(SPI1->SR&0x01));
while(!(SPI1->SR&0x02));
while((SPI1->SR&0x80));
SPI1->CR1=0x00000B3F;
}
int main()
{
int i;
modsel();
if(Read(0x0F)==0x3B) // Who are you ?
{
Write(0x20,0x47); // Data Rate=100Hz, Full Scale=2g, Activate, x,y,z enable
while(1)
{
who=Read(0x27); // Statusu ogrenelim. Kim hazir kim de?il?
if (who&1)
{
x=(Read(0x29)+xo);
xo=x>>1;
if (x>=0) PWM[0]=x;
else PWM[2]=-x;
}
if (who&2)
{
y=Read(0x2B)+yo;
yo=y>>1;
if (y>=0) PWM[1]=y;
else PWM[3]=-y;
}
if (who&4)
{
z=Read(0x2D);
}
SPI_Disable(); }
}
//TIM7->DIER=0x0000; // Update Int disable
while(1)
{
for(i=0;i<0x100;i++);
GPIOD->ODR^=0x0000F000;
}
}
Nihayet istedigim gibi oldu.
char SPI_CMD(short DAT)
{
char RxDat;
GPIOE->BSRRH=0x0008; // LIS302DL CS=0
RxDat=SPI1->SR; // AMAC DELAY (kalmasinda fayda var)
SPI1->DR=DAT; // Komutu yukle
while(!(SPI1->SR&0x01)); // RX BUF bos ise beklemede kal
while(SPI1->SR&0x80); // BSY durumu varsa kalkmasini bekleyelim
RxDat=SPI1->DR; // Cipten gelen veriyi oku
while(SPI1->SR!=0x02); // CS=1 yapmadan once cipin orjinal duruma donmeyi bekleyelim
GPIOE->BSRRL=0x0008; // LIS302DL CS=1
return(RxDat);
}
char Write(char Adr,unsigned char Data)
{
return(SPI_CMD(((Adr&0x3F)<< 8 )|Data));
}
char Read(char Adr)
{
return(SPI_CMD(((Adr&0x3F)|0x80)<< 8 ));
}
bekleme için TXE yi kontrol etseydiniz daha "cool" gözükürdü hocam kimse silmek istemezdi, ister istemez elim delete'e doğru gidiyor =)
RXBUF bos flagini bekleme kismini diyorsan;
Gonderilen dataya karsilik shift register yapisindan dolayi ayni cercevede data geliyor zaten.
RXNE flaginin set edilmesi TXE flaginin degisiminden daha sonra gerceklestigi icin bu ve benzeri uygulamalar icin TXE flagini kontrol etmenin gereksizligine karar verdim.
Ornek program kismindaki uygulamayi da duzelttim. Zaten PWM degerlerini olusturmayla ilgili hata varmis.
(Biz cipten veri okumak da istesek yazmak da istesek her durumda zaten cipten veri aliyoruz. Yazma asamasinda 0xFF aliyoruz baska mesele.)
yok hocam, aşağıdaki kısım için demiştim, biraz şamata olsun diye =)
RxDat=SPI1->SR; // AMAC DELAY (kalmasinda fayda var)
Anladim, o satir kaldirilsa da sorun yok, 5ns lik pay birakmak gerekiyor. 168Mhz de calisirken bu kodu kaldirirsak limite yakin kaliyoruz bu yuzden fantazi olsun istedim.
Bir registeri okuyacak fakat okunan degeri kullanmayacaksak, degisken icine okuma yapmadan bu isin yakisikli bir cozumu varmi?
O delay satirinda RxDat gibi bir degisken ismi bana da gicik geliyor. Sirf anlamli olsun diye de ikinci bir degisken tanimlamak istemedim.
Yada RxDat yerine Yazboz kullansam daha hos olurdu.
nasılsa dallanırken girişe ayrı bir register olarak ayrılıyor diye giren değişkenin işi bitince üzerine yazıyorum boş işler için,
ama bu durum için __NOP(); yakışıklı durabilir hocam
çalışan durumun keyfini çıkartmak bu olsa gerek =))
Hocam Hatanın sebebi ve Çözümünde neler yapıldığını yazabilirmisiniz ?
Programdaki kurguya göre;
MEMS çipine veri yollamak için, SPI modülünün CS pinini low yapıyor daha sonra SPI data registerine verimizi yazıyor ve ardından transferin tamamlanmasını bekliyoruz en sonunda da CS pinini tekrardan high yapıyoruz.
Hatalı programda transferin tamamlamadan CS pinini high yapıyordum. (Daha doğrusu transferin tamamlanıp tamamlanmadığını sadece TXE flağına bakarak yapıyordum.) Bu hatalı programı daha önceki mesajları geriye doğru tarayarak ulaşabilirsin.
Sözkonusu hata, kodlar debug menüde F11 ile adım adım koşturulurken oluşmuyor. (Çünkü klavyeyi parmaklama süremiz SPI ın data yolla süresinden çok uzun. CS pinini high yaptığımızda datamız çokdan MEMS çipine gidiyordu)
Sorun ortaya çıkınca transferin tamamlandığından emin olmak için REHBER de SPI status register bitleri ilgili açıklamalar okundu. Zaten SPI bölümünü baştan itibaren okumaya başlarsan nelere dikkat edilmesi gerektiği anlatılıyor.
/**
* @brief Sends a Byte through the SPI interface and return the Byte received
* from the SPI bus.
* @param Byte : Byte send.
* @retval The received byte value
*/
static uint8_t LIS302DL_SendByte(uint8_t byte)
{
/* Loop while DR register in not emplty */
LIS302DLTimeout = LIS302DL_FLAG_TIMEOUT;
while (SPI_I2S_GetFlagStatus(LIS302DL_SPI, SPI_I2S_FLAG_TXE) == RESET)
{
if((LIS302DLTimeout--) == 0) return LIS302DL_TIMEOUT_UserCallback();
}
/* Send a Byte through the SPI peripheral */
SPI_I2S_SendData(LIS302DL_SPI, byte);
/* Wait to receive a Byte */
LIS302DLTimeout = LIS302DL_FLAG_TIMEOUT;
while (SPI_I2S_GetFlagStatus(LIS302DL_SPI, SPI_I2S_FLAG_RXNE) == RESET)
{
if((LIS302DLTimeout--) == 0) return LIS302DL_TIMEOUT_UserCallback();
}
/* Return the Byte read from the SPI bus */
return (uint8_t)SPI_I2S_ReceiveData(LIS302DL_SPI);
}
STnin örnek kodunda öncelikle TXE'nin boşalması beklenmiş, sonra veri gönderilmiş, daha sonra rxne'nin set olması beklenmiş. belki bir ipucu verebilir...
DAC ları çalıştıramıyorum.
yaptığım ara kablo ile pc nn mic ine giriş yaptım.
Ben line girisine bagliyorum. Ornek kodlari deneyeceksen sinyali PA4 pininden alacaksin.
jack a bağlamayacak mıyım ?
Hayir. Bahsettigin jak kulaklik sesle ilgili ozel cipimize bagli. Audio DAC diye geciyor. Bu asamada o cipi register bazinda cozmek zaman alici. Ornek program bolumundeki kodlar bu DAC'i degil ARM cipin icindeki DAC'i kullaniyor. PA4 pinine 1uf kapasitor bagla ve buradan sinyali al.
a=x[0];
b=Read(0x29)-xo;
for(i=15;i>0;i--){ x[i]=x[i-1]; a+=(signed short)x[i];}
x[0]=b; a=a>>2;
arkadaşlar bu kısmı açıklayabilir misiniz (kartın eğim programının).
benim ilk aklıma gelen; a=read(0x29) deyip a nın eksi veya artı oluşuna göre PWM[0] ve PWM[2] yi atamak olurdu?
yukardaki kodu yorumlayamadım.
teşekürler...
Bülent Hocam PWM okumam Gerek. Bir yol haritası Çizermisiniz benim İçin ?
Alıntı YapPWM input mode
This mode is a particular case of input capture mode. The procedure is the same except:
● Two ICx signals are mapped on the same TIx input.
● These 2 ICx signals are active on edges with opposite polarity.
● One of the two TIxFP signals is selected as trigger input and the slave mode controller
is configured in reset mode.
For example, you can measure the period (in TIMx_CCR1 register) and the duty cycle (in
TIMx_CCR2 register) of the PWM applied on TI1 using the following procedure (depending
on CK_INT frequency and prescaler value):
● Select the active input for TIMx_CCR1: write the CC1S bits to 01 in the TIMx_CCMR1
register (TI1 selected).
● Select the active polarity for TI1FP1 (used both for capture in TIMx_CCR1 and counter
clear): write the CC1P and CC1NP bits to '0' (active on rising edge).
● Select the active input for TIMx_CCR2: write the CC2S bits to 10 in the TIMx_CCMR1
register (TI1 selected).
● Select the active polarity for TI1FP2 (used for capture in TIMx_CCR2): write the CC2P
and CC2NP bits to '1' (active on falling edge).
● Select the valid trigger input: write the TS bits to 101 in the TIMx_SMCR register
(TI1FP1 selected).
● Configure the slave mode controller in reset mode: write the SMS bits to 100 in the
TIMx_SMCR register.
● Enable the captures: write the CC1E and CC2E bits to '1' in the TIMx_CCER register.
Ne Demek İstiyor Yardım Edermisiniz ?
Rehber Sayfa 312
hocam tam çözemedim. TI1 e girilen bir PWM nin hem periyodunu hem de darbe genişliğini ölçüyor. biri için PWM nin düşen kenarında counter ı reset ediyor diğeri için yükselen kenarda sanırım. bu şekilde her resette counter içeriğini alıp hesaplama yapmak gerekiyor sanırım. şimdilik anladığım bu. bana karışık geliyor. tam anlasam bile hesaplamaları koda dökmem sıkıntı. hocam acilse birde PWM ölçüm örneği var st nin .
Reg. lere Bakıyorum Şimdi.
Acil Değil. Öğreneyim Sonra Deneyeceğim
Örnek bir PWM input konfigürasyonu vermiş.
Eğer sen hem periyot hem duty-cycle ölçeceksen TI1 için aşağıda açıklanan adımları uygula. Ama saati , bölücüyü vs.. ayarladıktan sonra.
1-Önce CC1S Bitlerine 01 yazarak aktif giriş olaratk TI1 seç.
2-CC1P ve CC1NP bitlrine 0 yazarak hem IC1 in yakalayacağı hem de sayıcının resetedileceği kenarı yükselen yap.
3-CC2S bitlerini 10 yaparak IC2 için kaynak olarak TI1'i seç
4-CC2P ve CC2NP bitlerini 1 yap ki IC2 yakalayacağı kenar düşen kenar olsun.
5-TS bitlerini 101 yap ki Timer tetiklemesi için TI1'i kullanacağımız belli olsun.
6-SMS bitlerini 100 yap. sayıcı yükselen kenarda sıfırlansın.
7-CC1E ve CC2E bitlerini açarak yakalamayı başlat.
yakalama
TI1 yükselirken hem IC1 sayıcı değerini yakaladı ce CCR1'e attı hem de sayıcı sıfırlandı.
darbe bir süre HI devam etti sonra düştü. Tam bu anda IC2 değeri yakaladı ve CCR2'ye attı. darbe biraz daha LO devam etti tekrar yükseldi. Bu anda IC1 değeri yakaladı ve CCR1'e attı. periyodu CCR1'den Duty'i de CCR2'den okudun.
Hem Duty Hem Period Ölçeceğim. Registerleri inceliyorum verilen basamaklara göre.
Bu işlem Bir kanal için geçerli. 7-8 adet Pwm i okumam gerekirse nasıl bir yol izlemeliyim ?
Eğer 8 tane timer varsa ve hepsi de IC destekli ise, bütün zamanlayıcıların register yapısı aynı. TI! için yaptığın işlemlerin aynısını diğerleri için de yaparsın.
Pwm frekansi ve cozunurluk nedir?
Bu arada C ile yeni tanisan arkadaslarin kartlariyla aralari nasil?
Denemeler yapmaya basladinizmi?
Basit test programlari yazmaya basladinizmi?
Hocam bu Usart'daki Oversampling olayı nedir?
bir de bu fraction hesaplama da ben sizinkinden farklı buldum, bir yerde hatamı yapıyorum?
bus hızı/ ( 8 * ( 2 - oversamplingdeğeri ) * baud )
42000000/(16*9600)=273.4375
mantissa = 273 = 0x111
virgüllükısım*8*(1+oversamplingdeğeri) // oversampling 0 ise 0-7 arası değer alıyor değilse 0-15
fraction = 0.4375*8 = 3.5=~0x4
yani BRR=0x1114; sizinki 0x1112
Alıntı yapılan: bunalmis - 10 Ocak 2012, 02:29:23
Bu arada C ile yeni tanisan arkadaslarin kartlariyla aralari nasil?
Denemeler yapmaya basladinizmi?
Basit test programlari yazmaya basladinizmi?
kit odamın baş köşesinde kutusuyla beraber duruyor, şimdilik kiti yormak istemiyorum :)
şaka bi yana iş yoğunluğundan fırsat bulupda kurcalayamadim daha :(
Alıntı yapılan: ErsinErce - 10 Ocak 2012, 05:01:25
Hocam bu Usart'daki Oversampling olayı nedir?
bir de bu fraction hesaplama da ben sizinkinden farklı buldum, bir yerde hatamı yapıyorum?
Belki de hesaplamada ben hata yapmisimdir. Gun icinde kontrol edeyim.
Bizim cipdeki oversampling de sanirim anlatacagimla ayni anlama geliyordur;
Bir sinyal hattina gereken min sample sayisinin cok daha ustunde de sample alarak bakilabilir. Bu, gurultunun yogun oldugu durumlarda sinyali gurultuden ayirt etmeyi saglar.
Ornegin 16 kez oversapmle yapildiysa ve sinyal 6 kez 0 10 kez de 1 okundu ise bu sinyal 1 dir seklinde yorumlanir.
Arkadaşlar DMA ile bir çalışmam olmadı hiç. Kafamda şekillendirmeye çalışıyorum. Örneğin ADC'yi DMA ile çalıştırmak istiyorum. Bunun hikayesini kısaca anlatabilirseniz çok sevinirim.
Mesele DMA için ram de yermi ayrılıyor. bunun boyutunu bizmi belirliyoruz ? adc den n adet veri içinmi çalışıyor adc , yada DMA buffer dolana kadarmı okuyor ?
Alıntı yapılan: bunalmis - 10 Ocak 2012, 02:06:32
Pwm frekansi ve cozunurluk nedir?
RC Servo için kullanacağım
Alıntı yapılan: bunalmis - 10 Ocak 2012, 10:25:50
Bizim cipdeki oversampling de sanirim anlatacagimla ayni anlama geliyordur;
Bir sinyal hattina gereken min sample sayisinin cok daha ustunde de sample alarak bakilabilir. Bu, gurultunun yogun oldugu durumlarda sinyali gurultuden ayirt etmeyi saglar.
Ornegin 16 kez oversapmle yapildiysa ve sinyal 6 kez 0 10 kez de 1 okundu ise bu sinyal 1 dir seklinde yorumlanir.
dediğiniz gibiymiş hocam, Reference manual sf 617'de koşulları da detaylı açıklamışlar, bir bit için 8 veya 16 örnek alarak sonuç çıkartmaya yarıyormuş,
Teşekkür ettim =)
Alıntı yapılan: muhittin_kaplan - 10 Ocak 2012, 13:40:44
RC Servo için kullanacağım
O zaman işin çok kolay.
Timeri 100 mikrosaniyede int üretecek şekilde kur.
Interrupt rutininde tüm PWM giriş pinlerinin konumunu okusun girişlerden 1 olanların H_Count değerini 1 artırsın. 0 olanlar için de L_Count değerini 1 artırsın..... Girişin 1 den 0 a yada 0 dan 1 e geçişi durumunda Count değerlerini sağklar ve Count değerlerini sıfırlarsın.
H_Count ve L_Count değerleri sana aradığın PWM değerlerini verecektir.
//////////////////////////////////////////////
// //
// BU PROJEDE En Az 6 Kanaldan PWM okunacak.//
// //
// //
//////////////////////////////////////////////
#include "STM32F4xx.h"
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
void TIM7_IRQHandler()
{
volatile short i;
static char LedFlag=0;
TIM7->SR=0; // Timer Int Flagy silelim
LedFlag=(LedFlag+1)&1;
if (LedFlag) GPIOD->ODR= 0x0000F000; // Ledler yansin
else GPIOD->ODR= 0x00000000; // Ledler sonsun
}
int main()
{
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =2100; // Prescaler değerimiz 8000, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) = 84000000 / (8000) = 2000 Hz
TIM7->ARR =0; // Counter, Decimal 1 olunca basa donsun 10khz demek
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
while(1)
{
}
}
// Programin sonu
Hocam Yukardaki Kodda TIM7 Frekansı kaç olur ?
hocam bu sanırım bunalmış hocam ayarlar. 84 Mhz gözüküyor.
Yok Hocam 20Khz şimdi. Yanlız 42Mhz gibi oluyor APB1 2 katı olması gerekmiyormydu ?
hocam bentimer 7 ye giden clock frekansını demiştim. hocam prescaler e 2100 vermişsiniz. burdan counter frekansı = 84E6/(2100+1) yapar
o da yaklaşık 40kHz yapar. da ARR yi "0" yapmışsınız. tam olarak ne ayarlamak istemiştiniz?
Bunalmış Hocam Şu Timerların Kurulması ile alakalı bir ders tekrarı yapmamız gerek sanırım.
Örneğin
TIMx_ARR ne yapıyor ?
Yapmak İstediğim 100us lik bir kesme oluşturmak. oluşturdum ama hesaplamada sıkıntı var.
hocam ARR değeri timer ın sayacağı ve o değere ulaşınca kesme oluşacağı değer. şimdi sizin 2100(2099 yapalım. +1 ile 2100 olucak) ve ARR ye yükleyceğiniz değer ile ne kadar sürede kesme oluşacağı belirleniyor.
2100 için 40Khz hesapladık.
ARR ye 40000 değeri verirseniz 1 sn de bir kesme oluşur. yani timer 1sn de 40000 sayım yapar ve ARR değerine ulaştım der kesme oluşur. benim anladığım bu.
Anlamadığım Nokta Şu, Sayıcıyı Başlattğımızda ve esme luştuğunda Auto Reload değeri ARR reg atıyor. Bunalmış Hoca Buna
Alıntı YapCounter, Decimal ...... olunca basa donsun ..... demek
Demiş.
ARR reg Ulaşılacak Değer mi ki Böyle bir cümle kurmuş ?
int main()
{
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =42000; // Prescaler değerimiz 8000, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) = 84000000 / (8000) = 2000 Hz
[b] TIM7->ARR =1; [/b] // Counter, Decimal 0 olunca basa donsun 10khz demek
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
while(1)
ile 1khz
int main()
{
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =42000; // Prescaler değerimiz 8000, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) = 84000000 / (8000) = 2000 Hz
[b] TIM7->ARR =1000; [/b] // Counter, Decimal 0 olunca basa donsun 10khz demek
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
while(1)
{
}
}
1Hz
hocam galiba ARR ye timer ı başlatmadan değer yazıyoruz.
Alıntı YapCounting mode
The counter counts from 0 to the auto-reload value (contents of the TIMx_ARR register),
then restarts from 0 and generates a counter overflow event.
An update event can be generate at each counter overflow or by setting the UG bit in the
TIMx_EGR register (by software or by using the slave mode controller).
The UEV event can be disabled by software by setting the UDIS bit in the TIMx_CR1
rehber 458. timer buna ulaşınca taşma oluyor.
edit: değer atamalarınız doğru hocam 1Hz ve 1KHz için. birde (42000-1) yapın.
Lojik Analizörle kontrol ediyorum.
int main()
{
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =4200; // Prescaler değerimiz 4200, Count frekansimiz = (42000000 / 4200) / Arr =10Khz (100us)
TIM7->ARR =1; // Counter, Decimal 0 olunca basa donsun 10khz demek
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
while(1)
{
}
}
10khz
Bunalmis hocam bu apbh1 hatti 84 mhz olmayacakmi
Eğer APB prescaler 1 değilse Timerlar bağlı oluğu APB BUS frekansından 2 kat yüksek frekansla saydırılır.
Daha önce kullandığımız bir kod örneği aşağıda.
int main()
{
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =42000-1; // Count frekansimiz = fCK_PSC / (Yuklenen Deger - 1) 84E6 / (42000-1) = 2000 Hz
TIM7->ARR =1000; // Counter, Decimal 1000 olunca basa donsun 0.5 sn demek
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
while(1)
{
}
}
Bir eksiği konusuna dikkat etmek lazım. Bizim yaptığımız uygulamalarda bir ekiğine bölmemekle çok büyük bir hata yapmış olmuyoruz.
84E6 / (42000-1) yaklaşık olarak 84E6 / (42000) e eşit.
hocam yukarda verdiğim kodlarda nedense 42mhz çalıştırıyor.
10khz lik örnekte 4200 e bölüyorum. 10 000 e eşit ve automatik reload registerine 1 yüklüyorum. sonuçta 10khz lik bir sinyal oluşuyor. eğer bu bus hattı 84mhz olsaydı 20khz olmazmıydı ?
hoca kelimesi yanlış yazıldığından hocam kelimesiyle değiştirildi
Autoreload degerin n olursa n'e mi bölüyor? n+1 e mi?
hesaplarıma göre N e bölüyor.
ama bus hızı neden ikiye katlanmıyor ?
Kafam Allak Bullak Oldu n+1 e bölme ihtimali de var.
Öyle zaten.
Şimdi Hocam;
#include "STM32F4xx.h"
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
void TIM7_IRQHandler()
{
volatile short i;
static char LedFlag=0;
TIM7->SR=0; // Timer Int Flagy silelim
LedFlag=(LedFlag+1)&1;
if (LedFlag) GPIOD->ODR= 0x0000F000; // Ledler yansin
else GPIOD->ODR= 0x00000000; // Ledler sonsun
}
int main()
{
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =4200; // Prescaler değerimiz 8000, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) = 84000000 / (8000) = 2000 Hz
TIM7->ARR =1; // Counter, Decimal 0 olunca basa donsun 10khz demek
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
while(1)
{
}
}
// Programin sonu
Kodu ile Lojik Analizer ile (PD13) ölçüm aldığımda 5Khz görüyorum (Her led Toggle da iki kez kesmeye giriyor). Budan Dolayı 10Khz olduğunu görüyorum.
Böylelikle BUS hattının 84 de çalıştığını anlıyorum.
Konu Kapanmıştır Teşekkür ederim.
;;;12 d=GPIOD->ODR & 0xFF00;
000002 4bad LDR r3,|L1.696|
000004 681b LDR r3,[r3,#0]
000006 f403427f AND r2,r3,#0xff00
Yukarıdaki assembly kod parçacığını biri açıklayabilir mi. Arm assembly söz dizimi biraz kafamı karıştırdı.
İlk satırda r3 registerine GPIOD->ODR değerini attı. Bu tamam.
2. satırda r3'ün alt 16 bitine 0 değeri attı // sanırım yanlış yorumluyorum.
3. satırda r3 ile 0xff00 değerini and yapıp sonucu r2 ( d için kullanılan register) registerine attı.
Eğer 2. satırı yanlış anladıysam bir sorun yok. Ama yanlış anlamadıysam 2. satır anlamsız duruyor.
Tamam şimdi oturdu.
LDR |r3,L1.696| ile pointerin gösterdiği adresin içeriğini aldığını düşünmüştüm. İş orada karıştı.
Cortex çekirdeğinde r0....rn kaydedicileri özdeş mi?. ben istediğim operasyonu istediğim registerde yapabiliyor muyum? Kısıtlamalar neler?
cortex assembly söz dizimi için aşağıdakiler doğru mudur?
x , | ... | şeklinde bir yazım adresler üzerinde işlem
x, [ ... ] adresin gösterdiği içerik üzerinde
x, .... doğrudan içerik üzerinde işlem yapar.
Hocam! doğru anlayıp anlamadığımı test içn aşağıdaki kodu orumlayacağım.
;;;13 CNTR++;
00000a 4bac LDR r3,|L1.700|
00000c 881b LDRH r3,[r3,#0] ; CNTR
00000e f1030301 ADD r3,r3,#1
000012 4caa LDR r4,|L1.700|
000014 8023 STRH r3,[r4,#0]
;;;14 if(CNTR>=255)
000016 4623 MOV r3,r4
000018 881b LDRH r3,[r3,#0] ; CNTR
00001a 2bff CMP r3,#0xff
00001c db19 BLT |L1.82|
;;;16 CNTR=0;
00001e f04f0300 MOV r3,#0
000022 8023 STRH r3,[r4,#0]
LDR r3,|L1.700| r3'e CNTR değişkeninin adresini al.
LDRH r3,[r3,#0] r3'e r3'te gösterilen adresteki verinin 16 bitlik kısmını al.
eğer biz CNTR değil de bir sonraki 16 bitlik değişkenin içeriğini almak isteseydik LDRH r3,[r3,#2] yapacaktık sanırım. verdiğimiz offset değerleri byte cinsinden anladığım kadarıyla.
ADD r3,r3,#1 r3'e 1 ekle yine r3'e at.
LDR r4,|L1.700| r4'e L1.700 deki (CNTR değişkeni) adresini r4'e yükle.
STRH r3,[r4,#0] r3'te bulunan verinin 16 bitini r4+0 ile gösterilen adrese(CNTR) 16 bit olarak at. burada işlemin yönü ters.
MOV r3,r4 r4'ün içeriğini r3'e aktar. artık r3 içeriği CNTR değişkeninin adresi.
LDRH r3,[r3,#0] r3+0 adresindeki (CNTR) içeriği yine r3'e yükle.
CMP r3,#0xff r3 0xff den büyükse bir satır atla. burada sadece büyük kontrolü yapılıyor sanırım. Komut setinde CME gibi eşitlik kontrolü yapan bir komut göremedim. CMN küçükse CMP de büyükse diye yorumluyorum.
BLT |L1.82| programı L1.82 etiketli adrese gönderiyor. Ama komut setinde BLT komutunu bulamadım
MOV r3,#0 r3' içeriğini 0 yap
STRH r3,[r4,#0] r4'ün göstrdiği adrese r3 içeriğini 16 bit olarak yaz.
Cortex komut kümesini detaylı açıklayan bir doküman bulamadım. bulduklarımın tamamı sadece komut kümesini vermiş. Aaa açıklamalar yok.
CMP compare demek.
Komutların pek çoğunun sonuna şart ekleri getirebilirsin. Mesela B Branch iken BLT küçükse Branch yap demek.
ADD topla iken ADDLT küçükse topla gibi...
Hocam CMP'nin compare olduğunu biliyorum ama karşılaştırmanın neye göre yapıldığını anlamadım.
komut setinde CMP ve CMN var. CMP büyükse CMN de küçükse karşılaştırması yapıyor sanıyorum. Peki Eşitlik karşılaştırmasını ne yapıyor?
kumutların çoşuna şart eki getirebiliyor demişsiniz. CMP ve CMN bunlara dahil mi.
Eğer öyle ise CMP ve CMN ile ilgili teorim çöktü.
bu durmda CMP pozitif sayılar için eşitlik CMPL pozitif sayılar için küçüktür CMPH de pozitif sayılar için büyüktür kontrolü mü yapar?
Öyle düşünme.
CMP R1,R2
BEQ L1
R1 ve R2 yi karşılaştır eğer eşitse L1 e git.
CMN ARM işlemcilere özel bir karşılaştırma şekli.
CMP R1,R2 Çıkartma yapıp sonuca bakarken
CMN R1,R2 Toplama yapıp sonuca bakar.
CMP ile karşılaştırırsın daha sonra büyük, küçük, eşit, için şart ekleri getirirsin.
Mesela R1 ile R2 eşitse R3 ve R4 ü toplamak için
CMP R1,R2
ADDEQ R3,R4
gibi.
Tamamdır hocam bu kısım da anlaşıldı.
Halen cortex-m4 assembler manual bulamadım. Bulan, bilen, gören duyan varsa buraya bildirmeleri rica olunur :)
Arkadaşlar bakıyorum da çok hızlı gidiyorsunuz ben daha kartı elime alamadım sınavların yoğunluğundan.Darısı başıma...
NVIC->ISER[1] = 0X00800000;
Hocalarım Bu NVIC in Registerler bilgilerine nereden ulaşabilirim.
ISER i nereden buldunuzda neden 0X00800000 yaptınız. (Elimdek 32F100 de var beraber karşılaştırarak gidiyorum.)
Alıntı yapılan: silvercopper - 12 Ocak 2012, 13:29:48
Arkadaşlar bakıyorum da çok hızlı gidiyorsunuz ben daha kartı elime alamadım sınavların yoğunluğundan.Darısı başıma...
+1
Alıntı yapılan: muhittin_kaplan - 12 Ocak 2012, 14:26:25
NVIC->ISER[1] = 0X00800000;
Hocalarım Bu NVIC in Registerler bilgilerine nereden ulaşabilirim.
ISER i nereden buldunuzda neden 0X00800000 yaptınız. (Elimdek 32F100 de var beraber karşılaştırarak gidiyorum.)
Bunu daha önce konuşmuştuk. NVIC ARM çekirdeğine ait bir birim. Dolayısı ile bunu ARM çekirdeğini anlatan dokmanlardan bakacaksın.
Hatta şamatalar başlığında linki de verilmişti.
Baktım hocam
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/BABBCFHA.html
ama anlamadım.
tüm aramalarıma rağmen ISER de bu kesmelerin hangi bitlere karşılık gerldiğini bulamadım.
Anladığım Kadarıyla
Iser0 ve Iser1 adında iki adet reg var. ve bu reg la int. ayarlanıyor.
bu ayarlama ise 8.1.2 Interrupt and exception vectors başlığında verilmiş.
hocam rehber 195. sayfada başlıyor. interrupt and exception vectors (9.1.3). cortex m3 programming manualda da 120. sayfa tablo 41.
mesala timer 7 için 9.1.3 den bakınca 55. sırada oluğu gözüküyor. tablo 41 den da hesaplarsak ISER[ 1 ] de 23. bite(32 bit( ISER[ 0 ]) + 23 bit=>55) denk geliyor(ISER[ 1 ]=0x00800000)
GPIOC yi giriş olarak tanımlayıp
GPIOC->MODER = 0x00000000; //
GPIOC->OSPEEDR= 0x22222222; //
Keil den Debug a baktığımda
herhangi bir giriş olmamasına ragmen neden anlamsız degerler alıyor
pinler boşta ise normal, pullup ve ya pulldown ile değer sabitlenmeli
peki bunu yazılımla yapabiliyormuyuz ?
(cevabı sanki evet gibi)
28.dakika da Bil Herd sebebini güzel bir şekilde anlatıyor bir gözatın
dahili pulluplar mevcut bunları aktif edebilirsiniz ama pulldown var mı emin değilim datasheet'e bakmak lazım
GPIOx_PUPDR miş
#include "STM32F4xx.h"
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
int main()
{
SystemInit();
while(1)
{
int a;
GPIOD->ODR= 0x0000F000;
for (a=0;a<0x0000FFFF;a++);
GPIOD->ODR= 0x00000000;
for (a=0;a<0x0000FFFF;a++);
}
}
// Programın sonudur.
Aslında Programda yapmak istediğim ardı ardına Usarttan bilgi göndermekti. Ardı ardına giden bilgiyi pc de yerlerine koymak istemiştim.
bunu sağlamak için 8bitlik datanın önüne bir preamble bilgi koyacaktım. neyse yapamadım. geri geri giderken yazığım programda buraya kadar döndüm.
yukardaki programda debugda çalışıyor ama normal çalışmada for larda çakılıyor.
sebebi nedir.
Program çakılmıyor. Döngü hızı yüksek olduğu için ledlerin yanıp söndüğünü göremiyorsun o kadar.
for (a=0;a<0x00FFFFFF;a++); şeklinde düzeltirsen çalıştığını göreceksin.
Alıntı yapılan: Klein - 13 Ocak 2012, 21:15:21
Program çakılmıyor. Döngü hızı yüksek olduğu için ledlerin yanıp söndüğünü göremiyorsun o kadar.
for (a=0;a<0x00FFFFFF;a++); şeklinde düzeltirsen çalıştığını göreceksin.
+1.
160Mhz de çalışsa. pic gibi 4 saykılda çalışsa(sanırım öyle değil) . FFFF e kadar 1.5 ms de sayar.
FFFFFF 0.5sn kadar yapıcak sanırım.
peki bu usart3 den byte byte bilgi gönderirken gönderilen bilgiler arasında nekadar beklemeliyim? yada alıp işlem yaptığını nereden anlarım ?
Alıntı yapılan: fryrmnd - 13 Ocak 2012, 21:25:39
+1.
160Mhz de çalışsa. pic gibi 4 saykılda çalışsa(sanırım öyle değil) . FFFF e kadar 1.5 ms de sayar.
FFFFFF 0.5sn kadar yapıcak sanırım.
O hesap assembly için geçerli for- komutu için kaç ass. komut yazdığına bakmak gerek. MIPS nin ne olduğunu bilmek, ayrıca yanlışım varsa düzeltin arm da (8051 de öyleydi) bütün assm komutlar 1 komut saykılında çalışmıyor
haklısınız hocam. ben komutları tam olarak ne kaç sakılda işlediğini bilmediğimi belirttim. ama klein hocamın yazdığı gibi FFFF çok kısa olucaktır arm ler için sanırım.
Pipeline mekanizmasi bozulmadigi surece komutlarin cogu 1 yada 2 cycle da calisiyor. Branch tipi komutlar kullanilirsa hersey allak bullak oluyor.
Bölme yok. ama bir döngü için 4 komut gerektiği için yine 4-5 civarında bir değer bölünmüş oluyor. (BLT kaç cycle sürüyor bilmiyorum. Dokümanda 1+P yazıyor. P için 1-3 aralığında olabilir diyor. ) yaklaşık 0.5 saniyede bir flash yapıyor.
eğer for döngüsü for (a=0xFFFFFF;a;a--); şeklinde yazılsaydı her döngü 1cycle daha kısa sürecekti.
;;;32 for (a=0xFFFFFF;a;a--);
0000a0 f06f437f MVN r3,#0xff000000
0000a4 e001 B |L1.170|
|L1.166|
0000a6 f1a30301 SUB r3,r3,#1
|L1.170|
0000aa 2b00 CMP r3,#0
0000ac d1fb BNE |L1.166|
;;;33 for (a=0;a<0x00ffFFFF;a++);
0000ae bf00 NOP
0000b0 e001 B |L1.182|
|L1.178|
0000b2 f1030301 ADD r3,r3,#1
|L1.182|
0000b6 f06f407f MVN r0,#0xff000000
0000ba 4283 CMP r3,r0
0000bc dbf9 BLT |L1.178|
bunalmış hocam verdiğin usart ile denemeler yapıyordum
char (8bit) bilgiden daha büyük (örn 16bit) nasıl gönderebilirim
Alıntı yapılan: muhittin_kaplan - 13 Ocak 2012, 22:00:06
peki bu usart3 den byte byte bilgi gönderirken gönderilen bilgiler arasında nekadar beklemeliyim? yada alıp işlem yaptığını nereden anlarım ?
Usart ile bilgi gönderirken bilgiler arasına sabit beklemeler koymak yerine , TX tamponunun boşalmasını beklemek daha daha doğru olur.
Usart bayraklarını incelemedim. Ama SPI ile olan tecrübelerden, TX tamponundaki bilgi donanıma aktarıldığında, donanımın işini bitirmesi beklenmeden bayrağın çekileceğini tahmin ediyorum.
Eğer öyle ise, eğer RS485 gibi bir sistemi alma moduna geçirecekseniz , sadece son verinin sonuna bir bekleme konulabilir.
Bu değeri sabit bir sayı yerine baud hızına göre değişen bir değer yapmak programı daha esnek yapar.
Eğer 8 bit data, 1 stop , parite yok şeklinde bir konfigürasyon varsa. Start+Data+Stop = 10 bit veri gönderilecek demektir.
TX tamponu boşaldıktan sonra bu kadar bitin gönderilmesine yetecek kadar bir süre beklenmesi uygun olacaktır.
Bu süre şöyle hesaplanabilir.
(Start+Data+Stop+Parite)/baud
sonuç saniye cinsindendir.
Ekleme:
Şimdi baktım. TXE bayrağı dediğim gibi çalışıyor. TC bayrağı ise gönderim tamamen bittiğinde çekliyor.
Veri aralarında TXE veri gönderimi tamamen bittiğinde TC bayrağı kullanılabilir.
Program Size: Code=15088 RO-data=29592 RW-data=56 ZI-data=10316
Şimdi ben kaç kb ram kaç kb rom kullanmışım?
Selamun aleykum arkadaşlar, heveslendim stm32f4 satın aldım ve ADC tek kanal 1024 bit okuma yapmak istiyorum. sağdan soldan birkaç kod buldum ama coğu sorunlu ve uzun bir kod yapısı var. acaba basit bir örnek yazarmısınız. :(
uzun dediğiniz kodları biz yazsak register bazında kodlama ile anlayabilicekmisiniz. yani yanlış anlamayın da program çok basit olmayacaktır. altı üstü 10 bit ADC diyebilirsiniz tabi ama anlamak istiyorsanız,kodda nerede ne yapılmış bilmek istiyorsanız datasheeti kurcalamanız gerekicek. ben 1-2 deneme yapıtım henüz sonuç alamadım. umarım yardım eden olur. ama siz yazsaydınız ,şu kodu çalıştıramadım, yada şu register ne iş yapıyor bu programda deseydiniz daha çok yardım eden olabilir.
Bunalmis hocam sizin yazdığınız uart3 modülünü kullanarak rs232 bluetooth bağladım telefonada bir terminal programı kurdum. Ama ne telefona veri göndere biliyorum nede stm32f4 e mesela telefondan A verisi geldiğinde GPIOD->ODR 0x00001000 deki led yansın gibi ama beceremedim hocam yardımını bekliyorum. Elimdeki bluetooth modülü http://www.goodluckbuy.com/serial-bluetooth-rf-transceiver-module-rs232-w-backplane-enable-and-state-pin-1.html bu üründür. Sadece RX-TX'e TX-RX'e ve VCC - GND Bacakları bağlı.
#include "STM32F4xx.h"
unsigned char WAdr,RAdr;
char RxBuf[128];
/*********************************************************************************
CPU frekansi 168Mhz
AHB frekansi 84 Mhz
APB frekansi 42 Mhz
*********************************************************************************/
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim 168 Mhz
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000001F; // GPIO A,B,C,D,E clock'u aktif edelim
GPIOD->MODER = 0x55550000; // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
/*********************************************************************************
USART3 modulunu kullanarak asenkron haberlesme (Hata kontrolu yapilmiyor)
*********************************************************************************/
void USART3_IRQHandler()
{
volatile int Sts;
Sts=USART3->SR;
RxBuf[WAdr]=USART3->DR;
WAdr=(WAdr+1)&0x7F;
}
void UsartInit()
{
WAdr=0;RAdr=0;
// USART3 MODULUNU AKTIF HALE GETIRELIM
RCC->APB1ENR|=0x00040000; // USART3 Clk Enable (Rehber Sayfa 113)
RCC->APB1RSTR|=0x00040000; // USART3 Resetlendi
GPIOB->AFR[1]=0x07777700; // PB10..PB14 pinleri USART3 ile alakalandirildi (Hard Sayfa 49)
GPIOB->MODER|=0x2AA00000; // GPIOB 10..14 icin alternatif fonksiyon tanimi (Rehber Sayfa 148)
// USART3 MODULUNU AYARLAYALIM // 1 Start, 8 Data, 1 Stop, No parity (Default degerler)
RCC->APB1RSTR&=~0x00040000; // USART3 Reseti kaldiralim
// USART3->SR&=~0X03FF; // Status registeri silelim
USART3->BRR=0X1112; // 9600 Baud
USART3->CR1|=0x0000202C; // USART3 enable
NVIC->ISER[1]|=0x80; // NVIC da USART3 interrupta izin verelim
}
void SendChar(char Tx)
{
while(!(USART3->SR&0x80)); // TX Buffer dolu ise bekle (Rehber Sayfa 646)
USART3->DR=Tx;
}
void SendTxt(char *Adr)
{
while(*Adr)
{
SendChar(*Adr);
Adr++;
}
}
char DataReady()
{
return(WAdr-RAdr);
}
char ReadChar()
{
char Dat;
Dat=RxBuf[RAdr];
RAdr=(RAdr+1)&0x7F;
return(Dat);
}
// Rx ve TX pinlerini (GPIOB10 ve GPIOB11) birbirine baglarsaniz gonderdiginiz datalar geri gelecektir
int main()
{
int i;
UsartInit();
SendTxt("Mcu-Turkey");
SendChar(' ');
SendTxt("Bunalmis");
for(i=0;i<0x1000000;i++); // Laf olsun diye bekledik
while(DataReady()) ReadChar();
while(1);
}
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm324xg_eval.h"
#include "stm324xg_eval_lcd.h"
#include <stdio.h>
/** @addtogroup STM32F4xx_StdPeriph_Examples
* @{
*/
/** @addtogroup ADC_ADC3_DMA
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* used to display the ADC converted value on LCD */
#define PRINT_ON_LCD
/* if you are not using the LCD, you can monitor the converted value by adding
the variable "ADC3ConvertedValue" to the debugger watch window */
#define ADC3_DR_ADDRESS ((uint32_t)0x4001224C)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t ADC3ConvertedValue = 0;
__IO uint32_t ADC3ConvertedVoltage = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void ADC3_CH7_DMA_Config(void);
#ifdef PRINT_ON_LCD
void Display_Init(void);
void Display(void);
#endif /* PRINT_ON_LCD */
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f4xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
#ifdef PRINT_ON_LCD
/* LCD Display init */
Display_Init();
#endif
/* ADC3 configuration *******************************************************/
/* - Enable peripheral clocks */
/* - DMA2_Stream0 channel2 configuration */
/* - Configure ADC Channel7 pin as analog input */
/* - Configure ADC3 Channel7 */
ADC3_CH7_DMA_Config();
/* Start ADC3 Software Conversion */
ADC_SoftwareStartConv(ADC3);
while (1)
{
ADC3ConvertedVoltage = ADC3ConvertedValue *3300/0xFFF;
#ifdef PRINT_ON_LCD
/* Display ADC3 converted value on LCD */
Display();
#endif
}
}
/**
* @brief ADC3 channel07 with DMA configuration
* @param None
* @retval None
*/
void ADC3_CH7_DMA_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable ADC3, DMA2 and GPIO clocks ****************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOF, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
/* DMA2 Stream0 channel2 configuration **************************************/
DMA_InitStructure.DMA_Channel = DMA_Channel_2;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
/* Configure ADC3 Channel7 pin as analog input ******************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOF, &GPIO_InitStructure);
/* ADC Common Init **********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC3 Init ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC3, &ADC_InitStructure);
/* ADC3 regular channel7 configuration *************************************/
ADC_RegularChannelConfig(ADC3, ADC_Channel_7, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);
/* Enable ADC3 DMA */
ADC_DMACmd(ADC3, ENABLE);
/* Enable ADC3 */
ADC_Cmd(ADC3, ENABLE);
}
#ifdef PRINT_ON_LCD
/**
* @brief Display ADC converted value on LCD
* @param None
* @retval None
*/
void Display(void)
{
uint32_t v=0,mv=0;
uint8_t text[50];
v=(ADC3ConvertedVoltage)/1000;
mv = (ADC3ConvertedVoltage%1000)/100;
sprintf((char*)text," ADC = %d,%d V ",v,mv);
LCD_DisplayStringLine(LINE(6),text);
}
/**
* @brief Display Init (LCD)
* @param None
* @retval None
*/
void Display_Init(void)
{
/* Initialize the LCD */
STM324xG_LCD_Init();
/* Clear the LCD */
LCD_Clear(White);
/* Set the LCD Text size */
LCD_SetFont(&Font8x12);
/* Set the LCD Back Color and Text Color*/
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
/* Display */
LCD_DisplayStringLine(LINE(0x13), " ADC conversion w/ DMA transfer example ");
/* Set the LCD Text size */
LCD_SetFont(&Font16x24);
/* Display */
LCD_DisplayStringLine(LINE(0), "ADC Ch7 Conv @2.4Msps");
/* Set the LCD Back Color and Text Color*/
LCD_SetBackColor(White);
LCD_SetTextColor(Blue);
/* Display */
LCD_DisplayStringLine(LINE(2)," Turn RV1(PF.09) ");
LCD_DisplayStringLine(LINE(4)," Potentiometer ");
}
#endif /* PRINT_ON_LCD */
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
kod bu, header dosyalarını da ekledim fakat derlediğimde 30 tane hata verdi
hatalardan birisi de HalfWord undefined diyor (tanımlı değilmiş) lcd dosyası lazım değil dedim kodları sadeleştirdim yine değişen birşey olmadı nerde hata yapıyorum anlamadım
kaynak:http://tech.munts.com/MCU/Frameworks/ARM/stm32f4/libs/STM32F4xx_DSP_StdPeriph_Lib_V1.0.0/Project/STM32F4xx_StdPeriph_Examples/ADC/ADC3_DMA/
Yeri Gelmişken SendTXT nasıl çalışıyor hocam.
larkin hocam readme dosyasını okudunuz mu. koskoca st çalışmayan kod koymaz sanırım.
Hardware and Software environment
- This example runs on STM32F4xx Devices.
- This example has been tested with STM324xG-EVAL RevB and can be easily tailored
to any other development board.
- STM324xG-EVAL Set-up
- Use the Potentiometer (RV1) of the Eval board (connected to PF.09).
In order to make the program work, you must do the following :
- Copy all source files from this example folder to the template folder under
Project\STM32F4xx_StdPeriph_Templates
- Open your preferred toolchain
- Rebuild all files and load your image into target memory
- Run the example
gibi uyarılar var. gerekli ayarları yaparsanız çalışcaktır sanırım.
Alıntı yapılan: muhittin_kaplan - 14 Ocak 2012, 17:41:02
Yeri Gelmişken SendTXT nasıl çalışıyor hocam.
Sorduğunuz sorular yoruma dayalı veya doğrudan kişiyi ilgilendiren sorular olmadığı için; doğrudan @bunalmıs'a sorulmuş olsa da gördükçe yanıtlamaya çalışıyorum. Umarım kızmaz.
void SendTxt(char *Adr)
{
while(*Adr)
{
SendChar(*Adr);
Adr++;
}
}
Eğer soru koddaki pointerler ile ilgili değilse:
C de metinler (TXT) sıfır sonludur. bir pointer veya array'a "merhaba dunya" yazdığınızda siz metnin sonuna 0 koymasanız da derleyicilerin çoğu otomatik olarak metnin sonuna 0 sayısını ('0' karakteri değil) koyar. Biz de metnin sonuna gelip gelmediğimizi bilmek için bu sayıyı kontrol ederiz.
şart cümlelerinde eğer kontrol edeceğimiz cümleye '>' , '<' , '==' gibi karşılaştırma operatörü koymamışsak, eğer doğruysa anlamına gelir. Eğer şarta konu olan değer bir sayı ise 0'dan farklı hangi değeri alırsa alsın "doğru" değeri gönderir
while(*Adr) döngüsünde yapılan da budur. Adr işaretçisi ile gösterilen hücrenin değeri 0 dan farklı olduğu sürece dönmeye devam edecektir.
SendChar(*Adr); burada yapılan belli. SendChar(..) fonksiyonu nun parametresi char tipinde. parametre bir işaretçi olmadığı için o fonksiyonu doğrudan değerin kendisi ile çağırmak gerekiyor. Burada yapılan iş de Adr işaretçisinin gösterdiği adresin içeriğini doğrudan SendChar(...) fonksiyonuna parametre olarak geçmek.
Adr++; Burada da yapılan iş açık. pointer değeri 1 artırılarak , bir sonraki adresi göstermesi sağlanıyor.
Eğer soru bu anlattıklarım ile ilgili değil , işaretçiler ve kullanımları ile ilgili ise:
Pointer konusu yanlış hatırlamıyorsam "Basic kullanıcılarını C'ye alaıştırma" gibi bir başlıkta konuşulmuştu. Orada daha fazla detay olabilir.
C de metinler (TXT) sıfır sonludur
Anahtar Kelime Bu hocam. Sıfırdan Nastınız Null değer mi ? (/n)
--ekleme--
SendTXT ("Mcu-Turkey") ile ram a sırayla M C U gibi karakter katarlarınının char değerini ekliyor. (Nereye Nasıl Ekliyor ?)
SendTXT (Char *A) ilede bu her bir karakterin adresini veriyor.
SendChar gösterilen adresteki CHAR değeri gönderiyor
Doğrumu anlamışım ?
(USART_DR) register değeri 32bit görünüyor. neden Char Gönderiyoruz ?
Evet null değeri.
SendTXT ("Mcu-Turkey") ile ram a sırayla M C U gibi karakter katarlarınının char değerini ekliyor. (Nereye Nasıl Ekliyor ?)
Fonksiyona bu şekilde derleme anında belli olan bir parametre değeri verilmişse, derleyici derleme esnasında bu değeri rom'da bir yere yazar. fonksiyonu çağırdığımızda Adr işaretçisine rom'daki bu adresi atar. artık işaretçimizin gösterdiği adres burasıdır.
SendChar(...) fonksiyonunda adres ile işimiz yok. Çünkü bu fonksiyonun parametresi işaretçi değil. Bu yüzden *Adr ile elde ettiğimiz değeri doğrudan bu fonksiyona parametre olarak geçiyoruz.
Şöyle bir akış gerçekleşiyor.
Burada r0,r1,r2 gibi tanımlamalar var. bunlar gerçekte mcu içerisindeki registerleri ifade ediyor. bir çeşit geçici alanlar. sürekli kullanmayacağı veriler üzerinde işlem yaparken bunlara veriyi atıyor, bu veri üzerinde işlem yapıyor. başka bir işleme geçtiğinde buraya başka bir veri atıyor. Bir çeşit yaz boz tahtası.
SendTXT("Mcu-Turkey") fonksiyonu çağııldı.
fonksiyonun adresine git.
r0' a "Mcu-Turkey" metninin bulunduğu yerin adresini at. örn. 0x200;
while(*Adr)
r1'e 0x200 adresinde bulunan karakteri at.
r2'ye 0 değerini at.
r1 ile r2'yi karşılaştır. eğer aynı değilse yoluna devam et.
SendChar(*Adr);
r1'e 0x200 adresindeki karakteri at.
sendchar(..) fonksiyonunu r1 ile çağır. SendChar(r1); demek gibi. dikkat et burada gerçekten değer ile çağırıyoruz. Adres yok.
Adr++;
r0 içeriğini 1 artır. r0 =r0+1 gibi. artık r0'ın değeri 0x0201
başa dön.
Bundan sonra 0x200 yerine 0x2001, 0x2002 gibi gidecek.
Alıntı yapılan: muhittin_kaplan - 14 Ocak 2012, 19:40:36
(USART_DR) register değeri 32bit görünüyor. neden Char Gönderiyoruz ?
Char gönderebiliyor olmamızın sebebi, register yapısından veya işlemcinin yeteklerinden kaynaklı bir durum değil.
uart,usart haberleşme protokolünün yapısından kaynaklı.
Bu protokolde her bir pakette ancak 7,8 veya 9 bit veri olabiliyor. Biri çıkıp ben usart_32 diye bir protokol yazdım derse ve bunu da bir endüstri standartı haline getirebilirse, o zaman üreticiler bu protokole uygun donanımlar veya yazılımlar yapar. Ancak şimdilik elimizdeki bu.
Hocam Aslında Birçok Sorunun cevabını Biliyorum.
232 Standardına Ne olduğunu Örneğin. Ama Basic den kalma Bir alışkanlık var. Muhittin i Gönder dediğimizde Karşıya Muhittin Gönderir. İçeriği nedir ilgilenmezsin.
r0 lar r1 8051 de de kullanıyordum. ama asm olunca ve burada C ile yazınca hiç r0 lar r1 ler gelmiyor aklımıza.
Telefona usart3 ile veri gönderebildim. Ama bi türlü telefondan örneğin A verisini gönderdiğimda D portundaki 0x0000F000 Ledlerinin hepsi yansın dediğimde birşey olmuyor.
Hocalarım C4 değil ama birçok şey den bahsetmiş c3 için.
http://www.hitex.com/fileadmin/pdf/insiders-guides/stm32/isg-stm32-v18d-scr.pdf
WD u biliriz. Ama analog WD nedir ?
Eğer okuduğunuz analog değerler, belirlediğiniz alt ve üst sınırların dışında olursa bu arkadaş size haber veriyor.
sürekli olarak adc verisini okumanız gerekemiyor.
CM4 için capture örneğine ihtiyacım var. deneme yapan oldumu acaba ?
Merhabalar; ben de şu anda Timer çalışmaları yapıyorum. (biraz geri kaldım ama :D) Timer2 ile ledleri 1 sn boyunca yakan 1 sn boyunca söndüren bir uygulama yaptım. İstediğim gibi de oluyor ancak program bir süre (1 dk falan) durduktan (ledler sönük vaziyette) sonra çalışmaya başlıyor, bunun sebebi nedir acaba?
Herkese kolay gelsin.
#include "STM32F4xx.h"
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
int main()
{
RCC->APB1ENR|=0x00000001;
TIM2->CR1=0x0080;
TIM2->PSC=41999;
TIM2->ARR=2000;
TIM2->CR1|=0x0001;
while(1)
{
if(TIM2->CNT < 1000)
GPIOD->ODR=0x0000F000;
else
GPIOD->ODR=0x00000000;
}
}
Edit:
Programı Timer2 yerine Timer7 ile çalışacak biçimde düzenlediğimde (2 ' leri 7 yaparak ve clock ayarını değiştirerek) sıkıntı olmuyor
Alıntı yapılan: -Hasan- - 17 Ocak 2012, 16:59:49
Programı Timer2 yerine Timer7 ile çalışacak biçimde düzenlediğimde (2 ' leri 7 yaparak ve clock ayarını değiştirerek) sıkıntı olmuyor
RCC->APB1ENR|=0x00000001;
Bu satırıda değiştiriyorsun değil mi? Timer7 clock aktik etmek için RCC->APB1ENR|=0x20; (6.bit)
Evet; aynen o şekilde yapıyorum.
Edit:
Şimdi Timer8 ile bir uygulama yaptım. Bu gayet düzgün çalışıyor. Ancak Timer2 neden öyle yaptı anlamadım.
#include "STM32F4xx.h"
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
int main()
{
RCC->APB2ENR|=0x00000002;
TIM8->CR1=0x0080;
TIM8->PSC=41999;
TIM8->ARR=8000;
TIM8->CR1|=0x0001;
while(1)
{
if(TIM8->CNT < 4000)
GPIOD->ODR=0x0000F000;
else
GPIOD->ODR=0x00000000;
}
}
bunalmış hocam HARD 49 da verilen tabloda pinlere vereceğimiz alternatif fonksiyonlar var. TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4 ler ve TIM 4 lerde de aynısı var. bu kanallar nedir ?
Timerlari harici pindeki bir clk ile saydirabiliyorsun. Hatta bazi timerlari up/down modda saydirabiliyorsun.
Timer cikislarini da pinlerle iliskilendirebiliyorsun. (Compare cikisi gibi)
Rehber 294 de bak.
Alıntı yapılan: -Hasan- - 17 Ocak 2012, 17:32:20
Şimdi Timer8 ile bir uygulama yaptım. Bu gayet düzgün çalışıyor. Ancak Timer2 neden öyle yaptı anlamadım.
Hasan
ARM cipimiz icin verilmis programlarda bazi register indislerini degistirerek yeni programlar uretirken cok dikkatli ol.
Ornegin TIM7->XXX gibi satirlari TIM2->XXX yapmaya kalkarsan sorun yasarsin. Cunku Timer 2 ozelligi olan ve diger timerlardan farkli bir timer.
Verdigin programi denedigimde sorunlu oldugunu gordum. Autoreload islemini ilk sayimda cok gec yapiyor cunku 32 bit bir timerin tasmasi zaman aliyor. Bende hemen reload yapmasi icin counter registerine -1 degerini yukledim. Shadow regleri derhal yuklemesi icin belki bir reg vardir.
Rehber 361 e bak.
Verdigin programda main satirini asagidaki gibi degistirirsen Timer2 de duzgun calisir. Aslinda senin programinda calisiyor. Sadece ledlerin flash etmesi icin beklemen gerekiyor. (TIMER2 16 değil 32 bitlik bir timer)
int main()
{
RCC->APB1ENR|=0x00000001; // TIMER2 CLK Enable edildi
TIM2->CR1=0x0080;
TIM2->PSC=41999;
TIM2->CNT=0xFFFFFFFF;
TIM2->ARR=2000;
TIM2->CR1|=0x0001;
while(1)
{
if(TIM2->CNT < 1000) GPIOD->ODR=0x0000F000;
else GPIOD->ODR=0x00000000;
}
}
ayrıca interrupt rutinlerinde, startup dosyasındaki interrupt handler ismini yazdığınız programdaki isimle karşılaştırın
TIM6, TIM7 ile benzer diye onu kullanmaya karar verdim, isme dikkat etmediğimden 1 saati boşu boşuna harcadım
programınız B . diye bir yerde dönüyorsa bu noktaya mutlaka göz gezdirin
Bülent Hocam o uygulamayı satırları değiştirerek yapmamıştım. Onu main kısmını komple silip Rehber ' den bakarak, diğer Timer uygulamalarında yaptığımız ayarları yaparak yazmaya çalıştım. Timer2 düzgün çalışmayınca o şekilde satırları değiştirdim.
Alıntı yapılan: bunalmisAutoreload islemini ilk sayimda cok gec yapiyor cunku 32 bit bir timerin tasmasi zaman aliyor. Bende hemen reload yapmasi icin counter registerine -1 degerini yukledim. Shadow regleri derhal yuklemesi icin belki bir reg vardir.
Yani hocam Timer2 ' nin Autoreload yapması için ilk başta bir kere taşana kadar sayması mı gerekiyor?
TIMx->CR1 deki ARPE bit'ini 0 yaparsanız, yüklediğiniz değer bir sonraki update'i beklemeden doğrudan shadow register'a yüklenir.
arkadaşlar benim anlamadığım en başta mesela
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi
0x55000000 bu hex i anlamadım , nasıl oluşturuluyor ? nasıl ayarlanıyor ? kısaca açıklarmısınız ?
(http://s13.postimg.cc/y00kw76sn/GPIO.jpg)
Rehber Sayfa 148
GPIOD->MODER = 0x55000000;
Dediğimiz zaman bu registerin en yüskek değerlikli byte 01010101 olur. Bu durumda GPIOD ' nin son 4 pini için General Purpouse Output Mode seçilmiş olur. Yani bir pini yönlendirmek için 2 bit kullanılıyor:
01010101
GPIOD 15. Pin
GPIOD 14. Pin
GPIOD 13. Pin
GPIOD 12. Pin
rehber i indirdim , anladım teşekkür ederim
Alıntı yapılan: -Hasan- - 18 Ocak 2012, 08:50:56
Yani hocam Timer2 ' nin Autoreload yapması için ilk başta bir kere taşana kadar sayması mı gerekiyor?
Görünen durum bu. Daha önceki örneklerde timerlar 16 bit oldukları için taşması kısa zaman alıyordu.
Ancak örnek olarak verdiğim programlar fazla düşünülmeden yazılmış programlar. Dokumanlara tekrardan gözatıp reload şartlarına bir daha bakmak lazım.
Şu anki çözümüm iş görse de açıkcası hiç beğenmedim.
Alıntı yapılan: JKramer - 18 Ocak 2012, 09:04:36
TIMx->CR1 deki ARPE bit'ini 0 yaparsanız, yüklediğiniz değer bir sonraki update'i beklemeden doğrudan shadow register'a yüklenir.
Hocam bu şekilde yapınca oluyor. Siz o biti hep 1 yapmışsınız. O bitin görevi nedir tam anlayamadım?
Bit 7 ARPE: Auto-reload preload enable
0: TIMx_ARR register is not buffered
1: TIMx_ARR register is bufferedNVIC->ISER[1]=0x00800000;
Bir de hocam Rehber ' de bu registeri bulamadım. Ben mi göremiyorum acaba?
Alıntı yapılan: bunalmisŞu anki çözümüm iş görse de açıkcası hiç beğenmedim.
Estağfurullah hocam. Buradaki çoğu kişi (ben de dahil) sizin sayenizde ARM ' a başlangıç yaptı. Size ne kadar teşekkür etsek azdır. O incelikleri de yaptıkça görüyoruz işte.
Denemedim ama evet mantıklı. Gölge register deselerdi anlamak daha kolay olurdu.
Auto Reload Register iki parçadan oluşuyor; biri bizim okuyup yazdığımız Preload (önyükleme) register, diğeri Shadow (gölge) register. Timer taştığı zaman önceden yüklenmiş değeri almak için Auto Reload Register'ın Shadow kısmına bakıyor.
ARPE bit'i 0 olduğunda preload register'ına yüklediğimiz değer doğrudan shadow register'a kopyalanıyor.
ARPE bit'i 1 olduğunda ise preload register'ına yüklenmiş değer, sadece bir "update event" (UEV) oluştuğunda shadow register'a kopyalanıyor.
UEV, üç farklı şekilde oluşabilir:
1- Sayaçların taşma durumunda
2- Yazılımsal olarak (TIMx->EGR'deki Update Generation _UG_ bit'i set edildiğinde)
3- Diğer timer'lardan ya da harici (?) kaynaklardan tetiklenme durumunda
ARPE bit'inin 1 olduğu durumda Auto Reload Register içindeki shadow register'ı güncellemek için UG bit'ini set etmeniz yeterli.
Alıntı yapılan: -Hasan- - 18 Ocak 2012, 12:40:35
Hocam bu şekilde yapınca oluyor. Siz o biti hep 1 yapmışsınız. O bitin görevi nedir tam anlayamadım?
Bit 7 ARPE: Auto-reload preload enable
0: TIMx_ARR register is not buffered
1: TIMx_ARR register is buffered
NVIC->ISER[1]=0x00800000;
Bir de hocam Rehber ' de bu registeri bulamadım. Ben mi göremiyorum acaba?
Estağfurullah hocam. Buradaki çoğu kişi (ben de dahil) sizin sayenizde ARM ' a başlangıç yaptı. Size ne kadar teşekkür etsek azdır. O incelikleri de yaptıkça görüyoruz işte.
UG'yi timer'ı ayarladıktan sonra set etmezseniz, ilk timer süreniz değişir.
Ve eğer timer interrupt kullanacaksanız, doğrudan timer interrupta gidersiniz.
ISER registeri için diyorsan, o register arm cortex m3 programming manual içinde. Systemtick, interrupt registerleri daha doğrusu core ile ilgili registerler.
STM'de yukarıda karşılaştığınız durama benzer şeyler var, bitanesini söylüyeyim mesela i2c modülünü registerleri ayarladıktan sonra enable yaparsanız(modul enable, clk enable değil) i2c modulünü çalıştıramıya bilirsiniz veya dengesiz çalışır.
Tanımlayabileceğimiz maximum char dizisi kaç elemanlı olabilir? Ben kullandığım işlemcinin ram kapasitesinden daha büyük diziler tanımladığımda bana herhangi bir hata vermiyor ve programı çalıştırdığımda çakılıyor. Sanırım exeption olayından biri gerçekleşiyor .Debuggerım yok. Hafıza sınırlamalarını hangi kaynakdan okurum? Birde keilin kullandığım mcu nun ram*rom sınırlarını aştığımda bana uyarı vermesini nasıl sağlarım.
/**
******************************************************************************
* @file TIM_PWM_Input/main.c
* @author MCD Application Team
* @version V1.0.0
* @date 19-September-2011
* @brief Main program body
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f4_discovery.h"
/** @addtogroup STM32F4_Discovery_Peripheral_Examples
* @{
*/
/** @addtogroup TIM_PWM_Input
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_ICInitTypeDef TIM_ICInitStructure;
/* Private function prototypes -----------------------------------------------*/
void TIM_Config(void);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f4xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
/* TIM Configuration */
TIM_Config();
/* TIM4 configuration: PWM Input mode ------------------------
The external signal is connected to TIM4 CH2 pin (PB.07),
The Rising edge is used as active edge,
The TIM4 CCR2 is used to compute the frequency value
The TIM4 CCR1 is used to compute the duty cycle value
------------------------------------------------------------ */
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(TIM4, &TIM_ICInitStructure);
/* Select the TIM4 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM4, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE);
while (1);
}
/**
* @brief Configure the TIM4 Pins.
* @param None
* @retval None
*/
void TIM_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM4 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //RCC->APB1ENR|=0x00000004
/* GPIOB clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//RCC->AHB1ENR|=0x00000002
/* TIM4 chennel2 configuration : PB.07 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//GPIO->MODER&=0xFFFFBFFF
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//GPIOB->OSPEEDR=0xFFFFFFFF
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;//GPIO->OTYPER=0x00000000
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect TIM pin to AF2 */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4);
/* Enable the TIM4 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;//NVIC->ISER[0] = 0X40000000;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
while (1)
{}
}
#endif
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
Hocam PWM input la ilgili bir Example varmış. Bir kütüphane kullanaak yapılmış. Tabiki anlamadım. Arayıp Bulduğum yerleri Açıklama şeklinde yazdım. Ama Yardıma İhtiyacım Var. PWM INPUT örneğini Register kodlaması yaparak yazabilirmiyiz?
Alıntı yapılan: mcan - 18 Ocak 2012, 21:14:10
Tanımlayabileceğimiz maximum char dizisi kaç elemanlı olabilir? Ben kullandığım işlemcinin ram kapasitesinden daha büyük diziler tanımladığımda bana herhangi bir hata vermiyor ve programı çalıştırdığımda çakılıyor. Sanırım exeption olayından biri gerçekleşiyor .Debuggerım yok. Hafıza sınırlamalarını hangi kaynakdan okurum? Birde keilin kullandığım mcu nun ram*rom sınırlarını aştığımda bana uyarı vermesini nasıl sağlarım.
STM32F4 Discovery üzerindeki ST Link tarafından debug yapabilirsiniz.
Bu arada derleyici o tanımladığını dizi için ancak kullanıldığı zaman derlemede yer ayırıyor. Yoksa oraları zaten boş diye derlemeye almıyor.
Eğer kod içerisinde dinamik olarak kullanırsanız o zaman muhtemelen hata/uyarı mesajı alırsınız. Diğer türlü sabit olarak tanımlarsanız yani ana program içerisinde dizi değişkenlerine atama yapmazsanız o zaman da static olarak derleme esnasında flasha gömülüyor değerler. Ve bu sebepten dolayı da yine RAM de yer tutmuyor.
Alıntı yapılan: muhittin_kaplan - 18 Ocak 2012, 23:17:40
Hocam PWM input la ilgili bir Example varmış. Bir kütüphane kullanaak yapılmış. Tabiki anlamadım. Arayıp Bulduğum yerleri Açıklama şeklinde yazdım. Ama Yardıma İhtiyacım Var. PWM INPUT örneğini Register kodlaması yaparak yazabilirmiyiz?
Yapılabilir. Aslında biraz örnekleri incelesen sen de yapabilirsin.
Geçtiğimiz günlerde (sanırım sizin sorunuzdu) Rehber 378 sayfadaki PWM Inpud mode için verdiği direktifleri türkçe olarak anlatmıştım.
O direktiflerde yazanları uygulaman, timer frekans ayarları için @bunalmıs hocamın örneklerinden TIMER 7 yi incelemen ve Port alternatif fonksiyonların tanımı için yazddığım header dosyasını incelemen yeterli.
senin için bu söylediklerimi kullanarak bir örnek yazdım. PWM input mode için rehberde söylenenleri aynen yaptım. Şu registere şu değeri yaz, buna bu değeri yaz gibi doğrudan değerler vermiş. Timer saat kaynağı ayarları için TIM7 örneğinden bir bölüm aldım. gerisini de header dosyadan
// Bu kısım Timer 7 den çekilen kopya.
RCC->APB1ENR|=0x00000001; // Timer2 CLK'u aktif edelim (84 Mhz)
TIM2->PSC = 4199;
TIM2->ARR = 2000;
TIM2->DIER = 0x0001;
// Bu kısım Rehberde verilen talimatlar
TIM2->CCMR1 |= 0x0002; //CCR 1 için Giriş kaynağı TI1 seçildi
TIM2->CCER &= ~0x000A; // TI1FP1 için polarite seçimi. evirilmemiş / yükselen kenar
TIM2->CCMR1 |= 0x0200; //CCR 2 için Giriş kaynağı TI1 seçildi
TIM2->CCER |= 0x0020; // TI1FP2 için polarite seçimi. evirilmiş / düşen kenar
TIM2->SMCR |= 0x0050; // geçerli tetikleme kaynağı TI1FP1
TIM2->SMCR |= 0x0004; // Slave mode = reset Yükselen kenarda sayıcıyı sıfırla ve değeri güncelle.
TIM2->CCER |= 0x0011; // CC1 ve CC2 aaktif.
// Bu kısım PA 15 portunu TIM2 ile ilişkilendiren Alternatif fonksiyon tanımlama
PA->MODER.pin.p15 = PORT_ALTERNATE_FUNC; // Port alternatif fonksiyon
PA->PUPDR.pin.p15 = PORT_PULL_UP; // Port PULL_UP direncini aç
PA->AFR.pin.p15 = PORT_AF1_TIM2; // Portu TIM2 ile ilişkilendir.
// Bu kısım interrupt aktif etme ve sayıcıyı başlatma
NVIC_EnableIRQ(TIM2_IRQn); //Timer 2 interrupt aktif et;
TIM2->CR1 |= 0x0001; // sayıcıyı başlat.
// Bu kısım TIM2 interrupt rutini
// unsigned short ccr1,ccr2;
void TIM2_IRQHandler(){
ccp_update=1;
ccr1=TIM2->CCR1;
ccr2=TIM2->CCR2;
TIM2->SR=0;
}
// bu kısım da ana döngü içinde çalışan, CCR registerlerinden aldığım değerleri seri porttan gönderdiğim bölüm. Seri port örneklerde var.
if(ccp_update ){
ccp_update=0;
sprintf(TxBuf,"CC1= %u\rCC2= %u\r",ccr1,ccr2);
SendTxt(TxBuf);
}
// CC2 duty değerini gösteriyor.
// CC1 hep 0 alıyorum. öyle mi olmalı? yoksa bir hata mı var bilmiyorum. Yarın incelerim.
PA 15'e ~13.3Hz civarında %80 civarı duty değeri olan PWM veriyorum.
TIM2 ön bölücü olarak 4200 verdik. CLK frekansımız 84MHz. sayıcımız saniyede 20000 sayıyor.
Frekansımız 13.3 duty %80. Yaklaşık duty süremiz 60mS. Duty süresince sayıcımızın sayması gereken değer 20000*0.06 =1200;
CC2 değerim 1200. Yani doğru okuyor.
Test edebilmen için aşağıda timer ile yazılımsal PWM üretmek için yazdığım deneme kodlarını veriyorum
// Başlatma kodları. PWM çıkışımız PB_5
PB->MODER.pin.p5 = PORT_OUTPUT;
PB->OSPEEDR.pin.p5 = PORT_FAST_SPEED;
PB->OTYPER.pin.p5 = PORT_PUSH_PULL;
RCC->APB1ENR|=0x00000008; // Timer5 CLK'u aktif edelim (84 Mhz)
TIM5->PSC = 4199;
TIM5->ARR = 2;
TIM5->DIER = 0x0001;
NVIC_EnableIRQ(TIM5_IRQn); //Timer 5 interrupt aktif et;
TIM5->CR1 |= 0x0001; // sayıcıyı başlat.
// interrupt handler
void TIM5_IRQHandler(){
if(++ pwm_counter > pwm_duty){
pwm_counter=0;
if(!pwm_out){
pwm_duty=800;
} else pwm_duty=200;
pwm_out =!pwm_out;
}
PB->ODR.pin.p5 = pwm_out;
TIM5->SR=0;
}
Ekleme:
Bu aletin capture modülünün hayranı oldum. İnanılmaz stabil okuyor. En küçük bir oynama yok. Bunda darbeyi de aynı işlemciden vermiş olmamın da etkisi olabilir tabi. Ama yine de beğendim.
Alıntı yapılan: fatihinanc - 18 Ocak 2012, 23:46:46
STM32F4 Discovery üzerindeki ST Link tarafından debug yapabilirsiniz.
Bu arada derleyici o tanımladığını dizi için ancak kullanıldığı zaman derlemede yer ayırıyor. Yoksa oraları zaten boş diye derlemeye almıyor.
Eğer kod içerisinde dinamik olarak kullanırsanız o zaman muhtemelen hata/uyarı mesajı alırsınız. Diğer türlü sabit olarak tanımlarsanız yani ana program içerisinde dizi değişkenlerine atama yapmazsanız o zaman da static olarak derleme esnasında flasha gömülüyor değerler. Ve bu sebepten dolayı da yine RAM de yer tutmuyor.
Ben kullanıyorum, kullandığım zaman da göçüyor o noktaya kadar program normal işliyor o noktadan sonra göçüyor.Bende şu anda c4 yok c3 ile çalışıyorum zorunlu olarak o sebeple debugger da yok sadece uart ıle programı atabiliyorum.
Alıntı yapılan: mcan - 18 Ocak 2012, 21:14:10
Tanımlayabileceğimiz maximum char dizisi kaç elemanlı olabilir? Ben kullandığım işlemcinin ram kapasitesinden daha büyük diziler tanımladığımda bana herhangi bir hata vermiyor ve programı çalıştırdığımda çakılıyor. Sanırım exeption olayından biri gerçekleşiyor .Debuggerım yok. Hafıza sınırlamalarını hangi kaynakdan okurum? Birde keilin kullandığım mcu nun ram*rom sınırlarını aştığımda bana uyarı vermesini nasıl sağlarım.
Dizide index boyutunu yazıyor musun? Mesela aşağıdaki gibi. Kullandığın işlemcinin hafızası kadar sınırın varsa okadar denebilir veya tanımlayabilecek variable kadar. Fakat programın büyüktür ve global değişkenlerin çoktur bunları hafıza sayısından düşmen gerekir ve tabii ektradan derleyicininde yaz boz yapacağı ram kadar bırakman gerekir yoksa arm'ı pic gibi hafızadan hafızaya data taşımak zorunda bırakırsın.
(piclerde bank işlemi)
char MyArray[20000];
ADC registerlarının ayarlanması ile ilgili bir örnek var mı acaba ? Konfigrasyon aşamasında hangi sıra ile gitmeliyiz ? En basitinden, tek bir adc çevrimi için hangi registerlar set edilmeli ?
Tüm pinlerde analog giriş işlemi yapılabiliyor mu? Yoksa piclerde olduğu gibi sadece bazı pinler mi bu iş için tahsis edilmiş? MODER registerlarındaki ilgili pinler "11: Analog mode" değerine set edildiğinde ADC işlevini gerçekleştiriyorsa, bu tüm pinlerin ADC için kullanılabileceğini mi belirtiyor ?
Yazmaya başladığım kod şu şekilde, fakat son kısmında takıldım:
GPIOC->MODER |= 0x03; // C0 pini Analog ("11") olarak ayarlandı
RCC->APB2ENR |= (1<<8); // ADC1 için clock sinyali aktif
ADC1->SQR1 = 0x00000000; // 1 çevrim yapılacak
ADC1->SQR2 = 0x00000000;
ADC1->SQR3 = ??? ; // Burada 1.sıradaki çevrim için 4 bitlik SQ1[4:0] alanına ne yazmam gerekiyor ? 1. çevrim için kullanacağımız pini mi yazacağız ? Eğer öyleyse C0 pinini nasıl yazacağım ?
Bir de adc konusundaki registerlarda , aynı registerların "injected" olanları var. Injected tam olarak ne anlama geliyor ?
Tüm pinlerde analog giriş işlemi yapılabiliyor mu? Yoksa piclerde olduğu gibi sadece bazı pinler mi bu iş için tahsis edilmiş? Her ADC'nin (adc1 , adc2 , adc3) kendine has pinleri mevcut.
MODER registerlarındaki ilgili pinler "11: Analog mode" değerine set edildiğinde ADC işlevini gerçekleştiriyorsa, bu tüm pinlerin ADC için kullanılabileceğini mi belirtiyor ?
Tüm pinler için analog ayarlayabileceğini sanmıyorum. http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/DM00037051.pdf s.43 teki tabloda hangi pin ne fonksiyonu var yazıyor.
injected ve regular adc ler var. Tam olarak bende kavrayamadım ama injected özel uygulamalar için bir çözüm olabiliyormuş. Regularde bir çevrim bitmeden ikinci çevrime başlayamazken (bir adcx için) injected de ise bir adc ye ait kanal sampling süresi ardından daha convertion bitmeden aynı adc ile farklı bir kanaldan 2. çevrime başlayabiliniyor sanırım.
Mesela o tablodaki "Alternate Functions" sütunundaki ADC123_IN0 yazan pin, ADC1 ADC2 ve ADC3 için 0.Input anlamında mı oluyor? _IN kısmını hep external interrupt olarak düşünmüştüm.
Bu durumda ADC girişi için MODER'den "11: Analog mode" yerine "10: Alternate function mode" mu seçmemiz gerekiyor ?
Bir de ADC1_SQR3 yerine ne yazmamız gerekiyor o zaman?
128x64 grafik lcd driver ı var mı arkadaşlar ?
adc ve diğer denemelerde ekran çok lazım oluyor.
Alıntı yapılan: pcb - 19 Ocak 2012, 14:37:41
128x64 grafik lcd driver ı var mı arkadaşlar ?
adc ve diğer denemelerde ekran çok lazım oluyor.
lcd çözümü için ben şu yolu kullandım ;
https://www.picproje.org/index.php/topic,37143.0.html
ErsinErce arkaşımız da KS0108 için bir driver yapmış.
https://www.picproje.org/index.php/topic,37118.msg268952.html#msg268952
Alıntı yapılan: uicroarm - 19 Ocak 2012, 09:51:25
Dizide index boyutunu yazıyor musun? Mesela aşağıdaki gibi. Kullandığın işlemcinin hafızası kadar sınırın varsa okadar denebilir veya tanımlayabilecek variable kadar. Fakat programın büyüktür ve global değişkenlerin çoktur bunları hafıza sayısından düşmen gerekir ve tabii ektradan derleyicininde yaz boz yapacağı ram kadar bırakman gerekir yoksa arm'ı pic gibi hafızadan hafızaya data taşımak zorunda bırakırsın.
(piclerde bank işlemi)
char MyArray[20000];
Merhaba hocam kullandığım işlemci stm32f103 512kb rom ve 64 kb ram var 64 pinli. Programda yazdığım bir fonksiyon içerisinde dizi tanımlıyorum şu şekilde ;
void fonksiyon (void)
{
char dbuffer[65537];
dbuffer[65535]=1;
}
Main fonksiyonu içerisinden de bu fonksiyonu çağırıyorum,ancak derleme esnasında hiçbir hata almamama rağmen program fonksiyon çağırılıncaya kadar çalışıp sonrasında duruyor. Eğer tanımlarken bin katı kadar tanımlama yaparsam ( char dbuffer[65537000] ) aşşağıdaki hatayı alıyorum.
Bana göre olması gereken 65536 sayısında bile hata vermesi gerekirdi.Acaba değişkeni ram üzerine değilde rom üzerine mi tanımlıyor?
sd_spi_stm32.c: Error: C3048U: out of store while compiling with -g. Allocation size was 131076096, system size is 1740855276
Alıntı yapılan: GreeN - 19 Ocak 2012, 14:42:52
lcd çözümü için ben şu yolu kullandım ;
https://www.picproje.org/index.php/topic,37143.0.html
pcb yi basıp ekranı çalıştırabildiniz mi ? yoksa hiç 128x64 lcd ile uğraşmayalım mı?
Alıntı yapılan: NecroCapo - 19 Ocak 2012, 14:29:22
Mesela o tablodaki "Alternate Functions" sütunundaki ADC123_IN0 yazan pin, ADC1 ADC2 ve ADC3 için 0.Input anlamında mı oluyor? _IN kısmını hep external interrupt olarak düşünmüştüm.
Bu durumda ADC girişi için MODER'den "11: Analog mode" yerine "10: Alternate function mode" mu seçmemiz gerekiyor ?
Bir de ADC1_SQR3 yerine ne yazmamız gerekiyor o zaman?
Hayır alternatif mod seçmeyeceksin. Analog seçeceksin.
PORTC0 kullanacağına göre kanal numaran 10.
ADC kısmını tam okumadım daha. Bu yüzden sequence registeri tam olarak ne yapıyor bilmiyorum. Tahminen, birden fazla kanalın varsa kanalların çevrime girme sıralamasını kullanıcının ayarlamasını sağlıyor. Eğer böyle ise , birinci çevrimde senin kanalını sıraya alması için
ilk 5 bit (SQ1) değerin kanal numaran 10 olduğu için 0xA olmalı. ( bu sadece tahmine dayalı bir yorum.)
Alıntı YapHayır alternatif mod seçmeyeceksin. Analog seçeceksin.
PORTC0 kullanacağına göre kanal numaran 10.
ADC kısmını tam okumadım daha. Bu yüzden sequence registeri tam olarak ne yapıyor bilmiyorum. Tahminen, birden fazla kanalın varsa kanalların çevrime girme sıralamasını kullanıcının ayarlamasını sağlıyor. Eğer böyle ise , birinci çevrimde senin kanalını sıraya alması için
ilk 5 bit (SQ1) değerin kanal numaran 10 olduğu için 0xA olmalı. ( bu sadece tahmine dayalı bir yorum.)
Teşekkürler çok açıklayıcı oldu. Aynen dediğiniz gibi, çevrime girme sıralaması için kullanılıyor. Fakat PORTC0'ın kanal numarasının 10 olduğunu nereden buldunuz ?
Peki arkadaşlar kartı nasıl kullanıyorsunuz? bir alt kart yaptınız mı?
@mcan
ben deneyemedim,açıkçası ram kullanımına dikkat ettiğim için böyle karşılaşmadım tabii yanlışlıkla yazılabilir, az özce keilin forumuna baktım birkaç kişi max ram için tanımlama yapmış ve array tanımlarken array max ramden çok ise error direktifi ile compilera msj yazdırmışlar. Keil forumunda sorarsan daha kesin bir cevap alırsın.
Alıntı yapılan: pcb - 19 Ocak 2012, 14:55:40
pcb yi basıp ekranı çalıştırabildiniz mi ? yoksa hiç 128x64 lcd ile uğraşmayalım mı?
PCB yi hazırladım ama montaj için vakit bulamadım. Kısmetse haftasonuna...
Alıntı yapılan: NecroCapo - 19 Ocak 2012, 15:48:39
Teşekkürler çok açıklayıcı oldu. Aynen dediğiniz gibi, çevrime girme sıralaması için kullanılıyor. Fakat PORTC0'ın kanal numarasının 10 olduğunu nereden buldunuz ?
Hard:43 den başlayan bir tablo var. Alternatif fonksiyonları gösteriyor. Alternatif fonksiyon demesi kafanızı karıştırmasın. Analogları da alternatif fonksiyon gibi değerlendirip , başka bir gurup olduğunu göstermek için de koyu harflerle yazmış. Oradan tüm ADC kanallarının hangi portlara bağlı olduğunu bulup bir tablo çıkardım.
ADC Kanal Port
1-2-3 IN0 A0
1-2-3 IN1 A1
1-2-3 IN2 A2
1-2-3 IN3 A3
1-2 IN4 A4
1-2 IN5 A5
1-2 IN6 A6
1-2 IN7 A7
1-2 IN8 B0
1-2 IN9 B1
1-2-3 IN10 C0
1-2-3 IN11 C1
1-2-3 IN12 C2
1-2-3 IN13 C3
1-2 IN14 C4
1-2 IN15 C5
Klein hocam süpersiniz. Çok iyi oldu bu, şimdi taşlar yerine oturdu :)
Ben alt kart için bir plaket aldım onun üzerine aklıma geldikçe eklemeler yapacağım. Şimdilik aldıklarım bunlar:
(http://s14.postimg.cc/4w0x75j69/IMG00003.jpg)
Sizler nasıl yapıyorsunuz arkadaşlar? (sormuştum arada kaynadı gitti :D)
Ben ADC için bir örnek yaptım. Biraz da alıntı yaptım bunalmıs hocanın kodlarından. Program ADC'yi interrupt ile okuyor okuduğu bilgiyi usart3 modülünden gönderiyor. Program denendi çalışıyor. PA0 pininden okuma yapılıyor.
#include <stm32f4xx.h>
unsigned int i,x,en,an;
void SystemInit(void)
{
// Burası alıntıdır.
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim 168 Mhz
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000001F; // GPIO A,B,C,D,E clock'u aktif edelim
GPIOD->MODER = 0x55550000; // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
void USART3_IRQHandler()
{
//Burası Alıntıdır.
volatile int Sts;
Sts=USART3->SR;
//RxBuf[WAdr]=USART3->DR;
x=USART3->DR;
}
void ADC_IRQHandler (void)
{
volatile int Sts;
Sts=ADC2->SR;
an=ADC2->DR;
en=1;
}
void UsartInit()
{
// Burası alıntıdır.
// USART3 MODULUNU AKTIF HALE GETIRELIM
RCC->APB1ENR|=0x00040000; // USART3 Clk Enable (Rehber Sayfa 113)
RCC->APB1RSTR|=0x00040000; // USART3 Resetlendi
GPIOB->AFR[1]=0x07777700; // PB10..PB14 pinleri USART3 ile alakalandirildi (Hard Sayfa 49)
GPIOB->MODER|=0x2AA00000; // GPIOB 10..14 icin alternatif fonksiyon tanimi (Rehber Sayfa 148)
// USART3 MODULUNU AYARLAYALIM // 1 Start, 8 Data, 1 Stop, No parity (Default degerler)
RCC->APB1RSTR&=~0x00040000; // USART3 Reseti kaldiralim
// USART3->SR&=~0X03FF; // Status registeri silelim
USART3->BRR=0X1112; // 9600 Baud
USART3->CR1|=0x0000202C; // USART3 enable
NVIC->ISER[1]|=0x80; // NVIC da USART3 interrupta izin verelim
}
void SendChar(char Tx)
{
// Burası alıntıdır.
while(!(USART3->SR&0x80)); // TX Buffer dolu ise bekle (Rehber Sayfa 646)
USART3->DR=Tx;
}
void SendTxt(char *Adr)
{
//Burası alıntıdır.
while(*Adr)
{
SendChar(*Adr);
Adr++;
}
}
void AdcInit(void)
{
unsigned long i;
RCC->APB2ENR |= 0x00000700; // ADC Clock aktif.
RCC->APB2RSTR |=0x00000100; // ADC Resetlendi.
GPIOA->MODER |=0x00000003; // PA0 Analog olarak ayarlandı.
RCC->APB2RSTR &=~0x00000100;
ADC2->CR2 |=0x00000003; // ADC Aktif edildi, Continuous mod seçildi.
for(i=0;i<0x1000000;i++); // Biraz Beklemek Gerekiyor.
ADC2->CR1 |= 0X00000020; // 12 Bitlik çevirim yapılacak ve interrupt aktif.
NVIC->ISER[0]|=0x00040000; // ADC interrupt aktif ediliyor.
ADC2->CR2 |= 0x40000000; // ADC Çevirimi başlatıldı.
}
void SendInt (unsigned long sayi)
{
unsigned char dizi[10];
unsigned char i,durum=0;
for(i=0;i<=9;i++)dizi[i]=0;
if(sayi==0){
SendChar('0');
}
else{
dizi[0]=sayi/1000000000;
sayi-=dizi[0]*1000000000;
dizi[1]=sayi/100000000;
sayi-=dizi[1]*100000000;
dizi[2]=sayi/10000000;
sayi-=dizi[2]*10000000;
dizi[3]=sayi/1000000;
sayi-=dizi[3]*1000000;
dizi[4]=sayi/100000;
sayi-=dizi[4]*100000;
dizi[5]=sayi/10000;
sayi-=dizi[5]*10000;
dizi[6]=sayi/1000;
sayi-=dizi[6]*1000;
dizi[7]=sayi/100;
sayi-=dizi[7]*100;
dizi[8]=sayi/10;
sayi-=dizi[8]*10;
dizi[9]=sayi%10;
for(i=0;i<=9;i++)
{
if(dizi[i]!=0)
{
durum=1;
}
if(durum==1){
switch (dizi[i]){
case 0:
SendChar(48);
break;
case 1:
SendChar(49);
break;
case 2:
SendChar(50);
break;
case 3:
SendChar(51);
break;
case 4:
SendChar(52);
break;
case 5:
SendChar(53);
break;
case 6:
SendChar(53);
break;
case 7:
SendChar(55);
break;
case 8:
SendChar(56);
break;
case 9:
SendChar(57);
break;
default:
break;
}
}
}
}
}
int main(void)
{
UsartInit();
AdcInit();
SendTxt("Deneme");
SendChar(' ');
while(1){
if(en==1){
SendInt(an);
SendChar(' ');
SendChar(' ');
SendChar(' ');
SendChar(' ');
en=0;
}
}
}
ekrana yazdırma dışında bana yetebilecek örnekler oluştu neredeyse
peki arkadaşlar kendi kartımızı hazırladığımızda bu programları nasıl gönderebiliriz işlemciye ?
Mikroişlemci gibi bir yükleyici yok bildiğim kadarı ile , karta yükleme devresini de ilave etmemiz mi gerekiyor ?
Dahili bootloaderleri kullanılarak LPC ' lerdeki gibi seri porttan yüklenebilir.
Alıntı yapılan: pcb - 20 Ocak 2012, 13:57:24
ekrana yazdırma dışında bana yetebilecek örnekler oluştu neredeyse
peki arkadaşlar kendi kartımızı hazırladığımızda bu programları nasıl gönderebiliriz işlemciye ?
Mikroişlemci gibi bir yükleyici yok bildiğim kadarı ile , karta yükleme devresini de ilave etmemiz mi gerekiyor ?
Discovery kartımız üzerinde programlama ünitesi mevcut. Kendi yaptığın kartın SWD pinlerine bağlayacağın kabloları Discovery kartının SWD pinlerine bağladığında program atarsın. Yapacağın tek şey Discovery kartında jumper pozisyonlarını değiştirmek.
Bu jumperlar SWD ünitesini ya senin kartdaki CPUya yada Discovery üzerindeki CPUya ilişkilendiriyor.
örnek olması açısından
Nvic de
OTG_HS int açmak için komutun ne olması gerekir ?
NVIC->????????=?????
Alıntı yapılan: muhittin_kaplan - 21 Ocak 2012, 15:39:58
örnek olması açısından
Nvic de
OTG_HS int açmak için komutun ne olması gerekir ?
NVIC->????????=?????
NVIC->ISER[2]=(1<<13)
Alıntı Yap// Bu kısım Timer 7 den çekilen kopya.
RCC->APB1ENR|=0x00000001; // Timer2 CLK'u aktif edelim (84 Mhz)
TIM2->PSC = 4199;
TIM2->ARR = 2000;
TIM2->DIER = 0x0001;
bu değerlere göre timer 2 kesme zamanı nedir ?
(http://img542.imageshack.us/img542/813/clockp.jpg)
Cortex M4 için NVIC dökümanına ihtiyacım var. Elinde olan, gören , duyan paylaşabilirmi ?
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/BHCFCFDB.html bnun dışında bir kaynak yok elimde.
Tamam. Buraya bende baktım, baktım ama döküman içerisinde "NVIC->ISER[1]|= 0x80; // NVIC da USART3 interrupta izin verelim" bunun açıklamasını bulamadım. Veya NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim bunun. Yada NVIC->ISER[0] = 0x00000040; // NVIC EXTI0_IRQ interrupti acalim bunun
Herhangi bir ARM CM3 cipin NVIC dokumanina bakin.
http://www.fileserve.com/file/u56Ky3J/nvic.xlsx
"core_cm4.h" dosyasını incelemekte fayda var.
Interrupt Enable bitleri ISER registerlerinde bulunuyor. Bunlardaki her bit bir tane kesmeyi açıyor ya da kapatıyor.
ISER registerleri 32 bitlik 8 elemandan oluşan bir array. 8x32 =256 toplamda 256 tane interrupt kontrol edilebilir.
"core_cm4.h" içerisinde tanımlılar. typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
...
}
NVIC->ISER[0] |=0x00000001 dediğimizde İlk interrupt'a izin vermiş oluyoruz.
Peki bu ilk interrupt hangisi. Bu sanıyorum çipin üreticisine göre değişiyor. Bu yüzden Cortex-M dokümanlarında bulunmuyor. Belki üreticiler arasında bir standartlaşma vardır. Onu bilmiyorum.
Bizim çipimiz STM32F4XX olduğu için kaçıncı kesmenin ne olduğunu bulmak için Rehber:196'ya bakıyoruz.
Tablonun en solundaki sayı bizim kesmemizin bu array içindeki yerini gösteriyor.
ISER[0]'ın 0. biti WWDG (Window Watch Dog) kesmesiymiş.
Diyelim ki TIMER7 kesmesini arıyoruz. Rehber:196.. dan bakıyoruz. Pozisyonumuz 55. yani 55. bitteyiz. Gerisi bit hesabı.
Bit hesabını bilmeyenler , elinde bit sayan hesap makinası yoksa basitçe yeri şöyle bulabilir.
55. bit ISER'in neresinde? ISER registerlerimiz 32 bit. 55/32 = 1.71... tam kısım 1 yani ISER[1] deymişiz.
Ama ben bit hesabı yapmak istemiyorum derseniz , "core_cm4.h" size kolaylıklar sunmuş.
NVIC_EnableIRQ(TIM7_IRQn);
NVIC_DisableIRQ(TIM7_IRQn);
hocam yukarda bir XLS dosya yaptım NVIC için. Hata yoktur diye umut ediyorum
Ve soruma geçiyorum
RCC->APB1ENR|=0x00000002; // Timer3 CLK'u aktif edelim (84 Mhz)
TIM3->PSC = 4199;
TIM3->ARR = 2000;
TIM3->DIER = 0x0001;
// Bu kısım Rehberde verilen talimatlar
TIM3->CCMR1 |= 0x0002; //CCR 1 için Giriş kaynağı TI2 seçildi
TIM3->CCER &= ~0x000A; // TI1FP1 için polarite seçimi. evirilmemiş / yükselen kenar
TIM3->CCMR1 |= 0x0200; //CCR 2 için Giriş kaynağı TI1 seçildi
TIM3->CCER |= 0x0020; // TI1FP2 için polarite seçimi. evirilmiş / düşen kenar
TIM3->SMCR |= 0x0050; // geçerli tetikleme kaynağı TI1FP1
TIM3->SMCR |= 0x0004; // Slave mode = reset Yükselen kenarda sayıcıyı sıfırla ve değeri güncelle.
TIM3->CCER |= 0x0011; // CC1 ve CC2 aaktif.
// Bu kısım PA 15 portunu TIM5 ile ilişkilendiren Alternatif fonksiyon tanımlama
GPIOC->MODER &=0xFFFF2FFF;//
GPIOC->PUPDR |=0x00001000; // Port PULL_UP direncini aç
GPIOC->AFR[0]|=0x02000000; // PC6 Portu TIM3 ile ilişkilendir.
// Bu kısım interrupt aktif etme ve sayıcıyı başlatma
NVIC->ISER[0]|=0x20000000; //Timer 0 interrupt aktif et;NVIC->ISER[0]|=0x10000000
TIM3->CR1 |= 0x0001; // sayıcıyı başlat.
}
void TIM3_IRQHandler()
{
ccp_update=1;
ccr3_1=TIM3->CCR1;
ccr3_2=TIM3->CCR2;
SendChar(ccr3_2+0x2D); //deger A dan başlaması için bu işlem yapıldı
TIM3->SR=0;
}
PWM girişi olarak PC6 da hatam nerede ki çalışmıyor (CCR2 de hiç değer yok)
-- GPIOC->AFR[0]|=0x02000000; // PC6 Portu TIM3 ile ilişkilendir.-- Olarak değiştirilde Hala Çalışmıyor
Alıntı yapılan: Klein - 22 Ocak 2012, 21:26:04
"core_cm4.h" dosyasını incelemekte fayda var.
Interrupt Enable bitleri ISER registerlerinde bulunuyor. Bunlardaki her bit bir tane kesmeyi açıyor ya da kapatıyor.
ISER registerleri 32 bitlik 8 elemandan oluşan bir array. 8x32 =256 toplamda 256 tane interrupt kontrol edilebilir.
"core_cm4.h" içerisinde tanımlılar. typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
...
}
NVIC->ISER[0] |=0x00000001 dediğimizde İlk interrupt'a izin vermiş oluyoruz.
Peki bu ilk interrupt hangisi. Bu sanıyorum çipin üreticisine göre değişiyor. Bu yüzden Cortex-M dokümanlarında bulunmuyor. Belki üreticiler arasında bir standartlaşma vardır. Onu bilmiyorum.
Bizim çipimiz STM32F4XX olduğu için kaçıncı kesmenin ne olduğunu bulmak için Rehber:196'ya bakıyoruz.
Tablonun en solundaki sayı bizim kesmemizin bu array içindeki yerini gösteriyor.
ISER[0]'ın 0. biti WWDG (Window Watch Dog) kesmesiymiş.
Diyelim ki TIMER7 kesmesini arıyoruz. Rehber:196.. dan bakıyoruz. Pozisyonumuz 55. yani 55. bitteyiz. Gerisi bit hesabı.
Bit hesabını bilmeyenler , elinde bit sayan hesap makinası yoksa basitçe yeri şöyle bulabilir.
55. bit ISER'in neresinde? ISER registerlerimiz 32 bit. 55/32 = 1.71... tam kısım 1 yani ISER[1] deymişiz.
Ama ben bit hesabı yapmak istemiyorum derseniz , "core_cm4.h" size kolaylıklar sunmuş.
NVIC_EnableIRQ(TIM7_IRQn);
NVIC_DisableIRQ(TIM7_IRQn);
Dökümandan bile iyi bir anlatım olmuş. Kafamdaki tüm soru işaretleri kalktı. Teşekkür ederim. ::)
@muhittin
Çalışmaması için bir sebep yok gibi görünüyor. Belki benim de gözden kaçırdığım bir yer vardır.
gelen PWM'in genişliği çok uzun olabilir.
Biraz sonra kiti kurar bir denerim. Debug modda ortaya çıkar.
20ms lik peryotta %10 ile %20 duty. ama çalıştıramadım.
sorun bu satırda GPIOC->MODER &=0xFFFF2FFF;// ilk bakışta farkedilmesi gereken bir satır. Güzel saklanmış :)
Açılışta MODER registerimiz 0x00000000 0xFFFF2FFF ile & yaptığımızda yine sıfır. CCR1'de var sıfır :)
GPIOC->MODER |=0x00002000; şeklinde düzeltirsen çalışır.
hemen deniyorum :-[
TIM3->CCMR1 |= 0x0002; //CCR 1 için Giriş kaynağı TI2 seçildi
Bu satırı
TIM3->CCMR1 |= 0x0001; //CCR 1 için Giriş kaynağı TI1 seçildi
şeklinde düzeltirsen peiyot ölçümü de yapar. Yanlışlıkla kaynağı TI2 seçmişiz.
Hocam Orayı Fark ettim ama kendime güvenmediğimden "Vardır bir bildiği, Her moku da sormayalım artık" diyerek es geçmiştim.
arkadaşlar 12864 grafik ekran ile uğraşıyorum , ekrana yazdırma komutu
printf( "Please input two numbers to be multiplied: " ); şeklinde mi ?
Alıntı yapılan: pcb - 24 Ocak 2012, 12:45:22
arkadaşlar 12864 grafik ekran ile uğraşıyorum , ekrana yazdırma komutu
printf( "Please input two numbers to be multiplied: " ); şeklinde mi ?
kullandığın kütüphanede fonksiyon ne olarak isimlendirilmişse o şekilde kullanabilirsin. putchr(); vs de olabilir.
kullandığın kütüphanede fonksiyon ne olarak isimlendirilmişse o şekilde kullanabilirsin. putchr(); vs de olabilir.
aşağıda ki kod daki gibi mi ?
/* Public Functions */
extern void init_ks0108(void);
extern void gotoxy_ks0108(unsigned char, unsigned char);
extern void putc_ks0108(unsigned char);
extern void puts_ks0108(unsigned char*);
extern void cls_ks0108(void);
puts_ks0108("deneme");
putc_ks0108(d);
putc_ks0108(e);
putc_ks0108(n);
putc_ks0108(e);
putc_ks0108(m);
putc_ks0108(e);
evet bunlar gibi.
Selamlar,
Bu gün systick olayını denemek istedim. Bazı dökümanlar okudum ancak hala anlamadım systick bir timer mi yoksa sadece kesmemi? Eğer kesme ise bunun diğer kesmelerden bir farkı varmı? Bu kesmeyi işletirken işlemci işini gücünü bırakıp bu kesmeyimi işliyor? Yani her 1 us de bir systick içindeki değişkeni update etmek istersek işlemciyi saniyede 1 milyon kere işini kesmiş mi olacağız?
sanki evet. ama bu tik zamanlayıcı vs için değilde multitasking yapmak için konulmuş gibi geliyor bana.
Alıntı yapılan: mcan - 24 Ocak 2012, 21:12:06
Selamlar,
Bu gün systick olayını denemek istedim. Bazı dökümanlar okudum ancak hala anlamadım systick bir timer mi yoksa sadece kesmemi? Eğer kesme ise bunun diğer kesmelerden bir farkı varmı? Bu kesmeyi işletirken işlemci işini gücünü bırakıp bu kesmeyimi işliyor? Yani her 1 us de bir systick içindeki değişkeni update etmek istersek işlemciyi saniyede 1 milyon kere işini kesmiş mi olacağız?
Sys Tick, timer ozellikleri acisindan diger timerlardan ekstarasi yok hatta eksikleri var. Fakat bu timer dogrudan CPU ya int yolluyor. Timer ile CPU arasinda NVIC yok.
User modunda bu timera ulasma sansiniz yok. Cekirdek kodlar yazip bununla olaylari yonetmek icin kullaniliyor. User moddaki programlarin bu timera erismesi mumkun olmadigindan
zamanlamanin bozulmasi mumkun degil.
Alıntı yapılan: bunalmis - 24 Ocak 2012, 22:00:09
Sys Tick, timer ozellikleri acisindan diger timerlardan ekstarasi yok hatta eksikleri var. Fakat bu timer dogrudan CPU ya int yolluyor. Timer ile CPU arasinda NVIC yok.
User modunda bu timera ulasma sansiniz yok. Cekirdek kodlar yazip bununla olaylari yonetmek icin kullaniliyor. User moddaki programlarin bu timera erismesi mumkun olmadigindan
zamanlamanin bozulmasi mumkun değil.
Hocam bu timer arada nvic olmadiği için işlemcinin zamanından sadece 1 cycle mi alıyor contex saving filan yapılmıyormu? Birde bu bir timer ise interrupt aktif etmesek nasıl bir şekilde kullanırız? User modundan başka hangi modlar var ve o modlara geçiş nasıl oluyor.
1 cycle degil tabiki. Context saving islemini yapmak NVIC in isi degil zaten bu isi CPU yapiyor. Sys Tick interruptin onceligi cok yuksek. Butun espirisi bu.
User mod yerine protected mod var. Zaten su anda yazdigimiz kodlar protected modda. User moda gectikmi geri donus yok. Ancak privileged seviyede tekrardan protected moda gecebiliriz. Mod gecis isleri control register uzerinden yapiliyor.
Hocam Usart Programında;
iki yada daha fazla ölçüm değerini (PWM) PC ye göndermem gerekiyor, C kullanarak nasıl yapılır;
IAR EW kullanan arkadaşlar debug yapmadan doğrudan download işlemini nasıl yapıyor ?
Project -> Download -> Download Active Application yolu var. Ben bunu kullanıyorum ama bu seçenekte kodu yükledikten sonra reset atmıyor...
Sizler nasıl yapıyorsunuz ?
Alıntı yapılan: muhittin_kaplan - 25 Ocak 2012, 00:20:12
Hocam Usart Programında;
iki yada daha fazla ölçüm değerini (PWM) PC ye göndermem gerekiyor, C kullanarak nasıl yapılır;
Neyseki Çözdüm..
SendChar ile Byte Byte Gönderdiğim değerlerin ardına Null değeride ekledim ve PC programında bu null değeri sorgulattım. Null değer geldiğinde İletişimin Bittiğini anlayarak Pc Tarafında String Manipulasyon ile istediğimiği istediğim yere aldım.
Merhaba Arkadaşlar;
STM32 ' de PH0 PH1 pinlerinden çıkış alamıyorum. KS0108 driveri yazmaya başlayacaktım, o pinlere de CS1 CS2 ' yi bağlamıştım ama istediğim çıkışı alamıyorum bunun sebebi nedir acaba?
#include "STM32F4xx.h"
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000009F; // GPIO A,B,C,D,E,H clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
void Delay()
{
unsigned int i;
for(i=0;i<0x00001000;i++);
}
int main()
{
GPIOH->MODER=0x00000005; // GPIOH 0. ve 1. Pinler Çıkış Yapıldı
GPIOH->OSPEEDR=0xFFFFFFFF; // GPIOH Çıkışlarını En Yüksek Hızda Kullanacağız
GPIOH->ODR=0x00000001; // GPIOH 0. Pin '1' Yapıldı
GPIOE->MODER=0x55555540;
GPIOE->OSPEEDR=0xFFFFFFFF;
GPIOE->ODR=0x00003F20;
GPIOE->ODR|=0x00000080;
Delay();
GPIOE->ODR&=~0x00000080;
Delay();
while(1);
}
Son günlerde bu başlık biraz öksüz kaldı sanki. Kitler bir köşeye mi atıldı ne?
Halen kitini bir köşeye atmamış olanlar için tek kanal ADC örneği.
#include "STM32F4xx.h"
#include "stdio.h"
unsigned char WAdr,RAdr;
char RxBuf[128];
char TxBuf[128];
unsigned char timer_update=0;
uint16_t adc_val;
/*********************************************************************************
CPU frekansi 168Mhz
AHB frekansi 84 Mhz
APB frekansi 42 Mhz
*********************************************************************************/
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim 168 Mhz
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000001F; // GPIO A,B,C,D,E clock'u aktif edelim
GPIOD->MODER = 0x55550000; // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =839; // Prescaler degerimiz 839, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 84E6 / (840) = 100 KHz
TIM7->ARR =5; // Counter, Decimal 1 olunca basa donsun. Her 20 mikrosaniye de bir timer int olusacak.
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
GPIOB->MODER |= 0x00000003;
RCC->APB2ENR|=0x00000100; // ADC saat kaynağını aktif ettik.
ADC1->CR1 |=0x00000100; // ADC scan modunda çalışacak.
ADC1->SQR3 |= 0x00000008; // Çevrime ilk girecek kanal 8. (PB0)
ADC1->CR2 |=0x00000003; // AD converter'i açtık. Sürekli çevirim yapacağımızı belirttik.
}
/*********************************************************************************
USART3 modulunu kullanarak asenkron haberlesme (Hata kontrolu yapilmiyor)
*********************************************************************************/
void USART3_IRQHandler()
{
volatile int Sts;
Sts=USART3->SR;
RxBuf[WAdr]=USART3->DR;
WAdr=(WAdr+1)&0x7F;
}
void UsartInit()
{
WAdr=0;RAdr=0;
// USART3 MODULUNU AKTIF HALE GETIRELIM
RCC->APB1ENR|=0x00040000; // USART3 Clk Enable (Rehber Sayfa 113)
RCC->APB1RSTR|=0x00040000; // USART3 Resetlendi
GPIOB->AFR[1]=0x07777700; // PB10..PB14 pinleri USART3 ile alakalandirildi (Hard Sayfa 49)
GPIOB->MODER|=0x2AA00000; // GPIOB 10..14 icin alternatif fonksiyon tanimi (Rehber Sayfa 148)
// USART3 MODULUNU AYARLAYALIM // 1 Start, 8 Data, 1 Stop, No parity (Default degerler)
RCC->APB1RSTR&=~0x00040000; // USART3 Reseti kaldiralim
// USART3->SR&=~0X03FF; // Status registeri silelim
USART3->BRR=0X1112; // 9600 Baud
USART3->CR1|=0x0000202C; // USART3 enable
NVIC->ISER[1]|=0x80; // NVIC da USART3 interrupta izin verelim
}
void SendChar(char Tx)
{
while(!(USART3->SR&0x80)); // TX Buffer dolu ise bekle (Rehber Sayfa 646)
USART3->DR=Tx;
}
void SendTxt(char *Adr)
{
while(*Adr)
{
SendChar(*Adr);
Adr++;
}
}
char DataReady()
{
return(WAdr-RAdr);
}
char ReadChar()
{
char Dat;
Dat=RxBuf[RAdr];
RAdr=(RAdr+1)&0x7F;
return(Dat);
}
void TIM7_IRQHandler()
{
TIM7->SR=0;
timer_update=1;
}
// Rx ve TX pinlerini (GPIOB10 ve GPIOB11) birbirine baglarsaniz gonderdiginiz datalar geri gelecektir
int main()
{
unsigned int ledtime;
UsartInit();
SendTxt("PicProje");
ADC1->CR2 |=0x40000000; // ADC çevrimini başlattık.
while(1){
if(ADC1->SR & 0x0002){
ADC1->SR &= ~0x0002;
adc_val = ADC1->DR;
}
if(timer_update){
timer_update=0;
if(++ledtime > 5000){
ledtime =0;
GPIOD->ODR ^= 0x0000008000;
sprintf(TxBuf,"ADC Degeri :%u\r",adc_val);
SendTxt(TxBuf);
}
}
};
}
Register açıklamaları:
RCC->APB2ENR|=0x00000100; // ADC saat kaynağını aktif ettik.
Artk her donanım için clk kaynağını aktif etmemiz gerektiğini , aktif olmadıkları zaman güç tüketiminin düştüğünü biliyoruz. Bu yüzden bunun detayına girmiyorum.
ADC1->CR1 |=0x00000100; // ADC scan modunda çalışacak.CR1 registerinin 8. biti scan modu açma kapama biti.
Eğer scan modu açıksa , kaç tane kanalın taranmasını istediysek o kadar kanalın çevrimi sırayla yapılır. Tüm kanallar bitince çevirim durur.
ADC1->SQR3 |= 0x00000008; // Çevrime ilk girecek kanal 8. (PB0)SQR registerleri hangi kanalın hangi sırayla çevirime gireceğini seçmemizi sağlar. Register 5'er bitlik alanlara ayrılmıştır. Her bir SQR registeri 6 tane kanalın sıralamasını seçmemize izin verir. SQR3 registeri ilk 6 sıra, SQR2 7- 11 arası SQR1 de 12-15 arası olmak üzere toplam 16 kanalın sırasını seçmemize olanak verir.
SQR1 reg isterini diğer SQR registerlerinden ayıran özellik ise, Bu registerin 20-21-221 ve 23. bitlerinden scan modda kaç kanalın taranacağını seçebiliyor olmamızdır.
Örneğimiz tek kanal olduğu için sadece İlk sıraya kanal numarası girdik diğerlerine bir şey girmedik. PB0 8. kanal olduğu için bu registere 8 yazdık.
ADC1->CR2 |=0x00000003; // AD converter'i açtık. Sürekli çevirim yapacağımızı belirttik.
CR2 registerinin ilk biti ADON bitidir. ADC'yi açma ve kapatmayay yarar. Burada dikkat edilmesi gereken şey ADC ON yapıldıktan sonra stabil olması için bir süre geçmesi gerekliliğidir. Stabil olduktan sonra çevirimi başlatmak gerek. Rehberde bununla ilgili açıklama var.
CR2 registerinin 1. biti ise continious mode seçim bitidir. Eğer 0 ise single 1 ise Continious modda çalışır.
ADC1->CR2 |=0x40000000; // ADC çevrimini başlattık.
CR2 registerinin 3. biti çevirimi başlatır. Continious mode seçili olduğu için bir kez başlatmak yeterlidir. Eğer single modda olsaydık. çevirim bittikten sonra başlatmak için yeniden set etmemiz gerekecekti.
Bu ve diğer bazı örnekler "örnekler" başlığı altında olsa daha ulaşılabilir olacak. Ancak yazmaya kapalı olduğu için atamadım.
Olurmu Hocam Kitle Çalışmaya Devam..
aksine daha yeni birşeyler yapmaya başladım.
15 tatilde çalışmalarım full speed gidiyordu. :D Ama okul açılınca durma noktasına kadar yavaşlıyor maalesef. :( Ders çalışıyorum. Tatilde kartın yarısını tamamladım. Temel elemanları koydum.
(http://s16.postimg.cc/s4ad7f391/IMG00042.jpg)
(http://s8.postimg.cc/tnxqizrqd/IMG00029.jpg)
(http://s18.postimg.cc/fsxqtbxvt/IMG00043.jpg)
Herkese kolay gelsin.
Bu kiti görünce nedense 1990 larda tasarlanmış yerlimalı en baba elektronik kit denen EBEK kod adlı bir kit vardı bogazicinden bir prof tasarlamıştı 8 bitlik 6502 mikroişlemci mimarili ses kasetlerine data kaydı yapan özellikli bir cihazdı :)Şİmdilerde ünv lerde kimse, yaa kendi kitimizi yapalım özgün özellikli bişi olsun diye çabalamıyor. 1990 lardan bile gerideyis sanki...
Herkese merhabalar;
Forumda ilk mesajım :) uzun zamandır uzaktan izliyorum arm bölümünü :D gerçeği söylemek gerekirse arm hakkında bu kadar türkçe kaynak bulacağım hiç aklıma gelmemişti emeği geçenlere teşekkür etmek isterim.
STM32F4 kitim bu gün elime ulaştı ve örneklerden bir kaç tanesini başarıyla çalıştırdım.İşin teorik kısmında anladığımı düşünüyorum.Ama çok önemli bir şey kaynamış gitmiş burada.Hangi sayfada olduğunu tam olarak hatırlamıyorum ama bunalmıs hocamız SystemInit fonksiyonuna ne kod yazacağımızı nereden bildik diye sormuştu sonra araya tartışma girdi bu önemli soru da kaynadı gitti :).
Rica etsem SystemInit i nasıl yazacağımızı nereden anladık öğrenebilir miyim?
Alıntı yapılan: pisayisi - 07 Şubat 2012, 18:44:22
Bu kiti görünce nedense 1990 larda tasarlanmış yerlimalı en baba elektronik kit denen EBEK kod adlı bir kit vardı bogazicinden bir prof tasarlamıştı 8 bitlik 6502 mikroişlemci mimarili ses kasetlerine data kaydı yapan özellikli bir cihazdı :)Şİmdilerde ünv lerde kimse, yaa kendi kitimizi yapalım özgün özellikli bişi olsun diye çabalamıyor. 1990 lardan bile gerideyis sanki...
Amacım reklam değil : http://www.expkits.com/ . Yapılan kitler var .
Ama kit işi genelde yarı iletken üreticilerinin elinde , bir çeşit pazarlama aracı sonuçta.
Alıntı yapılan: EMG81 - 12 Aralık 2011, 14:16:58
Ben STM32 Kartımı çok önceden almıştım. Fakat işten güçten anca dün adam biraz ilgilenebildim. Oturdum HD44780 chipli 2x16 Lcd için kod yazdım. Dün elimde Lcd olmadığı için deneyemedim. Aslında bu gün de deniyemiyecektim ama Tesadüfen elime bir tane geçti. Denedim Tüm Fonksiyonlar çalışmakta.
Main.c;
#include "STM32F4xx.h"
#include "Delay.c"
#include "HD44780.c"
void SystemInit(void)
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55005555; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
GPIOB->MODER = 0x00000500; // GPIOB 4 ve 5 i çıkış yaptık.
GPIOA->OSPEEDR= 0x00000000; // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
GPIOB->OSPEEDR= 0x00000000; // AYnı şey GPIOB içinde geçerli
GPIOC->OSPEEDR= 0xFFFFFFFF;
GPIOD->OSPEEDR= 0xFFFFFFFF;
}
int main(void)
{
void SystemInit();
while(1)
{
Lcd_init();
Lcd_Imlec_Yok();
Lcd_Yaz(" PicProje"); Lcd_Git(2,6);
Lcd_Yaz("Emg81");
Delay_ms(2000);
// Bit Banding
GPIO_D(15)=1;
Delay_ms(1000);
GPIO_D(15)=0;
Delay_ms(1000);
GPIO_D(14)=1;
Delay_ms(1000);
GPIO_D(14)=0;
Delay_ms(1000);
}
}
Delay.c;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Kullanılışı;
// Delay_ms(100); // 100 msn Bekle.
// Delay_us(100); // 100 usn Bekle.
// Not CPU OSC = 168 mhz - 210 MIPS
#include "Delay.h"
void Delay_ms(unsigned long Bekle)
{
Bekle = Bekle * 21008; // mSn ye ye çevirdik. OSC 168Mhz de uçuyor.
while(Bekle>0){Bekle--;}
}
void Delay_us(unsigned long Bekle)
{
Bekle = Bekle * 21; // uSn ye ye çevirdik. OSC 168Mhz de uçuyor.
while(Bekle>0){Bekle--;}
}
Delay.h;
extern void Delay_ms(unsigned long Bekle);
extern void Delay_us(unsigned long Bekle);
HD44780.c;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// LCD data Portu GPIOD
// RS. GPIOB.4
// E. GPIOB.5 olarak kullanılmıştır.
//
// Kullanılışı;
// Lcd_init(); // 2x16 LCD yi kullanıma hazır hale getirir.
// Lcd_Veri(); // Lcd ye KOmut göndermek için kullanılır.
// Lcd_Git(1,2); // Lcd nin 1. satırının 2. sütununa imleci konumlandırır.
// Lcd_Yaz("Merhaba"); // Lcd ye Merhaba Stringini gönderir.
// Yaz(); // Bu kullanılmayacak.
// Lcd_Sil(); // Lcd yi silmek için kullanılır.
// Lcd_Imlec_Var(); // İmleç YanSön Moduna sokar.
// Lcd_Imlec_Yok(); // İmleç i yok eder.
//
//
#include "hd44780.h"
void Lcd_init(void)
{
GPIOD->MODER = 0x55005555; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
GPIOB->MODER = 0x00000500; // GPIOB 4 ve 5 i çıkış yaptık.
GPIOA->OSPEEDR= 0x00000000; // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
GPIOB->OSPEEDR= 0x00000000; // AYnı şey GPIOB içinde geçerli
GPIO_B(4)=0; GPIO_B(5)=0; // Genel
GPIOD->ODR= 0x00000000; // Temizlik
Delay_ms(20);
Lcd_Veri(0x30); // Lcd Reset
Lcd_Sil();
Lcd_Veri(56); // 2 satır kullanacağımızı yazdık
Lcd_Veri(15); // Display i aç
Lcd_Veri(0x06); // Kursör 1 artan modda.
Lcd_Sil(); // Lcd yi temizle
}
void Lcd_Veri(unsigned char veri)
{
GPIO_B(4)=0; Delay_ms(10);
GPIOD->ODR = veri;
GPIO_B(5)=1; Delay_ms(10); GPIO_B(5)=0;
}
void Lcd_Git(unsigned char p1,unsigned char p2)
{
if (p1==1) Lcd_Veri(0x80+(p2-1));
else Lcd_Veri(0xC0+(p2-1));
}
void Lcd_Yaz(unsigned char *lcd_data)
{
Delay_ms(10);
while(*lcd_data) Yaz(*lcd_data++);
}
void Yaz(unsigned dat)
{
GPIO_B(4)=1; Delay_ms(10);
GPIOD->ODR = dat;
GPIO_B(5)=1; Delay_ms(10); GPIO_B(5)=0;
}
void Lcd_Sil(void)
{
Lcd_Veri(1);
Delay_ms(10);
}
void Lcd_Imlec_Yok(void)
{
Lcd_Veri(0x0C);
Delay_ms(10);
}
void Lcd_Imlec_Var(void)
{
Lcd_Veri(0x0F);
Delay_ms(10);
}
HD44780.h;
#define GPIO_A(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOA->ODR) << 5) + ((b) << 2)))
#define GPIO_B(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_C(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOC->ODR) << 5) + ((b) << 2)))
#define GPIO_D(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOD->ODR) << 5) + ((b) << 2)))
#define GPIO_E(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOE->ODR) << 5) + ((b) << 2)))
#define GPIO_F(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOF->ODR) << 5) + ((b) << 2)))
#define GPIO_G(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOG->ODR) << 5) + ((b) << 2)))
#define GPIO_I(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOI->ODR) << 5) + ((b) << 2)))
extern void Lcd_Veri(unsigned char veri);
extern void Lcd_Git(unsigned char p1,unsigned char p2);
extern void Yaz(unsigned dat);
extern void Lcd_Yaz(unsigned char *lcd_data);
extern void Lcd_Sil(void);
extern void Lcd_Imlec_Var(void);
extern void Lcd_Imlec_Yok(void);
Resim1;
[IMG]http://img849.imageshack.us/img849/5027/adsz1xu.jpg[/img] (http://imageshack.us/photo/my-images/849/adsz1xu.jpg/)
Resim2;
[IMG]http://img269.imageshack.us/img269/707/adsz2vq.jpg[/img] (http://imageshack.us/photo/my-images/269/adsz2vq.jpg/)
bi türlü calıstıramadım
bu hataları alıyorum
Build target 'Target 1'
compiling HD44780.c...
hd44780.h(16): warning: #1-D: last line of file ends without a newline
HD44780.c(24): error: #20: identifier "GPIOD" is undefined
HD44780.c(25): error: #20: identifier "GPIOB" is undefined
HD44780.c(27): error: #20: identifier "GPIOA" is undefined
HD44780.c(33): warning: #223-D: function "Delay_ms" declared implicitly
HD44780.c(46): error: #20: identifier "GPIOB" is undefined
HD44780.c(46): warning: #223-D: function "Delay_ms" declared implicitly
HD44780.c(47): error: #20: identifier "GPIOD" is undefined
HD44780.c(59): warning: #223-D: function "Delay_ms" declared implicitly
HD44780.c(65): error: #20: identifier "GPIOB" is undefined
HD44780.c(65): warning: #223-D: function "Delay_ms" declared implicitly
HD44780.c(66): error: #20: identifier "GPIOD" is undefined
HD44780.c(73): warning: #223-D: function "Delay_ms" declared implicitly
HD44780.c(79): warning: #223-D: function "Delay_ms" declared implicitly
HD44780.c(85): warning: #223-D: function "Delay_ms" declared implicitly
HD44780.c(86): warning: #1-D: last line of file ends without a newline
Target not created
tam emin değilim ama hd44780.c de stm32 yi include edebilirmisiniz.
zaten yazılı hocam tesekkurler bı kutuphane problemınden suphelenıyorum
main.c içindeki #include "delay.c" ve #include"hd44780.c" satırlarını #include "delay.h" ve #include"hd44780.h" olarak değiştir
hd44780.c içerisine
#include "stm32f4xx.h"
#include "delay.h"
hd44780.h içine de
extern void Lcd_init(void);
satırlarını ekle
Alıntı yapılan: Klein - 12 Şubat 2012, 19:30:28
main.c içindeki #include "delay.c" ve #include"hd44780.c" satırlarını #include "delay.h" ve #include"hd44780.h" olarak değiştir
hd44780.c içerisine
#include "stm32f4xx.h"
#include "delay.h"
satırlarını ekle
teşekkurler oldu. cok sagolun derleyebıldım
hocam derleyici hd44780 deki fonksiyon prottiplerini görünce main dosyada hd44780.c yi include etmesek bile hd44780.h dan bulurmu. nedir bunun püf noktası
Yok doğrudan bulamaz. Bu işin iki yolu var.
ya kaynak dosyayı doğrudan include edeceksiniz #include"xxx.c" gibi. Ama bu durumda ilgili koda ait header dosya varsa onu include etmeyeceksiniz.
ya da
kaynak kodu project managerden dprojeye dahil edecek , dosyanıza da *.h dosyasını include edeceksiniz.
(http://b1202.hizliresim.com/u/d/2nyf2.png)
bazı microchip application library demolarında sanki aynı isimli dosyaların hem header hem de c kaynak dosyası eklenmiş. o yüzden sormuştum. headerı da eklemenin sakıncası varmıdır. bunların mantığı tam olarak nedir. derleyici çalışmasını mı bilmek gerekiyor.
bir dosyayı #include yöntemiyle eklemek ile projeye eklemek arasında şöyle bir fark var. include edilen dosyalar doğrudan dosyaya bağlanır,
derleme esnasında iki dosya tek dosyaymış gibi birleştirilerek derlenir. projeye eklediğinizde ise, her iki dosya da ayrı ayrı derlenir ve link esnasında birbirine bağlanır.
Hem kaynak kodu hem de header dosyayı include edebilirsiniz. Az dosya ile çalışıyorsanız pek sorun olmaz. Ama çok dosya ile çalışıyorsanız, aynı header dosyasını birden fazla kaynak kod kullanıyorsa bazı sorunlar çıkabilir. eğer header dosyanın içinde çift tanımlamayı engelleycek kod yoksa , isim çakışması hatası alırsınız.
şöyle örnekleyeyim :
main.c
#include"display.h"
#include"display.c"
display.c
#include"display.h"
bu şekilde tanımlı main.c'yi derlediğinizde dosyalar tek dosya gibi birleştirileceği için aşağıdaki gibi bir durum ortaya çıkar
display.h tanımları
..
..
display.h tanımları
...
..
display.c tanımları
..
..
main.c tanımları
..
..
Görüldüğü gibi , display.h içeriği dosaya iki kez eklendi. Doğal olarak da derleyici hata verdi.
Tabi bu durumu engellemenin çeşitli yolları var. display.c içindeki include satırını kaldırabilirsiniz., display.h içerisine çift tanımları engelleyecek kilit atabilirsiniz. Ama çok fazla dosya ile çalışıyorsanız , o zaman organişze olmak çok zorlaşır. hangi dosyanın hangisinden önce veya sonra include edileceği gibi bir çok sorunla boğuşursunuz.
Bu sebeple sadece fonksiyon protatiplerini içeren dosyayı include edip, kaynak kodu link esnasında bağlamak daha kolay organize olmanızı sağlar.
merhaba
önceki mesajlarda geçen Lcd örneğini denemek istedim fakat lcd ekranda görüntü oluşturamadım. Lcd nin datasheetine baktığımda hd44780dan farklı bir kontrol IC vardı. Bu önemli bir farkmıdır yoksa ben başka bir hata mı yapıyorumdur ? Eğer önemli ise diğer ICleri olan Lcd ekranları nasıl kullanabiliriz ?
mesela elimde bu lcdden var
http://www.azdisplays.com/PDF/acm1602k.pdf Controller IC SPLC780D
kütüphane yazmayı hiç bilmiyorum bu konuda nasıl ilerlememiz gerekir bilgili arkadaşlar yardımcı olabilirseniz sevinirim
@Klein hocam, şuan neyi nerde include ettiğimi karıştıracak kadar program yazma kabiliyetim yok ama cevabınız için sağolun. microchipin bazı demolarını uyarlayıp kullanıyorum. gözüm hep neyi nerde include etmiş hangi kaynak dosyalar hangi headerları include etmiş onlara gidiyordu. cevaplarınız iyi oldu.
@f15eagle, displayin ıc si farkeder diye düşünüyorum. ben de lcd için kütüphane yazmadım ama hd44780 i kullanmak için lcd ye sırayla gönderilen komutların benzerlerini elinizdeki lc nin ıc si için uyarlamanız lazım. fxdev hocanın hitech örneklerinde hd44780 için sırasıyla yapılması gerekenler var. sanırım yardımcı olur.
Piyasada üretilen birçok karakter LCD çipi HD44780 komutlarını kabul eder.
Genellikle birebir uyumlu olurlar fakat bazılarında biryerleri set etmek gereke biliri. (pcb üzerinde bir jumper ve ya yazılımsal)
LCD panelinizde kullanılan çipin dökümanınına bakmanızda fayda var.
EXTI uzerinde calisiyordum da, asagidaki program PA0'dan interrupt uretebiliyor ama PB2'den uretmeyi beceremedim. Nerede hata yapiyorum? ???
Ekleme: Simdi baktim da PB2 yerine PA2 den interrupt aliyor. Demek ki EXTI line 2 yi secebilmisim.
SYSCFG->EXTICR[0] &=~0x00000100; Sorun buyuk ihtimalle bu satirda ama ne yaptiysam GPIO'larin 0. pinlerinden baska bir pinde interrupt olusturamadim.
void SystemInit() {
....
....
....
GPIOA->MODER&=~0x00000003; // PA0 giris olarak ayarlandi
GPIOB->MODER&=~0x00000030; // PB2 giris olarak ayarlandi
SYSCFG->EXTICR[0] &=~0x00000100; // EXTI0'da PA0 EXTI2'de PB2 interrupt kaynagi olarak secildi.
// (F=0000=PAx , E=0001=PBx)
// (x secilen line numarasi, bu durumda PA icin 0, PB icin 2)
// (manual sayfa 156)
EXTI->RTSR=0; // Yukselen kenar olmasin
EXTI->FTSR=5; // Dusen kenar isteniyor
EXTI->IMR=5; // Kanal 0 ve 2 nin interrupt maski secildi.
NVIC->ISER[0] = 0x40; // EXTI Line0 interrupt aktif
NVIC->ISER[0] = 0x100; // EXTI Line2 interrupt aktif
}
void EXTI0_IRQHandler(void)
{
EXTI->PR|=0x00000001;
}
void EXTI2_IRQHandler(void)
{
EXTI->PR|=0x00000004;
}
SYSCFG->EXTICR[0] &=~0x00000100; EXTICR[0] 8. biti sıfırlamışsın ama hiç bir yerde set etmemişsin. Bu yüzden Hep portA'dan interrupt alman normal. SYSCFG->EXTICR[0] |= 0x00000100; şeklibde yazarsan ilgili biti set edersin.
Ayrıca
NVIC->ISER[0] = 0x40; // EXTI Line0 interrupt aktif
NVIC->ISER[0] = 0x100; // EXTI Line2 interrupt aktif
Satırlarınında da anlamsız bir durum var. Önce 6. biti set ediyorsun , alttaki satırda 6. biti reset edip 8. biti set ediyorsun.
Sanırım gözden kaçırdın. Eğer ikisini de set emek istiyorsan aşağıdaki gibi yapabilirsin.
NVIC->ISER[0] |= 0x40; // EXTI Line0 interrupt aktif
NVIC->ISER[0] |= 0x100; // EXTI Line2 interrupt aktif
Alıntı yapılan: Klein - 15 Şubat 2012, 21:28:36
SYSCFG->EXTICR[0] &=~0x00000100; EXTICR[0] 8. biti sıfırlamışsın ama hiç bir yerde set etmemişsin. Bu yüzden Hep portA'dan interrupt alman normal. SYSCFG->EXTICR[0] |= 0x00000100; şeklibde yazarsan ilgili biti set edersin.
Ayrıca
NVIC->ISER[0] = 0x40; // EXTI Line0 interrupt aktif
NVIC->ISER[0] = 0x100; // EXTI Line2 interrupt aktif
Satırlarınında da anlamsız bir durum var. Önce 6. biti set ediyorsun , alttaki satırda 6. biti reset edip 8. biti set ediyorsun.
Sanırım gözden kaçırdın. Eğer ikisini de set emek istiyorsan aşağıdaki gibi yapabilirsin.
NVIC->ISER[0] |= 0x40; // EXTI Line0 interrupt aktif
NVIC->ISER[0] |= 0x100; // EXTI Line2 interrupt aktif
Kodu duzenlerken dalginliktan buraya yanlis haldeyken yazmisim. Denedigim kodda SYSCFG->EXTICR[0] |= 0x00000100; seklindeydi zaten. Ama calismadi.
(http://img7.imageshack.us/img7/8672/55100307.jpg)
Burada EXTI2'yi 0001 EXTI0'i da 0000 yapmam lazim.
Reset halinde hepsi zaten 0 olduguna gore SYSCFG->EXTICR[0] |= 0x00000100; satirinin istedigim seyi veriyor olmasi lazim. Ama olmuyor.
PA2den interrupt aldigima gore 8. bit setlenmiyor demektir. Oyle degil mi?
Pinden interrupt üretmek için pini input olarak değil , alternatif fonksiyon tanımlayıp , alternatif fonksiyonunu da eventout yapmak gerekliydi diye hatırlıyorum.
Yanlış hatırlıyormuşum.
Bu renklendirme isi cok bas yakacak. Daha once de defalarca karakterleri yuttu. Gereksiz yazismalara neden oldu.
Renkli gosterim cokmu lazim? Yada bu renklendirmenin daha duzgun calisani yokmu? mcu-turkey sitesindeki renklendirmede sorun yok gibi.
@sfounl
Ornek programlarda verdigim A0 pininden int ureten yazilimda da bir hata varmis. Fakat bu hataya ragmen kod calisiyormus.
B2 pininden int urettiremedigini yazdiginda bende ugrastim ve gercekten B2 den int uretilemedigini gordum.
Sorun SYSCFG registerinin clogunu acmamamizdan kaynaklaniyormus. Ornek programlara calisan bir ornek ekledim. System init rutininde de
SYSCFG register clock'unu actim diger ornekte de sozkonusu hatayi giderdim.
RCC->APB2ENR|=0x4000; // SYSCFG Enable
Peki SYSCFG clk acik olmadigi halde A0 pininden int ureten kod nasil calisiyordu?
SYSCFG->EXTICR[0] registerine 0 yazmamiz gerekiyorken clk acikolmadigi icin yazamiyoruz fakat bu registerin resetdeki default degeri 0 oldugu icin
duzguin calisiyordu. B2 pini icin bu rege 0x100 yazmamiz gerekirken yazamiyorduk. Sorunu bu registere 0x100 yazip 0x00 okumam uzerine farkettim.
Alıntı yapılan: bunalmis - 16 Şubat 2012, 01:23:58
@sfounl
Ornek programlarda verdigim A0 pininden int ureten yazilimda da bir hata varmis. Fakat bu hataya ragmen kod calisiyormus.
B2 pininden int urettiremedigini yazdiginda bende ugrastim ve gercekten B2 den int uretilemedigini gordum.
Sorun SYSCFG registerinin clogunu acmamamizdan kaynaklaniyormus. Ornek programlara calisan bir ornek ekledim. System init rutininde de
SYSCFG register clock'unu actim diger ornekte de sozkonusu hatayi giderdim.
RCC->APB2ENR|=0x4000; // SYSCFG Enable
Peki SYSCFG clk acik olmadigi halde A0 pininden int ureten kod nasil calisiyordu?
SYSCFG->EXTICR[0] registerine 0 yazmamiz gerekiyorken clk acikolmadigi icin yazamiyoruz fakat bu registerin resetdeki default degeri 0 oldugu icin
duzguin calisiyordu. B2 pini icin bu rege 0x100 yazmamiz gerekirken yazamiyorduk. Sorunu bu registere 0x100 yazip 0x00 okumam uzerine farkettim.
Tesekkurler Bulent hocam. Bugun en az 5 saat ugrastim cozebilmek icin. :-[
Bazi register'lari(NVIC gibi) view menusunde gorememizin nedeni nedir? Ayrica bazilarnin view menusunde ayri ayri tanimlanmasina ragmen header'da array olarak tanimlanmasi nedendir?
nvic i wiev de değil peripheral butonuyla görebiliyorsunuz
(http://img192.imageshack.us/img192/8972/123tvl.jpg)
Alıntı Yap...Ayrica bazilarnin view menusunde ayri ayri tanimlanmasina ragmen header'da array olarak tanimlanmasi nedendir?
Bu benim de canımı sıkan bir durum. Bu registerleri ilgili h dosyada değiştirip array yapısından kurtarmak mümkün. Ancak bu kez de bir başkasının yazdığı programları derlemek istediğimizde sorun çıkar.
Aslını sorarsan rehber dokumanda ne görüyorsam programda da onu yazmak isterdim.
GPIOA->MODER yerine GPIOA_MODER gibi. Fakat bu register tanımlarını yeni baştan yapmayı ve bahsettiğim uyum sorununu beraberinde getirecek.
Alıntı yapılan: bunalmis - 16 Şubat 2012, 11:55:05
Bu benim de canımı sıkan bir durum. Bu registerleri ilgili h dosyada değiştirip array yapısından kurtarmak mümkün. Ancak bu kez de bir başkasının yazdığı programları derlemek istediğimizde sorun çıkar.
Aslını sorarsan rehber dokumanda ne görüyorsam programda da onu yazmak isterdim.
GPIOA->MODER yerine GPIOA_MODER gibi. Fakat bu register tanımlarını yeni baştan yapmayı ve bahsettiğim uyum sorununu beraberinde getirecek.
Uyum sorunu olmaz, hem standart lib'i eklersin hemde senin yazdığın tanımlamaları, yani ikisinide kullanabilirsin. Açıkçası ben öyle kullanıyorum, duruma göre mix yapıyorum, bazı durumlarda benim yazdığım tanımlamaları yeri geldiğinde ST lib.i ekliyorum. Bu da işi hızlandırıyor.
Haklısın neden sorun çıksın ki? Başkasının yazdığı programda zaten onun header dosyalarını kullanacağız kendimizinkini değil.
Fakat STM32F4 ün header dosyası çok kabarık ve bunu istediğim formata getirmem zaman alır uğraşacağımı sanmıyorum.
Hocam Bu Z eksenini neden ölçemiyorum yada ölçüyorumda fark mı etmiyorum bu MEMS ile
Sorun yok.
Asagidaki program Z yonundeki ivmelenmeye gore ledleri yakiyor.
#include "STM32F4xx.h"
unsigned char PWM[8]; // PWM registerler
unsigned char SRG[8]; // Shadow Registerler
unsigned char CNTR; // PWM Counter
/*****************************************************************************************************
CPU PLL ile 168Mhz de kosturulur
AHB frekansy 168 Mhz
APB1 frekansy 42 Mhz
APB2 frekansy 84 Mhz
*****************************************************************************************************/
void SystemInit()
{
volatile unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000001F; // GPIO A,B,C,D,E clock'u aktif edelim
GPIOD->MODER = 0x55550000; // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
// GPIOA da A7, A6, A5 pinleri, LIS302DL cipiyle haberlesmek icin SPI moduna alinacak
GPIOA->AFR[0]=0x55500000; // SPI1 secelim (Rehber Sayfa 141), Hard Sayfa 49
GPIOA->MODER|=0x0000A800; // A7,A6,A5 Alternatif fonksiyon
RCC->APB2ENR|=0x00001000; // SPI1 clk enable // GPIOE3 pinini output tanimlayalim (LIS302DL SPI/I2C secimi)
GPIOE->MODER = 0x00000040; // GPIOE nin 3 nolu pini cikis tanimlandi
GPIOE->OSPEEDR= 0xFFFFFFFF; // GPIOE nin tum cikislari en yuksek hizda kullanacagiz
GPIOE->BSRRL=0x0008; // GPIOE3=1; LIS302DL CS=1
SPI1->CR1=0x00000B7F; // SPI1 16 bit, master , fulldublex vs
SPI1->CR2=0X0000;
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =839; // Prescaler degerimiz 839, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 84E6 / (840) = 100 KHz
TIM7->ARR =1; // Counter, Decimal 1 olunca basa donsun. Her 20 mikrosaniye de bir timer int olusacak.
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
}
void TIM7_IRQHandler()
{
unsigned short d,i,j;
TIM7->SR=0; // Timer Int Flagini silelim
d=GPIOD->ODR | 0xFF00;
CNTR++;
if(!CNTR)
{
for(i=0;i<8;i++) SRG[i]=PWM[i];
}
j=0x8000;
for(i=0;i<8;i++)
{
if (CNTR>=SRG[i]) d&=~j;
j=j>>1;
}
GPIOD->ODR=d;
}
signed char SPI_CMD(short DAT)
{
signed char RxDat;
GPIOE->BSRRH=0x0008; // LIS302DL CS=0
RxDat=SPI1->SR; // AMAC DELAY (kalmasinda fayda var)
SPI1->DR=DAT; // Komutu yukle
while(!(SPI1->SR&0x01)); // RX BUF bos ise beklemede kal
while(SPI1->SR&0x80); // BSY durumu varsa kalkmasini bekleyelim
RxDat=SPI1->DR; // Cipten gelen veriyi oku
while(SPI1->SR!=0x02); // CS=1 yapmadan once cipin orjinal duruma donmeyi bekleyelim
GPIOE->BSRRL=0x0008; // LIS302DL CS=1
return(RxDat);
}
signed char Write(char Adr,unsigned char Data)
{
return(SPI_CMD(((Adr&0x3F)<<8 )|Data));
}
signed char Read(char Adr)
{
return(SPI_CMD(((Adr&0x3F)|0x80)<<8 ));
}
int main()
{
int i;
signed char z[16]; // PWM registerler
signed char who,zo, b;
signed short a;
if(Read(0x0F)==0x3B) // Who are you ?
{
Write(0x20,0x47); // Data Rate=100Hz, Full Scale=2g, Activate, x,y,z enable
while(!(Read(0x27)&4)); zo=Read(0x2D);
while(1)
{
who=Read(0x27); // Statusu ogrenelim. Kim hazir kim deðil?
if (who&4)
{
a=z[0];
b=Read(0x2D)-zo;
for(i=15;i>0;i--){ z[i]=z[i-1]; a+=(signed short)z[i];}
z[0]=b; a=a>>2;
if (a>=0) { PWM[0]=a; PWM[2]=0; }
else { PWM[0]=0; PWM[2]=-a;}
}
}
}
TIM7->DIER=0x0000; // Update Int disable
while(1)
{
for(i=0;i<0x1000000;i++);
GPIOD->ODR^=0x0000F000;
}
}
bu program neden çalışmadı fikri olan varmı.
#include "STM32F4xx.h";
#define led1 0x00001000;
#define led2 0x00002000;
#define led3 0x00004000;
#define led4 0x00008000;
void SystemInit()
{
volatile int i;
for(i=0;i<0x00100000;i++);
RCC->CFGR=0x00009400;
RCC->CR |=0x00010000;
while(!(RCC->CR & 0x00020000));
RCC->PLLCFGR=0x07405408;
RCC->CR |=0x01000000;
while(!(RCC->CR & 0x02000000));
FLASH->ACR = 0x00000605;
RCC->CFGR |=0x00000002;
while ((RCC->CFGR & 0x0000000F) != 0x0000000A);
RCC->AHB1ENR |= 0x0000000F;
GPIOD->MODER=0x55000000;
GPIOD->OSPEEDR=0xFFFFFFFF;
}
void delay()
{
unsigned int s;
for(s=0;s<0x800000;s++);
}
int main()
{
while(1)
{
int i=0;
if(GPIOA->IDR & 0x00000001)
{
i++;
if(i==1)
{
GPIOD->ODR=led1;
}
else if(i==2)
{
GPIOD->ODR=led2;
}
else if(i==3)
{
GPIOD->ODR=led3;
}
else if(i==4)
{
GPIOD->ODR=led4;
}
if(i>4)i=0;
}
}
}
1) #include "STM32F4xx.h"; satir sonundaki ; silerek warning i kaldir.
2)
while(1)
{
int i=0;
if(GPIOA->IDR & 0x00000001)
{
int i=0; satirini burdan al ve main satirinin ustune yada while(1) satirinin ustune tasi.
Butona bastiginda tum ledler cok hizli sekilde karasimsek yaparak doner, parmagini butondan cektiginde sansina hangi led yaniyorsa o kalir.
dediğiniz şekilde oldu hocam
birde
;hocam buton basılı olunca orda beklenmesini while(GPIOA->IDR); koyup bekletmeye çalıştım pek olmadı.bunu nasıl halledecem
;portun bir bitine erişme nasıl oluyor
if(i>4)i=0;
satirinin hemen altina asagidaki satiri ekle.
while(GPIOA->IDR & 0x00000001);
Bu durumda butona bastiginda sirasi gelen led yanar ve yeni ekledigimiz satira gelindiginde parmagimizin butondan kaldirilmasi beklenir.
while(GPIOA->IDR & 0x00000001); 0. bit 1 ise bekle demek
while(GPIOA->IDR & 0x00000002); 1. bit 1 ise bekle demek
bir bite bagli beklemenin mantigi boyle.
ya ben bu lcd deki bacakları tutturamıyorum yada baska bı problem var
GPIOD->MODER = 0x55005555; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
GPIOB->MODER = 0x00000500; // GPIOB 4 ve 5 i çıkış yaptık.
kucuk bır azarla beraber hocam EMG81 cevabı verdı :)
azar
HD44780.c içerisinde aradığın şey yazıyor..
cevap
// LCD data Portu GPIOD
// RS. GPIOB.4
// E. GPIOB.5 olarak kullanılmıştır.
sagolsunlar umarım calıstırırım
hocalarım dün masanın üztünde MCU nun iç yapısı yazılı olarak dururken bazı çevresel üniteler dikkatimi çekti
CAMERA INTERFACE ve SDIO/MMC bunlarla neler yapabiliriz ?
mesala camera ile OSD, SDIO ile sd kart çalışması yapabilimiyiz ?
http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f10x_stdperiph_lib.zip
adresinde sdio ile ilgili örnek var ama stm32_eval_sdio_sd.c adında dosyalar kullanıyor. (epeyce örnek mevcut)
ben bunu (pin bağlantılarını uyarlayarak) kullanabilir miyim ?
Bilgisayarın stm kitini tanımaması neyden kaynaklanıyordur bilgisi olan varmı. :'(
bazen görüyor görmeyincede görmüyor...
Alıntı yapılan: sseedat - 19 Şubat 2012, 02:50:39
Bilgisayarın stm kitini tanımaması neyden kaynaklanıyordur bilgisi olan varmı. :'(
Tanımamaktan kastınız nedir, mesela nasıl bir uyarıyla karşılaşıyorsunuz?
Arkadaşlar kit ile gelen mouse uygulamasının kodları bir yerlerde var mı acaba?
Alıntı yapılan: silvercopper - 19 Şubat 2012, 11:24:11
Tanımamaktan kastınız nedir, mesela nasıl bir uyarıyla karşılaşıyorsunuz?
usb aygıtı tanımıyor uyarısı veriyor.
@yamak hocam
http://www.st.com/internet/evalboard/product/252419.jsp (http://www.st.com/internet/evalboard/product/252419.jsp) var ama demonstration/binary de hex dosyası var. bir de demonstration altında main.c var. blink mems felan onda gibi ama mouse olayı var mı tam inceleyemedim.
Usart modulünü msb first yada lsb first olarak ayarlayabilceğimiz bir yapı varmı? Yada işlemciye ait bir bellek erişim yapısı yani msb yi alıp lsb ye yazsın diğer kalan bitleri de aynı şekilde..
Gelişme;
Sanırım aradığım şey RBIT komutu bunu keilde c fonksiyonu olarak nasıl kullanırız? #asm #endasm gibi bir preprocessor varmı?
STM32F407 nin Network Interface özelliği bulunuyor mu?
Alıntı yapılan: mcan - 27 Şubat 2012, 21:26:08
Usart modulünü msb first yada lsb first olarak ayarlayabilceğimiz bir yapı varmı? Yada işlemciye ait bir bellek erişim yapısı yani msb yi alıp lsb ye yazsın diğer kalan bitleri de aynı şekilde..
Gelişme;
Sanırım aradığım şey RBIT komutu bunu keilde c fonksiyonu olarak nasıl kullanırız? #asm #endasm gibi bir preprocessor varmı?
Bulamayanlar için fonskiyon bu __RBIT(uint32_t int value) CMSIS ile geliyor.
bilgisayarın stm kartını tanıyamaması kullandığım kabloyla alakalıymış.orjinal kablo ile sorun ortadan kalktı aynı sorunu yaşayanlar kabloyu değiştirerek sorunu halledebilirler.
ADC uygulaması yapan varmı.varsa paylaşabilirmi:)
58. sayfa
teşekkürler görmemişim orayı
LM35 sıcaklık sensörü ile sıcaklık okutmaya çalışıyorum da bir türlü adc ayarlarını kuramadım.program aşağıdaki gibi eksiklik yada hata nerde yardımcı olursanız sevinirim.
#include "STM32F4xx.h"
#include "Delay.c"
#include "HD44780.c"
unsigned char say[]="";
uint16_t adc_val;
float isb=0.005;
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000)); // Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402584; // PLL katsayilarini M=4, N=150, P=2 ve Q=7 yapalim 150 Mhz
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55005555; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
GPIOB->MODER = 0x00000500;
GPIOA->OSPEEDR= 0x00000000; // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
GPIOB->OSPEEDR= 0x00000000; // AYnı şey GPIOB içinde geçerli
GPIOC->OSPEEDR= 0xFFFFFFFF;
GPIOD->OSPEEDR= 0xFFFFFFFF;
GPIOB->MODER |= 0x00000003;
RCC->APB2ENR|=0x00000100; // ADC saat kaynağını aktif ettik.
ADC1->CR1 |=0x00000100; // ADC scan modunda çalışacak.
ADC1->SQR3 |= 0x00000008; // Çevrime ilk girecek kanal 8. (PB0)
ADC1->CR2 |=0x00000003; // AD converter'i açtık. Sürekli çevirim yapacağımızı belirttik.
}
int main()
{
volatile int i;
Lcd_init();
ADC1->CR2 |=0x40000000; // ADC çevrimini başlattık.
while(1)
{
if(ADC1->SR & 0x0002)
{
ADC1->SR &= ~0x0002;
adc_val= ADC1->DR;
}
adc_val=adc_val*isb*100;
sprintf(say,"%d",adc_val);
Lcd_Git(2,0);
Lcd_Yaz(say);
Delay_ms(2000);
}
}
Sorunu biraz daha açık tarif eder misin? Ne oluyor ya da ne olmuyor?
problem şu lcd nin ekranında alakasız sayılar çıkıyor (45,48,55,82,82 gibi sayılar çıkıyor rastegele)
adc_val=adc_val*isb*100;
Öncelikle bu satırı kaldır, ham veriyi bir görelim. Ama bundan önce LM35 yerine bir trimpot ile deneme yapmak daha kolay olacaktır.
10-20K civarı trimpotu kitteki VDD ve GNd uçları arasına bağlayıp , orta ucunu da analog girişe verirsek, denemeleri daha kolay yaparız. 0-4096 arası değeri LCD'de gösterp gösteremediğimize bir bakalım. Sonra LM35 kısmına geçelim. Verdiğin değerler birbirine yakın. Gürültüden etkileniyor olabilir.
dediğiniz gibi yaptım pot ile bu seferde 122 140 168 785 gibi rastgele sayılar çıkıyor.PB0 bacağına giriş vermediğimde yada verdiğimde bişey değişmiyor.
58.sayfadaki örneği aynen alıp denedim. bir sorun görünmüyor.
LCD yazma kısmında bir sorun veya örnek koddan buraya geçirirken unuttuğun bir şey olabilir.
Kodunda bir anormallik görmedim. Benim de gözden kaçırdığım bir yer olabilir.
yok lcd de problem yok normal orada. evet dediğin gibi gözden kaçan küçük bir ayrıntı vardır ben uğraşayım çıkar elbet ilgilendiğin için sağol:)
stm ile adc ugulaması yapan varmı.varsa paylaşabilir mi*
Arkadaşlar kodlara örnek olması açısından şöyle bi board buldum:
http://www.aliexpress.com/fm-store/312788/210751525-534332413/free-shipping-ARM-Cortex-M4-STM32-STM32F407-STM32F407IGT6-development-board-with-3-2-inch-LCD-display.html (http://www.aliexpress.com/fm-store/312788/210751525-534332413/free-shipping-ARM-Cortex-M4-STM32-STM32F407-STM32F407IGT6-development-board-with-3-2-inch-LCD-display.html)
Henüz cd'yi bulamadım internette ama gerek şematik gerekte kod bakımından faydalı olacağını düşünüyorum. Gerçi fiyatıda uygun gibi aslında ST'nin kendi eval boarduna göre :)
ST Eval bordunda da STM32F407IG kullanmış. Sitede eval board için hazırlanmış birçok örnek içeren bir döküman vardı.
aynı satıcı
http://www.aliexpress.com/fm-store/312788/210751525-508792264/free-shipping-ST-Cortex-M4-STM32-STM32F407-STM32F4Discovery-Board.html (http://www.aliexpress.com/fm-store/312788/210751525-508792264/free-shipping-ST-Cortex-M4-STM32-STM32F407-STM32F4Discovery-Board.html)
bizim 15-20 tl ye aldığımız kartı kaça satıyor. ????
Alıntı yapılan: omereliusuk - 11 Mart 2012, 09:52:08
aynı satıcı
http://www.aliexpress.com/fm-store/312788/210751525-508792264/free-shipping-ST-Cortex-M4-STM32-STM32F407-STM32F4Discovery-Board.html (http://www.aliexpress.com/fm-store/312788/210751525-508792264/free-shipping-ST-Cortex-M4-STM32-STM32F407-STM32F4Discovery-Board.html)
bizim 15-20 tl ye aldığımız kartı kaça satıyor. ??? ?
Hocam bu board çok yeni olduğu için piyasada oldukça zor bulunuyor. Ayrıca biz bu boardları gerçekten çok ucuza aldık. İşlemci bile bu boardlardan daha pahalı. Bu konuda emeği geçen herkese tekrar teşekkürler.
Hard dökümanlarını incelemeye başladım.
Kartın Hangi Pinine +5V verirsem USB bağlantısı olmadan çalıştırabilirim ?
5V yazan pine vererek çalıştırabilirsiniz. Bu pin doğrudan kartın üzerindeki regülatöre bağlı. Bu regülatörde D1 diyotu üzerinden USB 5V'ta bağlı. Bu (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00039084.pdf)dökümanın 32. sayfasına bakabilirsiniz.
o zaman benim kartta bir başka iş var o pinle çalıştıramadım
Aşağıdaki siteye bir bak. Bir diyodun bozulmasından bahsediyordu.
http://www.mcu-turkey.com/?p=23302 (http://www.mcu-turkey.com/?p=23302)
D1 diyotunu ölçtüğümde 300mV çıktı bede hocam. Sizde durum nedir USB ile çalışıp harici 5V ile mi çalışmıyor. Eğer durum bu ise diyot sağlam olabilir.
evet usb ile çalışıyor. 5v harici ile çalışmıyor..
Akşam Bakayım tekrar deneyeceğim. Diyodu da kontrol edey,m
Audio_playback_and_record adli örnek programı inceleyen oldu mu veya direk olarak bu mikrofon yardımıyla ses kaydı yapan
Bu şekilde yapılan kayıtlar winamp yardımıyla çalınabiliyor fakat örnekleme hızı 8 khz olarak gözüküyör. 16khz olması gerekmiyormu PDM_Filter_Init fonksiyonu kullanılırken 16 khz olarak verilmiş. Birde kayıt edilen seste biraz atlamalar oluyor.
Matlab ile bu dosyayı okuyup 8 khz ile çalmaya çalıştığımda sürekli olarak gürültü geliyor. 16 khz ile çaldığımda yine gürültü var ama kayıt edilen sesin ritmi tutuyo sanki kayıt frekansı 16 khz miş gibi zaten de böyle olması gerekmiyor mu?
Mono olarak kayıt yapılırken wav dosyası Streo olarak gözüküyor. Bu konuda bilgisi olan var mı ?
Direk olarak bu mikrofon ile kayıt yapıp sorunsuz çalıştırabilen var mı? Mikrofonun ile ilgili çalışmalar yapan arkadaşlar varsa paylaşabilirler mi?
merhaba hocam GPIOD->MODER=0x55000000; komutuyla 15,14,13,12 pinleri çıkış yaptınız ama 0x55000000 sayısının binary karşılığı 15,14,13,12 pinlere tekabul etmiyo bunu açıklayabilirmisiniz armda daha yeniyim kusra bakmayın :( çok teşekkür ederim
MODER kaydedicisinde her pin için 2 bit saklanıyor.
ilk iki bit 0. pin son 2 bit 15. pin için.
0x55000000 binary açılımı 0b0101010100......00
ikişer bit olarak ayırırsak
01 01 01 01 00......00
pine ilişkin MODER bitleri 01 olduğunda çıkış olduğuna göre
01 01 01 01 00 , .......... , 00
15 , 14 , 13 , 12 , 11 , .......... , 0
O O O O I I
olur.
Alıntı yapılan: Klein - 01 Mayıs 2012, 16:29:10
MODER kaydedicisinde her pin için 2 bit saklanıyor.
ilk iki bit 0. pin son 2 bit 15. pin için.
0x55000000 binary açılımı 0b0101010100......00
ikişer bit olarak ayırırsak
01 01 01 01 00......00
pine ilişkin MODER bitleri 01 olduğunda çıkış olduğuna göre
01 01 01 01 00 , .......... , 00
15 , 14 , 13 , 12 , 11 , .......... , 0
O O O O I I
olur.
çok saolun hocam şimdi anladım her pin için 4 olasılık var 01 gpio olarak atanıyo çok teşekkür ettim :)
Selamun aleyküm kardeşlerim, karta bağlayacağım sht75 sensörunden sıcaklık ve nem verılerıni okuyacağım ,kartla ılgılı uygulmaları inceledım ama harıcı sensörden verı okunmasıyla ılgılı bişeye rastlamadım bu konuda yardımcı olabilirmisinız acaba teşekkürlerr...
hocam entegre I2C ile haberleşme yapıyormuş yani user manuelde bu iletişimin nasıl kullanıldığına bakacaksın.Bu konu üzerinde çalışan arkadaşlar varsa örnek kodlar paylaşırlar belki.
Alıntı yapılan: marecrisium - 26 Mayıs 2012, 03:31:08
hocam entegre I2C ile haberleşme yapıyormuş yani user manuelde bu iletişimin nasıl kullanıldığına bakacaksın.Bu konu üzerinde çalışan arkadaşlar varsa örnek kodlar paylaşırlar belki.
Diğer işlemcilerde kullanılan koduu arm için düzenledım ama sensörden verıyı okuyamıyorum nerde yanlıs yapıyorum çözemedım,,sht haberleşme fonksıyonlarının yeırne ı2c nın kendıı özell fonksıyonlaırınımı kullanmak gerekıyor acaba ..
#include "STM32F4xx.h"
#include "delay.h"
#include "HD44780.h"
#include "math.h"
#include "stdio.h"
//adr komut r/w
#define YAZMA_DURUM 0x06 //000 0011 0
#define OKUMA_DURUM 0x07 //000 0011 1
#define ISI_OLCUM 0x03 //000 0001 1
#define NEM_OLCUM 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
#define noACK 0
#define ACK 1
#define DATA GPIO_B(7)
#define SCK GPIO_B(6)
void SystemInit(void)
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000001F; // GPIO A,B,C,D,E clock'u aktif edelim
GPIOD->MODER = 0x55005555; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
GPIOB->MODER = 0x00000500; // GPIOB 4 ve 5 i çıkış yaptık.
//GPIOE->MODER = 0x00000880; // GPIOE 4 ve 6 i çıkış yaptık.
// DATA ÇIKIŞ=E4 SCK ÇIKIŞ= E6
GPIOA->OSPEEDR= 0x00000000; // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
GPIOB->OSPEEDR= 0xFFFFFFFF; // AYnı şey GPIOB içinde geçerli
GPIOC->OSPEEDR= 0xFFFFFFFF;
GPIOD->OSPEEDR= 0xFFFFFFFF;
GPIOE->OSPEEDR= 0xFFFFFFFF;
}
void bekle( unsigned int sure )
{
int i;
while( sure != 0 )
{
i = 120;
while( i != 0 )
{
i --;
}
sure --;
}
}
void ee_delay(void)
{ unsigned long y;
for(y=0; y<50; y++);
}
typedef union
{ unsigned int i;
float f;
} value;
enum {ISI,NEM};
char s_yaz_byte(unsigned char deger)
{
unsigned char i,hata=0;
for (i=0x80;i>0;i/=2)
{ if (i & deger) DATA=1;
else DATA=0;
ee_delay();
SCK=1;
ee_delay();
ee_delay();
ee_delay();
SCK=0;
ee_delay();
}
DATA=1;
ee_delay();
SCK=1;
hata=DATA;
SCK=0;
return hata;
}
/***** bir bayt okumak için tanımlama *****/
char s_oku_byte(unsigned char ack)
{
unsigned char i,val=0;
DATA=1;
for (i=0x80;i>0;i/=2) //bit maskeleme
{ SCK=1; //iletişim için saat sinyali
if (DATA) val=(val | i); //bir bit oku
SCK=0;
}
DATA=!ack;
ee_delay();
SCK=1;
ee_delay();
ee_delay();
ee_delay();
SCK=0;
ee_delay();
DATA=1; //veri değerini sil
return val;
}
/***** yeni bir iletişim başlat *****/
void s_basla(void)
{
DATA=1; SCK=0; //ilk durum
ee_delay();
SCK=1;
ee_delay();
DATA=0;
ee_delay();
SCK=0;
ee_delay();
ee_delay();
ee_delay();
SCK=1;
ee_delay();
DATA=1;
ee_delay();
SCK=0;
}
/*** iletişim yenile: DATA-line=1 ve sonraki 9 SCK saykili takiben başa dön ***/
void s_baglanti_reset(void)
{
unsigned char i;
DATA=1; SCK=0; //ilk durum
for(i=0;i<9;i++) //9 SCK saykili
{ SCK=1;
SCK=0;
}
s_basla(); //aktarmayi baslat
}
//----------------------------------------------------------------------------------
char s_softreset(void)
{
unsigned char hata=0;
s_baglanti_reset(); //reset communication
hata+=s_yaz_byte(RESET); //send RESET-command to sensor
return hata; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_oku_statusreg(unsigned char *p_deger, unsigned char *p_top)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
unsigned char hata=0;
s_basla(); //transmission start
hata=s_yaz_byte(OKUMA_DURUM); //send command to sensor
*p_deger=s_oku_byte(ACK); //read status register (8-bit)
*p_top=s_oku_byte(noACK); //read checksum (8-bit)
return hata; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_yaz_statusreg(unsigned char *p_deger)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
unsigned char hata=0;
s_basla(); //transmission start
hata+=s_oku_byte(YAZMA_DURUM);//send command to sensor
hata+=s_yaz_byte(*p_deger); //send value of status register
return hata; //error>=1 in case of no response form the sensor
}
/**** ölcüm yapar (nem/sıcaklık)****/
char s_olcum(unsigned char *p_deger, unsigned char *p_top, unsigned char mod)
{
unsigned hata=0;
unsigned int i;
s_basla(); //aktarmayı başlat.
switch(mod){ //sensöre komut göder.
case ISI : hata+=s_yaz_byte(ISI_OLCUM); break;
case NEM : hata+=s_yaz_byte(NEM_OLCUM); break;
default : break;
}
for (i=0;i<65535;i++) if(DATA==0) break; //sensör ölçümü tamamlayana kadar bekle.
if(DATA) hata+=1; // süre 2 saniye yi astiginda
*(p_deger) =s_oku_byte(ACK); //ilk bayti oku
*(p_deger+1)=s_oku_byte(ACK); //ikinci bayti oku
*p_top =s_oku_byte(noACK); //toplamı oku
return hata;
}
void sensor_hesapla(float *p_nem ,float *p_isi)
{
const float C1=-2.0468; // for 12 Bit RH
const float C2=+0.0367; // for 12 Bit RH
const float C3=-0.0000015955; // for 12 Bit RH
const float T1=+0.01; // for 12 Bit RH
const float T2=+0.00008; // for 12 Bit RH
float rh=*p_nem; // rh: nem [saat darbesi] 12 Bit
float t=*p_isi; // t: sicaklik [saat darbesi] 14 Bit
float rh_lin; // rh_lin: nem doğrusal
float rh_true; // rh_true: sicaklik telafi nem
float t_C; // t_C : sicaklik [íC]
t_C=t*0.01 - 40; //[íC] dan sıcaklık hesapla.
rh_lin=C3*rh*rh + C2*rh + C1; //[%RH] dan nem hesapla
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //[%RH] sıcaklık ısı telefisi hesapla
*p_isi=t_C; //sıcaklık değeri döndür[íC]
*p_nem=rh_true; //nem değeri döndür.[%RH]
}
void main(void)
{
void SystemInit();
value nem_deger,isi_deger;
unsigned char topla, hata;
unsigned int i;
char S1[16],S2[16];
s_baglanti_reset();
while(1)
{
hata=0;
//hata+=s_olcum((unsigned char*) &nem_deger.i,&topla,NEM);
s_olcum((unsigned char *)&nem_deger.i,&topla,NEM); //nem ölçümü
//hata+=s_olcum((unsigned char*) &isi_deger.i,&topla,ISI);
s_olcum((unsigned char *)&isi_deger.i,&topla,ISI); //sıceklık ölçümü
//if(hata!=0) s_baglanti_reset();
//else//{
nem_deger.f=(float)nem_deger.i; //tip dönüşümü
isi_deger.f=(float)isi_deger.i; //tip dönüşümü
sensor_hesapla(&nem_deger.f,&isi_deger.f); //sıcaklık ve nem hesapla
for (i=0;i<40000;i++); //(be sure that the compiler doesn't eliminate this line!)
//}
// sprintf(S1,"SiCAKLiK :%5.1fC%",isi_deger.f); //sicaklik değerini s1 degiskenine bastır
//sprintf(S2,"NEM......:%5.1f%%",nem_deger.f); //nem değerini s2 degiskenine bastır
Lcd_init();
Lcd_Imlec_Yok();
sprintf(S1,"SiCAKLiK :%5.1fC%",isi_deger.f); //sicaklik değerini s1 degiskenine bastır
Lcd_Yaz(S1); Lcd_Git(2,1);
sprintf(S2,"NEM......:%5.1f%%",nem_deger.f); //nem değerini s2 degiskenine bastır
Lcd_Yaz(S2);
Delay_ms(250);
}
}
Merhaba arkadaşlar,
Örneklerin çoğu takip ettim. Aklıma belli sorular takıldı. Yardımcı olursanız sevinirim. Sorularım cevaplandıkta uygun cevabu sorunun altına yazacağım.
1. Bazen değişkenler için volatile tanımlamasını kullanıyoruz. Bunun nedeni nedir? (Google bana yardımcı olmadı)
2. OSC oturturtma rutuni tam olarak nedir?
3. DAC orneginde
"GPIOA->MODER=0xA8000200; // GPIOA4 Analog inp yapildi"
demişiz. Analog olması için [1 1] yazmamız gerekmiyor mu?
Bu durumda GPIOA->MODER=0xA8000300 yazmamız gerekmez mi?
4. GPIOA ve GPIOB 'nun default moder değerleri
-0xA800 0000 for port A
-0x0000 0280 for port B
Diğer Moderlerinki 0x0000 0000 iken bunların niye farklı?
5. Systick kullanırken LOAD, CTRL adreslerini kendimiz tanımlamışız, zira datasheetimizde de açıklama bulunmuyor. Hicbir definition yapmadan sadece "STM32F4xx.h" ve "startup_stm32f4xx.s" dosyalarını çağırarak aşağıdaki gibi systick'i configüre edebiliyorum.
SysTick->LOAD = 168-1;
SysTick->CTRL &= ~0x00010000;
SysTick->CTRL |= 0x00000007;
Ancak bu 2 dosyada da systick adına hiç birşey yok! O zaman bu tanımlamalar nerde yapıldı da adresleri çağrıldı?
6. GPIO'ları alternate function olarak programlarken datasheete AFRH ve AFRL registerleri mevcutken biz AFR[1] kullandık. Zaten AFRH tanımsız, yani kullanılamıyor. Sorum bunu AFR[1] yazarak konfigüre edeceğimi buraya bakmasaydım nereden öğrenecektim. ST'nin bir programlama manueli var da bilmiyor muyum?
7. USART3 kullanırken USART'ı reset edip daha reseti kaldırdık. Clock uyguladığımız diğer çevresel birimlerede bunu yapabilirdik; ancak sadece buna yaptık. Nedeni nedir?
Baudrate hesaplarken:
USART3->BRR |= 0X1112; yerine USART3->BRR |= 0X1117; yazmamız gerekmez mi? Zira 0.438*16=7
Alıntı yapılan: denizhan50 - 27 Mayıs 2012, 04:08:21
Diğer işlemcilerde kullanılan koduu arm için düzenledım ama sensörden verıyı okuyamıyorum nerde yanlıs yapıyorum çözemedım,,sht haberleşme fonksıyonlarının yeırne ı2c nın kendıı özell fonksıyonlaırınımı kullanmak gerekıyor acaba ..
#include "STM32F4xx.h"
#include "delay.h"
#include "HD44780.h"
#include "math.h"
#include "stdio.h"
//adr komut r/w
#define YAZMA_DURUM 0x06 //000 0011 0
#define OKUMA_DURUM 0x07 //000 0011 1
#define ISI_OLCUM 0x03 //000 0001 1
#define NEM_OLCUM 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
#define noACK 0
#define ACK 1
#define DATA GPIO_B(7)
#define SCK GPIO_B(6)
void SystemInit(void)
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000001F; // GPIO A,B,C,D,E clock'u aktif edelim
GPIOD->MODER = 0x55005555; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
GPIOB->MODER = 0x00000500; // GPIOB 4 ve 5 i çıkış yaptık.
//GPIOE->MODER = 0x00000880; // GPIOE 4 ve 6 i çıkış yaptık.
// DATA ÇIKIŞ=E4 SCK ÇIKIŞ= E6
GPIOA->OSPEEDR= 0x00000000; // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
GPIOB->OSPEEDR= 0xFFFFFFFF; // AYnı şey GPIOB içinde geçerli
GPIOC->OSPEEDR= 0xFFFFFFFF;
GPIOD->OSPEEDR= 0xFFFFFFFF;
GPIOE->OSPEEDR= 0xFFFFFFFF;
}
void bekle( unsigned int sure )
{
int i;
while( sure != 0 )
{
i = 120;
while( i != 0 )
{
i --;
}
sure --;
}
}
void ee_delay(void)
{ unsigned long y;
for(y=0; y<50; y++);
}
typedef union
{ unsigned int i;
float f;
} value;
enum {ISI,NEM};
char s_yaz_byte(unsigned char deger)
{
unsigned char i,hata=0;
for (i=0x80;i>0;i/=2)
{ if (i & deger) DATA=1;
else DATA=0;
ee_delay();
SCK=1;
ee_delay();
ee_delay();
ee_delay();
SCK=0;
ee_delay();
}
DATA=1;
ee_delay();
SCK=1;
hata=DATA;
SCK=0;
return hata;
}
/***** bir bayt okumak için tanımlama *****/
char s_oku_byte(unsigned char ack)
{
unsigned char i,val=0;
DATA=1;
for (i=0x80;i>0;i/=2) //bit maskeleme
{ SCK=1; //iletişim için saat sinyali
if (DATA) val=(val | i); //bir bit oku
SCK=0;
}
DATA=!ack;
ee_delay();
SCK=1;
ee_delay();
ee_delay();
ee_delay();
SCK=0;
ee_delay();
DATA=1; //veri değerini sil
return val;
}
/***** yeni bir iletişim başlat *****/
void s_basla(void)
{
DATA=1; SCK=0; //ilk durum
ee_delay();
SCK=1;
ee_delay();
DATA=0;
ee_delay();
SCK=0;
ee_delay();
ee_delay();
ee_delay();
SCK=1;
ee_delay();
DATA=1;
ee_delay();
SCK=0;
}
/*** iletişim yenile: DATA-line=1 ve sonraki 9 SCK saykili takiben başa dön ***/
void s_baglanti_reset(void)
{
unsigned char i;
DATA=1; SCK=0; //ilk durum
for(i=0;i<9;i++) //9 SCK saykili
{ SCK=1;
SCK=0;
}
s_basla(); //aktarmayi baslat
}
//----------------------------------------------------------------------------------
char s_softreset(void)
{
unsigned char hata=0;
s_baglanti_reset(); //reset communication
hata+=s_yaz_byte(RESET); //send RESET-command to sensor
return hata; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_oku_statusreg(unsigned char *p_deger, unsigned char *p_top)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
unsigned char hata=0;
s_basla(); //transmission start
hata=s_yaz_byte(OKUMA_DURUM); //send command to sensor
*p_deger=s_oku_byte(ACK); //read status register (8-bit)
*p_top=s_oku_byte(noACK); //read checksum (8-bit)
return hata; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_yaz_statusreg(unsigned char *p_deger)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
unsigned char hata=0;
s_basla(); //transmission start
hata+=s_oku_byte(YAZMA_DURUM);//send command to sensor
hata+=s_yaz_byte(*p_deger); //send value of status register
return hata; //error>=1 in case of no response form the sensor
}
/**** ölcüm yapar (nem/sıcaklık)****/
char s_olcum(unsigned char *p_deger, unsigned char *p_top, unsigned char mod)
{
unsigned hata=0;
unsigned int i;
s_basla(); //aktarmayı başlat.
switch(mod){ //sensöre komut göder.
case ISI : hata+=s_yaz_byte(ISI_OLCUM); break;
case NEM : hata+=s_yaz_byte(NEM_OLCUM); break;
default : break;
}
for (i=0;i<65535;i++) if(DATA==0) break; //sensör ölçümü tamamlayana kadar bekle.
if(DATA) hata+=1; // süre 2 saniye yi astiginda
*(p_deger) =s_oku_byte(ACK); //ilk bayti oku
*(p_deger+1)=s_oku_byte(ACK); //ikinci bayti oku
*p_top =s_oku_byte(noACK); //toplamı oku
return hata;
}
void sensor_hesapla(float *p_nem ,float *p_isi)
{
const float C1=-2.0468; // for 12 Bit RH
const float C2=+0.0367; // for 12 Bit RH
const float C3=-0.0000015955; // for 12 Bit RH
const float T1=+0.01; // for 12 Bit RH
const float T2=+0.00008; // for 12 Bit RH
float rh=*p_nem; // rh: nem [saat darbesi] 12 Bit
float t=*p_isi; // t: sicaklik [saat darbesi] 14 Bit
float rh_lin; // rh_lin: nem doğrusal
float rh_true; // rh_true: sicaklik telafi nem
float t_C; // t_C : sicaklik [íC]
t_C=t*0.01 - 40; //[íC] dan sıcaklık hesapla.
rh_lin=C3*rh*rh + C2*rh + C1; //[%RH] dan nem hesapla
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //[%RH] sıcaklık ısı telefisi hesapla
*p_isi=t_C; //sıcaklık değeri döndür[íC]
*p_nem=rh_true; //nem değeri döndür.[%RH]
}
void main(void)
{
void SystemInit();
value nem_deger,isi_deger;
unsigned char topla, hata;
unsigned int i;
char S1[16],S2[16];
s_baglanti_reset();
while(1)
{
hata=0;
//hata+=s_olcum((unsigned char*) &nem_deger.i,&topla,NEM);
s_olcum((unsigned char *)&nem_deger.i,&topla,NEM); //nem ölçümü
//hata+=s_olcum((unsigned char*) &isi_deger.i,&topla,ISI);
s_olcum((unsigned char *)&isi_deger.i,&topla,ISI); //sıceklık ölçümü
//if(hata!=0) s_baglanti_reset();
//else//{
nem_deger.f=(float)nem_deger.i; //tip dönüşümü
isi_deger.f=(float)isi_deger.i; //tip dönüşümü
sensor_hesapla(&nem_deger.f,&isi_deger.f); //sıcaklık ve nem hesapla
for (i=0;i<40000;i++); //(be sure that the compiler doesn't eliminate this line!)
//}
// sprintf(S1,"SiCAKLiK :%5.1fC%",isi_deger.f); //sicaklik değerini s1 degiskenine bastır
//sprintf(S2,"NEM......:%5.1f%%",nem_deger.f); //nem değerini s2 degiskenine bastır
Lcd_init();
Lcd_Imlec_Yok();
sprintf(S1,"SiCAKLiK :%5.1fC%",isi_deger.f); //sicaklik değerini s1 degiskenine bastır
Lcd_Yaz(S1); Lcd_Git(2,1);
sprintf(S2,"NEM......:%5.1f%%",nem_deger.f); //nem değerini s2 degiskenine bastır
Lcd_Yaz(S2);
Delay_ms(250);
}
}
STM32F4'ün I2C donanımını kullanman gerekli hocam user manuelde nasıl kullanacağın,registerler falan yazılı oraya bi göz at derim.Bu şekilde bu kodlar bu işlemcide çalışmaz işlemciye özel tanımlamalar yapılması gerekiyor.
Merhabalar arkadaşlar konuda biraz geri kalmışım deneme kartımın geç gelmesinden dolayı yanlış yerde sordu isem kusura bakmayın.
elimde stm32f4discovery board mevcut .arm derslerindeki örnek kodları (örn led yakıp söndürme) derlerken kail hata vermiyor ancak debug ettiğimde kod startup bölümünde çakılıyor.
kodlardaki " int main() " ifadesi yerine " int __main()" yazınca çalıştı. bu problem neden olur aydınlatırsanız çok sevinirim.
kail mdk 4.53 deneme sürümü olarak kullanıyorum.
"__main" yazmak nerden esti derseniz startup kodlarını inceledim orda mainli ifadelerin tümü bu şekildeydi bende bir deniyim ölmem dedim.
Arkadaşlar başlık bildiğiniz öksüz gibi kaldı. Yukarı da (https://www.picproje.org/index.php/topic,35794.msg290715.html#msg290715 (https://www.picproje.org/index.php/topic,35794.msg290715.html#msg290715)) kafama takılan bir çok soru yazdım; hiçbirine cevap gelmedi. Yardımcı olabilir misiniz?
Register ları öğrenirsin ezberlersin buna itirazım yok, ancak hızlı bir kod geliştirme amacında isen st firmasının firmware tabanlı orjinal örneklerinden hareketle kod geliştirmeye başlamanı register larla tek tek uğraşmamanı öneririm.
merhaba arkadaşlar stm le 2*16 lık lcd yi bi türlü çalıştıramadım kütüphaneler aşağıdaki gibi bakarsanız çok iyi olur:)
hd44780.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// LCD data Portu GPIOD
// RS. GPIOB.4
// E. GPIOB.5 olarak kullanılmıştır.
//
// Kullanılışı;
// Lcd_init(); // 2x16 LCD yi kullanıma hazır hale getirir.
// Lcd_Veri(); // Lcd ye KOmut göndermek için kullanılır.
// Lcd_Git(1,2); // Lcd nin 1. satırının 2. sütununa imleci konumlandırır.
// Lcd_Yaz("Merhaba"); // Lcd ye Merhaba Stringini gönderir.
// Yaz(); // Bu kullanılmayacak.
// Lcd_Sil(); // Lcd yi silmek için kullanılır.
// Lcd_Imlec_Var(); // İmleç YanSön Moduna sokar.
// Lcd_Imlec_Yok(); // İmleç i yok eder.
//
//
#include "hd44780.h"
void lcd_busy(void)
{
Delay_us(250);
Delay_us(250);
}
void Lcd_init(void)
{
GPIOD->MODER = 0x55000055; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
GPIOB->MODER = 0x00000500; // GPIOB 4 ve 5 i çıkış yaptık.
GPIOA->OSPEEDR= 0x00000000; // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
GPIOB->OSPEEDR= 0x00000000; // AYnı şey GPIOB içinde geçerli
rs=0;
e=0; // Genel
GPIOD->ODR= 0x00000000; // Temizlik
Delay_ms(20);
e=1;
Lcd_Veri(0x02); // Lcd Reset
Lcd_Sil();
Lcd_Veri(40);
Lcd_Veri(15); // Display i aç
Lcd_Veri(0x06); // Kursör 1 artan modda.
Lcd_Sil(); // Lcd yi temizle
}
void Lcd_Veri(unsigned char veri) //komut
{
rs=0;
e=1;
GPIOD->ODR=(veri & 0xF0);
e=0;
lcd_busy();
e=1;
GPIOD->ODR=((veri & 0x0F)<<4);
e=0;
lcd_busy();
}
void Lcd_Git(unsigned char p1,unsigned char p2)
{
if (p1==1) Lcd_Veri(0x80+(p2-1));
else Lcd_Veri(0xC0+(p2-1));
}
void Lcd_Yaz(unsigned char *lcd_data)
{
lcd_busy();
while(*lcd_data) Yaz(*lcd_data++);
}
void Yaz(unsigned dat)
{
rs=1;
e=1;
GPIOD->ODR=(dat &0xF0);
e=0;
lcd_busy();
e=1;
GPIOD->ODR=((dat & 0x0F)<<4);
e=0;
lcd_busy();
}
void Lcd_Sil(void)
{
Lcd_Veri(1);
Delay_ms(10);
}
void Lcd_Imlec_Yok(void)
{
Lcd_Veri(0x0C);
Delay_ms(10);
}
void Lcd_Imlec_Var(void)
{
Lcd_Veri(0x0F);
Delay_ms(10);
}
hd44780.h
#define GPIO_A(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOA->ODR) << 5) + ((b) << 2)))
#define GPIO_B(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_C(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOC->ODR) << 5) + ((b) << 2)))
#define GPIO_D(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOD->ODR) << 5) + ((b) << 2)))
#define GPIO_E(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOE->ODR) << 5) + ((b) << 2)))
#define GPIO_F(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOF->ODR) << 5) + ((b) << 2)))
#define GPIO_G(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOG->ODR) << 5) + ((b) << 2)))
#define GPIO_I(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOI->ODR) << 5) + ((b) << 2)))
#define rs GPIO_B(4)
#define e GPIO_B(5)
extern void Lcd_Veri(unsigned char veri);
extern void Lcd_Git(unsigned char p1,unsigned char p2);
extern void Yaz(unsigned dat);
extern void Lcd_Yaz(unsigned char *lcd_data);
extern void Lcd_Sil(void);
extern void Lcd_Imlec_Var(void);
extern void Lcd_Imlec_Yok(void);
Yeni Tur,
Kart ile alakalı olarak USB üzerinden ivmeölçer bilgilerini göndermem gerekiyor. Nasıl Yapabilirim ?
Aynı bilgisayarda 2 adet STM32f4 kiti ile aynı anda çalışmayı deneyen oldu mu?
Bir proje üzerinde çalışıyorum. Kartın biri alıcı diğeri verici olarak çalışıyor. Programı 2 ayrı keil açarak yazıyorum. Ancak debug ederken sadece kartın birini debug ediyor. Hangi projeden debug edersem edeyim hep aynı kartı debug edebiliyorum. Dğer karta ulaşamıyorum.
Aygıtların içinde 2 adet STLink Dongle aygıtı görüyorum. Ama biri bu karta diğeri şu karta bağlansın diyemiyorum.
Hocam ben 2 tane kullanmayı denemedim fakat
Burada söylediğiniz "Ancak debug ederken sadece kartın birini debug ediyor. Hangi projeden debug edersem edeyim hep aynı kartı debug edebiliyorum"
Kartın birin arızalı olduğunu göstermezmi . Hep aynı karta ulaşıyorum diğerine ulaşamıyorum diyorsunuz . Yer değiştirip denedinizmi. Yine ilk başta ulaşabildiğiniz kartamı ulaşıyorsunuz...
Kart arızalı değil. Biraz yanlış ifade var.
2 tane USB var.
1. USB de kart 1
2. USB de kart 2 takılı.
Debug etmek istediğimde hep 1. Usb'ye bağlı olan kartı debug ediyor.
1.USB'yi sökersem 2. USB 'ye bağlı olan debug ediliyor.
Biraz daha basitleştirirsek:
Bilgisayara 2 adet kit bağladığınızda, USB aygıtların altında 2 adet ST Link Dongle görünüyor. Ama bunları Dongle 1,Dongle 2 gibi isimlendirmiyor.
Projenin Debugger ayarlarını yaparken de sadece ST-Link seçebiliyorsunuz. Ama hangisini istediğinizi seçemiyorsunuz.
Karta(forumdan aldığımız Cortexm4 discovery kartı) yazdığım programı sadece ram üzerinden çalışacak çekilde ayarladığımda, flash ve ram üzerinde çalışmasına göre nerdeyse yarı yarıya yavaş çalışıyor.
Ram üzerinde daha hızlı çalışmasını beklerken daha yavaş çalıştı. Bunun sebebi nedir daralan band genişliği sebebiyle harvard mimarisi mi? Ayrıca Cortex m3 için ICODE FLITF üzerinden sadece flah a bağlı gibi. Peki ben programı sadece rama yükleyip ram dan çalıştırınca ICODE nasıl sram a bağlanıyor? FLITF ve bus matrix üzerinden mi?
Bu Kit e uygun Kutu arıyorum
Merhaba arkadaslar sorunumu https://www.picproje.org/index.php/topic,35780.180.html (https://www.picproje.org/index.php/topic,35780.180.html) bölümüde dile getirdim fakat yardımcı olan olmadı.Acaba bunalmış hocamın yazmıs oldugu herhangi bir programı proj ayarları tam olarak foruma yükleyecek bir arkadasımız var mı acaba?
Karta yüklediğim programlar bir türlü çalışmıyor.Bu durum grcekten canımı sıkmaya basladı:( yardım edin lütfen
Her ne kadar yazdığım ve denediğim programları calıştıramasamda yılmak yok :)
Bunalmıs hocamın yazmış olduğu https://www.picproje.org/index.php/topic,35896.0.html (https://www.picproje.org/index.php/topic,35896.0.html) linkindeki timer 7 örneginde
Prescaler değerimiz 42000, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 42E6 / (42000) = 1000 Hz burasını anlamadım ben hocam.Bu bilgiyi nerden buldunuz ben dökümanlarda bulamadımda.Birde farklı frekanslar için (100 Hz,500Hz )
bir kaçtane daha örnek verirseniz cok iyi olur diye düşünüyorum.
Alıntı yapılan: EMP_Otto - 29 Temmuz 2012, 11:28:26
Her ne kadar yazdığım ve denediğim programları calıştıramasamda yılmak yok :)
Bunalmıs hocamın yazmış olduğu https://www.picproje.org/index.php/topic,35896.0.html (https://www.picproje.org/index.php/topic,35896.0.html) linkindeki timer 7 örneginde
Prescaler değerimiz 42000, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 42E6 / (42000) = 1000 Hz burasını anlamadım ben hocam.Bu bilgiyi nerden buldunuz ben dökümanlarda bulamadımda.Birde farklı frekanslar için (100 Hz,500Hz )
bir kaçtane daha örnek verirseniz cok iyi olur diye düşünüyorum.
https://www.picproje.org/index.php/topic,41659.0.html (https://www.picproje.org/index.php/topic,41659.0.html)
Arkadaşlar bu ADC ile ilgili detaylı bir açıklama yapılsa çok yararlı olur kanaatindeyim. Forumda bir iki örnek var ama yeterli değil. Mesela 3 adet kanal var. Fakat bu kanallr hangi pinler tarafından besleniyor çözemedim. Ayrıca ard arda 10 pinden veri nasıl okunabilir mesela?
arda arda okuma scan mode ile yapılabiliyor yanılmıyorsam.
Alıntı YapScan mode for automatic conversion of channel 0 to channel 'n'
Hocam şimdi bu çipin içerisinde 3 adet ADC modülü var. Peki her bir modül kaçar tane analog girişe sahip? Hangi modülün hangi kanala sahip olduğunu nasıl anlıyoruz? Bu nereden ayarlanıyor? PIC serilerinde 1 adet modül vardı ve analog pinler belliydi. Bu çipte öyle birşey yok. Hangi pin analogtur hangi modüle bağlıdır belli değil. Bütün pinler analog olarak ayarlanabiliyor yanılmıyorsam.
hocam bizim kartta yanlış anlamadıysam 2 adet ADC modül var. ADC12 diye geçiyor. 16 external giriş için kanal 3 tane de dahili adc kanalı.
şimdi bunalmış hocanın hard diye adlandırdığı doküman
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/DM00037051.pdf (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/DM00037051.pdf)
sayfa 43 de başlıyor. pin an ball definitions diye bir kısım. hangi pin kaç nolu kanal gösteriyor. benim anladığım ADC12_0 dan ADC12_15 e kadar bizim karttaki mcu nun donanımı. ADC yi kullandın mı diye sorarsanız henüz maalesef.
hatta düzelteyim 16 kanaladan bir kısmı(8 adet) ADC123 diye geçiyor. bu durumda 3 modül gibi.
Ben de az önce farkettim o dökümandaki açıklamayı. Çok karışık bu çipin dökümanları. ADC12'den kastı zannedersem hem ADC2'de hem de ADC1'de kullanılabiliyor olması aynı pinin.
evet o anlamda sanırım. dediğiniz gibi microchip datasheetlerinden sonra baya bir karışık geldi bana da. git bi pdf den registerlara bak diğerinden pin açıklamaları. :(
Klein hocamın örnek açıklayıcı tek kanal da olsa açıklayıcı ama.
Şimdi MikroC ile deniyorum baya basitleştirmişler kütüphane ile ADC okuma işini.
mesaj birleştirme:: 30 Temmuz 2012, 10:59:21
Arkadaşlar kitimizin pinlerinden nasıl bir kablo ile breadboard veya harici devrelere bağlantı yapabiliriz kolayca?
Alıntı yapılan: cenkun - 20 Aralık 2011, 18:31:42
Pin header sistemin çok kullanışlı olmadığını düşünerek kit üzerinde modifikasyon yaptım.
Erkek pinleri sökerek dişi kulandım. Kartın alt tarafında kısadevre oluşmasın diye yükseltmek için kartın alt tarafındaki Jp2 ve Jp3 jumperlerını sökmedim. Micro ubs soketi altındaki gnd bağlantısına 90 derecelik erkek pin header lehim yaparak bir destek oluşturdum.
(http://s11.postimg.cc/4a12crf2n/DSCN8720.jpg) (http://postimg.cc/image/4a12crf2n/)
(http://s9.postimg.cc/aod7nu9uz/DSCN8721.jpg) (http://postimg.cc/image/aod7nu9uz/)
bu güzel olmuş...
Şurada da karta altlık yapmak isteyenler için örnek bir çalışma var;
http://atomsoft.wordpress.com/2011/11/06/stm32f4-male-to-female/ (http://atomsoft.wordpress.com/2011/11/06/stm32f4-male-to-female/)
Eski floppy kablolarını da kullanabilirsiniz.
(http://img254.imageshack.us/img254/7795/asusflppy.jpg)
Bulent hoca bıraktı mı bu işleri?
Şu çevre birimlere birer örnek yazsaydı iyi olacaktı. Özellikle ADC registerları için detaylı bir anlatım yapılsa iyi olacak. Ard arda scan modu ile yapılacak bir uygulama güzel olurdu.
Alıntı yapılan: maytere - 01 Ağustos 2012, 14:01:28
Bulent hoca bıraktı mı bu işleri?
Şu çevre birimlere birer örnek yazsaydı iyi olacaktı. Özellikle ADC registerları için detaylı bir anlatım yapılsa iyi olacak. Ard arda scan modu ile yapılacak bir uygulama güzel olurdu.
Ard arda n adet örnek almaktan mı bahsediyorsun ?
böyle bir uygulamada scan mode register disable olmalı.
Ardarda farklı kanallardan okuma yapmak istiyorum. Bu durumda scan mode aktif olmayacak mı? Hangi registerların kurulacağından emin olamadım birtürlü.
Bir kaç gün yoğunum. Yoğunluğu atlatınca çok kanallı ADC örneği yazacağım.
Süper olur. Registerların fonksiyonlarını öğrenmek adına...
https://www.picproje.org/index.php/topic,35780.180.html (https://www.picproje.org/index.php/topic,35780.180.html)
Arkadaslar sorunumu bicok kez dile getirdim fakat yardım eden cıkmadı lütfen yardım edin :'(
Sorunum bunalmış hocamın veya internetten buldugum yada kendi yazdıgım kodların calısmaması.Derlemede falan hata yok kodları kite yüklüyorum fakat calısmıyor.Keil im kendi kendi içinde gelen kodlar sorunsuz çalışıyor.Proje ayarlarınında Keil ile gelen projeyle aynı yapıyorum ama bir türlü çalıştıramadım.Acaba bir arkadasımız bunalmış hocamın yazdıgı (ledleri flaş eden yada user butonu ile ledleri yakan ) projelerden birini proje proje ayarlarını yapıp kendi kitinizde denedikten sonra siteye yükleyebilecek bi arkadasımız yok mu acaba?
Lütfen yardım edin :'(
http://s3.dosya.tc/server/JKTXXl/STM32F4SAMPLE.rar.html (http://s3.dosya.tc/server/JKTXXl/STM32F4SAMPLE.rar.html)
mrb kolay gelsin.
#include "STM32F4xx.h"
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
// RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
// FLASH->ACR = 0x00000705; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
int main()
{
while(1)
{
if (GPIOA->IDR & 0x000000001) GPIOD->ODR= 0x0000F000; // Ledler yansin
else GPIOD->ODR= 0x00000000; // Ledler sonsun
}
}
program hatasız kitte çalışıyor.
şunlar bende tamam ve problemsiz kit üzerinden programı çalıştırıyorum
-->kitin driverini kurma
-->st-link utility kurma
-->keilin options for targetten utilities kısmından use external tool for flash p. kısmına
command:C:\Program Files\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility\ST-LINK_CLI.exe
arguments:-c SWD -p "$H@H.hex" -Rst -Run bunları yazınca çaışması lazım
void Write(char Adr,unsigned char Data)
{
GPIOE->BSRRH=0x0008; // LIS302DL CS=0
SPI1->DR=((Adr&0x3F)<<8)|Data;
while(!(SPI1->SR&2));
GPIOE->BSRRL=0x0008; // LIS302DL CS=1
}
char Read(char Adr)
{
GPIOE->BSRRH=0x0008; // LIS302DL CS=0
SPI1->DR=((Adr&0x3F)|0x80)<<8;
while(!(SPI1->SR&1));
GPIOE->BSRRL=0x0008; // LIS302DL CS=1
return(SPI1->DR);
}
int main()
{
char who;
if(Read(0x0F)==0x3B) // Who are you ?
Arkadaşlar yukarıdaki program parçacığı @z'nin accelerometer okuma örneğinden.
Burada write ve read fonksiyonlarında okunacak ve yazılacak register adrslerini 0x3f ile çarpmış. Neden?
Bir de 16 bit iletişim seçilmesinin nedeni nedir? 8 bit yetmez mi?
0x3F ile AND işlemine sokmanın sebebi
ilk 6 bitin içeriğine dokunmadan geri kalan son 2 biti 0 yapmak.
örn:
adr içeriği 0xAC = 1010 1100 binary.
bu sayıyı 0x3F ile AND yaparsak
1010 1100
0011 1111
------------
0010 1100
görüldüğü gibi adr değişkenimizin ilk 6 biti değişmedi. son 2 biti 0 oldu.
Neden 16 bit?
8 bit de yapılabilirdi. bu durumda adres bilgisi ve komut bilgisini 2 seferde göndermek ve geleni de aynı şekilde almak gerekirdi.
Burada kullanılan accelerometer çipi adres ve komut olmak üzere 2 baytlık veri kabul ediyor. Bu yüzden tek seferde 16 bit göndermek uygun olur. Eğer karşıdaki cihazdan tek tek veri okumak yerine eepromlarda olduğu gibi peşpeşe çok sayıda veri okumak veya yazmak isteseydik, 8 bit daha kullanışlı olabilirdi.
Cevabınız icin tesekkurler. Peki hocam mazur görün ilk iki biti neden sifirliyoruz?
Bu örnekte adr parametresine belirli bir değerin üstünün yanlışlıkla atılmasını engellemek için kullanılmış.
Programcı adres değeri için 0xFF bile verse adres verisi olarak hiç bir zaman 0x3F en daha büyük bir sayı gönderilmez.
Örnekteki yazma ve okuma rutinlerine dikkat edersen, yazma rutininde adresin son bitinin 1 yapıldığını görürsün. Ama okuma bitinde bu yok. Eğer programcı okuma yapmak isterken yanlışlıkla son biti 1 yaparsa karşı taraf bunu yazma isteği olarak algılayabilir. Bu da istemeyeceğimiz sonuçlar doğurabilir.
Programcı yanlışlık yaparsa zaten programın çalışmasından bu yanlışı anlayabilir , ne gerek var diyebilirsin.
Bu örnek için belki söylenebilir. Ama sorun her zaman programcıda olmayabilir. Çok daha karmaşık işlemlerde değer başka bir operasyon esnasında değişebilir.
Ağzı yanan yoğurdu üfleyerek yermiş.
Kodlara yapılacak bu tip küçük eklentiler, kafanızın çok karışık ve yorgun olduğunuz dönemlerde yapacağınız hatalardan sizi korur.
Hocam cevaplarinz için teşekkür ederim. Tecrübelerinizi ve bilginizi paylaşmanız gerçekten asilce.
Klein hocam okuma esnasında 1 yapılıyor 7. bit değil mi?
evet okuma isteği gönderilirken.
özür dilerim daha yeniyim..umarım bu sorumla canınızı sıkmam ama
while(!(RCC->CR & 0X00020000));
satırında RCC_CR nin içeriğini 00020000 ile AND işlemine sokuyoruz haliyle diğer bitler sıfırlanıyor ve bizi ilgilendiren 17.bit eğer 1 ise sonuç RCC_CR içeriği 00020000 oluyor..değilse 00000000 oluyor sonra birde bunun değilini alıyoruz..while yapısının içi ya FFFFFFFF ya da FFFFDFFF oluyor..içeride bir eşittir ifadesi de sorgulanmıyor..ben bu satırdan hiç bir şey anlayamadım lütfen birisi yardım etsin..ayrıca konu başında -> sembolünü sanki atama sembolüymüş gibi kabul ettik sonra açıklamasını yaparız diye geçtik ama başka yerde bulamadım açıklamasını yapıldı da ben mi göremedim yoksa açıklaması yapılmadı mı?
Çok teşekkür ederim gerbay hocam açık bir anlatım olmuş..
SAYGI DEĞER ARKADAŞLARIM BEN BU DISCOVERY KİTTE BUNALMIŞ HOCAMIZIN YAZDIĞI HİÇ BİR PROGRAMI ÇALIŞTIRAMADIM...YÜKLEME BAŞARIYLA GERÇEKLEŞTİRİLİYOR..PROGRAMLARI ATMAKTA SIKINTI YOK ANCAK USER BUTONUNA DA BASSAM RESET TUŞUNA DA BASSAM HİÇ BİR ŞEY OLMUYOR..DEBUG ETSEM YİNE AYNI..DEĞİŞEN BİŞEY YOK..KENDİ ÖRNEK BLINKY PROGRAMINI ATINCA GAYET GÜZEL ÇALIŞIYOR..BEN NEREDE HATA YAPIYORUM?
Sorun büyük ihtimalle main sembolü hatasıdır.İlk başta bulması zor oluyor ama debug ederken rastladım.
startup_stm32f4xx.S dosyasında;
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
yazan kısmı
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT main ; Burası
LDR R0, =SystemInit
BLX R0
LDR R0, =main ; ve burası degisecek
BX R0
ENDP
Şeklinde değiştirin.Keilda debug ettiğinizde hard faulta atmaması gerekir.Eğer hatanız Hard Fault ise tabi.
@gerbay hocam söylediklerinize katılmıyorum buradaki __main derleyici sembolü.İşletim sistemleriyle uğraştığımdan biliyorum her derleyici sembolleri farklı yorumluyor (siz de biliyorsunuzdur). Debug modunda incelerseniz __main sembolü çağrıldığında çekirdek HardFault moduna düşüyor.Ayrıca yukarıda verdiğim ilk örnekteki orjinal durum ST FW 1.1.0 kütüphanesindeki dosyada yer alıyor.Keil yükleme klasörü > ARM > Startup > ST > STM32F4xx klasörü içerisindeki startup_stm32f4xx.s dosyası da IMPORT main koduyla doğru sembolün __main değil main olduğunu kanıtlıyor(Satır 173).Aslında bu durum genellikle GNU derleyicilerinde oluyor.GCC ve G++ derleyicileri ( GNU başlığı altında ) sembolleri Object koduna __sembol_adi şeklinde Export ediyor.Keil'ın kendi derleyicisi ise (RealView oluyor) sembolleri sembol_adi şeklinde export ediyor.
inceledim + denedim ^ test ettim ~= çalışıyor :)
Sadece keil de değil IAR da da bunalmış hocamızın yazdığı kodları aynen çipe yükledim ama yine çalışmadı..en basit yanıp sönen buton uygulaması bile..ama kendi örnek uygulamaları çalışıyor..bu programları aynen alıp derleyip çalıştırabilen var mı yoksa kimse denemedi mi? :)
özür dilerim arkadaşlar konuya tam hakim olmadığım için şuanda başka birşeyden mi bahsediyorsunuz yoksa programların çalışmaması sorunundan mı anlayamadım? :) gerbay hocamın sölediği fpu seçeneğini not used yaparak yükledim programı yine çalışmadı..bir ledi yakmak ne kadar zor bu arm de? hayır hata söylediğiniz gibi sistemden kaynaklanan bir şeyse benden başka kimse denemedi mi bu programları 7 8 aydır bu kitte anlamadım ki? :)
Arkadaşlar bülent hocanın ilk uygulaması olan led yakma uygulmasını derliyorum sorun yok ,fakat kite attığımda hiçbir action olmuyor çakıldım kaldım nerde hata yapıyorum
#include "STM32F4xx.h"
void SystemInit()
{
RCC->AHB1ENR|=0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER=0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
int main()
{
while(1)
{
GPIOD->ODR= 0x0000F000; // Ledler yansin
GPIOD->ODR= 0x00000000; // Ledler sonsun
}
}
@gerbay hocam haklısınız, afedersiniz :-[ .Kodları disassembly penceresinde teker teker inceledim.Dediğiniz gibi derlenmiş çıktı dosyası yürütülürken ilk işletilen kod __main kodu oluyor.Bu kod bellekte 0x08000188 adresinde.Bizim main fonksiyonumuz ise daha ileride.__main den sonra zero init, scatter load şeklinde data segment belleğe kopyalanıyor.Sorduğunuz sorunun cevabı da açık zaten.
Aslında yanılgımın sebebi GCC derleyicisi.Farklı derleyiciler arasında uyumsuzluk yaşamamak için symbol prefixleri kullanıyorum.Yani eğer __GNUC__ tanımlıysa sembollere '_' ekle, değilse ek yok gibi.Bu da alışkanlık yapıyor _ öneklerini hep sembol olarak algılıyorum :)
Birde sorum olacak, bildiğiniz gibi elimizdeki mcu da kodlar çalışmadan önce Ram adreslerine remap ediliyor.Yani yansıtılıyor.Bu kodlar yalnız okunabilir mi? Yoksa veri akışı çift yönlü mü? Bu yolla Bellek alanına doğrudan erişim sağlayabilir miyiz? Yada bunun için section initializer mantığında bir kod yazarak dinamik veri akışı sağlayabilir miyiz?
Alıntı yapılan: rclk - 08 Ağustos 2012, 02:42:11
Arkadaşlar bülent hocanın ilk uygulaması olan led yakma uygulmasını derliyorum sorun yok ,fakat kite attığımda hiçbir action olmuyor çakıldım kaldım nerde hata yapıyorum
#include "STM32F4xx.h"
void SystemInit()
{
RCC->AHB1ENR|=0x00000008; // GPIOD donanımının clock sinyalini uygulayalım
GPIOD->MODER=0x55000000; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
int main()
{
while(1)
{
GPIOD->ODR= 0x0000F000; // Ledler yansin
GPIOD->ODR= 0x00000000; // Ledler sonsun
}
}
Bu programı keilde debug ederek çalıştırabilirsin. Yani debug'ı açıp f11 ' e basarak adım adım programı işletirsin.
Altında bir tane daha örnek var onu atarsan debug etmeden program çalışır. Programı atınca.
Alıntı yapılan: cooldoubtless - 08 Ağustos 2012, 01:45:10
özür dilerim arkadaşlar konuya tam hakim olmadığım için şuanda başka birşeyden mi bahsediyorsunuz yoksa programların çalışmaması sorunundan mı anlayamadım? :) gerbay hocamın sölediği fpu seçeneğini not used yaparak yükledim programı yine çalışmadı..bir ledi yakmak ne kadar zor bu arm de? hayır hata söylediğiniz gibi sistemden kaynaklanan bir şeyse benden başka kimse denemedi mi bu programları 7 8 aydır bu kitte anlamadım ki? :)
Keil versiyonun nedir?
Aşağıdaki linkte bunalmıs hocanın örneği alınarak oluşturulmuş bir proje var. Projenin tüm ayarları yapılmış vaziyette. dosyaları açtığın klasördeki proje dosyasını çalıştır bir dene bakalım.
http://s3.dosya.tc/server/JKTXXl/STM32F4SAMPLE.rar.html (http://s3.dosya.tc/server/JKTXXl/STM32F4SAMPLE.rar.html)
@gerbay hocam zaten sizin kadar olmasada C yi biliyorum.Dediğim gibi işletim sistemlerinde bu dosyaları ayıklama, PE Header lar ELF dosya formatları çok başımı ağrıttı :)
Siz başka bir durumu mu kasdettiniz anlayaadım ama "remap yok" demişsiniz.Remap var.İşlemci komut işlemeye PC = 0x00000000 dan başlıyor.Bizim Flash bellek alanımız ise aynı veri yolu matrisinde 0x08000000 adresine bağlanıyor.Bu elf hex imajını ise 0x00000000 adresine donanımsal olarak yansıtılıyor.Yani işlemci RAM den 0x00000000 okuduğunda aslında 0x08000000 yani hex verisinin yapıcı metodlarını çağırıyor.Buradan sonra sizinde anlattığınız gibi.Ben ise bu Remap sırasında imajın RAW halinde static verilerin yerleştiğini zannediyordum.Bu şekilde BSS initialize edilebilir ama dediğiniz gibi Data sectionı açıklayamayız.Demekki standart C ayrıştırması kullanılıyor.
Yapı konusunda beni tekrardan bilgilendirdiğiniz için teşekkür ederim.Çalışmalarınızda başarılar...
Projelerde daha hızlı çalışabilmek için ST nin hazır kütüphanelerini kullanabilirsiniz.Hem kendi için de proje örnekleride var.Bu örneklerden faydalanabilirsiniz.Oradaki projeleri Template olarak kullanabilirsiniz.ST Firmware v1.1.0
keil versiyonum 4.54..ilgilendiğiniz için teşekkür ederim..evet bu son gönderdiğiniz projeyi LOAD ile değil ama DEBUG ile çalıştırabildim...bunun nedeni nedir sizce? programlarda yapılan hangi hata buna neden oluyor?
Load ile çalışmaması STLINK kaynaklı bir sorun. Forumda çözümü ile ilgili bir başlık var.
Senin ayarlarda debug STLINK seçili mi? simulatorde kalmış olabilir.
gerçekten çok çok ilginç...gönderdiğiniz projeyi açtığımda herşey gayet normal debug ettiğimde ledler tepki veriyor..ancak bu projedeki kodları alıp kendim derlemeye çalıştığımda kitteki ledler hiç bir tepki vermiyor...o çalışan projedeki seçili olan seçeneklerin hepsini kendi yaptıgım projemde de yaptım..derleme şeklim de ilk once new project yapıorm stm32f407vg yi seçiorum projeye start dosyasını eklemesi için evet diyorum..sonra new den yeni kod sayfası açıyorum..oraya kodları yazıyorum(kopyala yapıştır yaptığım da oldu acaba kodları yanlış mı yazıyorum diye) sonra save as den dosyayı xxx.c olarak kaydediyorum...sonra soldaki proje kısmında source group dosyasına sağ tıklayıp oluşturduğum bu xxx.c dosyasını projeye ekliyorum...sonra derleme ve debug seçeneklerini aynen gönderdiğiniz projedeki gibi yapıyorum..sonra once derleme yapıyorum peşine de debug yapıyorum..her şey aynı ancak tek fark birinde kitteki ledler yanıyor birinde yanmıyor :)
seçili klein hocam hatta gönderdiğiniz projede st link (deprecated version) seçili bende ole denedim..ama sonuç aynı..
Proje klasörünü komple upload et. Ben çalıştırmaı deneyeyim.
Programı karta atmada sıkıntı yoksa büyük ihtimal kodda donanımsal sorun vardır.Proje ayarlarında Use Microlib ve Use FPU seçeneklerini kapatmayı deneyin.Debug modunda neler lduğunu kimin nereye dallandığını izleyin.Sonra ST LINK Utility ile kodları geri okuyup attığınızla karşılaştırın.Aynı olması gerekir.Aynı değilse kartı taktığınızda Aygıt yöneticisini açın ve oradan
(http://img18.imageshack.us/img18/5273/53283874.png)
(http://img594.imageshack.us/img594/2050/67467169.png)
(http://img18.imageshack.us/img18/5273/53283874.png)
yaparak sürücüyü güncelleyin.
Eğer program atmada sorun olmadığından emin olduysanız kodlarda sorun vardır.ST nin Peripheral kütüphanesindeki Projects\Peripheral Examples\IO_Toggle\ projesini Keilde açın.Proje ayarlarında Output sekmesinde Create Hex file işaretleyin.Projeyi derleyin.Bu biraz sürebilir.Sonra oluşan HEX dosyasını STLink Utility ile çipe yükleyin.Ledlerin sırayla yanıp aynı anda sönmesi gerekir.HEr program attıktan sonra çipi resetlemeyi unutmayın...
http://www.upload.gen.tr/d.php/www/993akmse/deneme2.rar.html (http://www.upload.gen.tr/d.php/www/993akmse/deneme2.rar.html) buraya yükledim proje dosyasını..program aynen çalışan bana gönderdiğiniz projeden kopyala yapıştır yaptığım program..haberlerinizi büyük bir merakla bekliyorum..
Kart tanımda değil. Yarın yüklemeyi denerim.
Proje ayarlarına baktım.
Debugger "ST-LINK" değil. "ULINK Cortex debugger" seçilmiş.
bende st link gözükürken sizde neden öyle gözüküyor :s
ST-Link ayarlarında SWD protu seçili değil mi?
ilk önce şunu söleyeyim ben keil in son sürümünü kullanıyorum...burada debug bölümünden eğer st-link debugger seçersem settingse tıklayınca swd mi jtag mı diye biryer çıkmıyor..altta da verdiğim resimdeki görüntü çıkıyor burada da gördüğünüz gibi port seçeneği sw seçilmilş durumda
(http://s8.postimg.cc/nni6uzxtt/Ads_z.jpg) (http://postimg.cc/image/nni6uzxtt/)
Alıntı yapılan: gerbay - 08 Ağustos 2012, 00:17:03
buna 4 satır ilave ederek HW FPU yu etkinleştirmek gerekiyor; şöyle olacak (aslında yukarda da vermiştim)
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
;FPU settings
LDR R0, =0xE000ED88 ; Enable CP10,CP11
LDR R1,[R0]
ORR R1,R1,#(0xF << 20)
STR R1,[R0]
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
ben de yeni başladım ve en son sürümü indirdim. uygulamaları çalıştıramıyordum yukarıdaki 4 satırı ekleyince sorun ortadan kalktı.
cevabınız için teşekkür ederim..nereye eklemem gerekiyor bu 4 satırı ?
mesaj birleştirme:: 10 Ağustos 2012, 03:37:08
a evet şuanda baktım o çalışan projelerin hepsinde o satırlar ekli..çok ilginç ama bu kadr amatörce bir iş de olmaz..bir mikroişlemci tanıtma amacıyla yapılmış kitte böyle saçma sapan bir şeyle insanları bu derece uğraştırmaları çok komik..çok teşekkür özgür arkadaşım klein arkadaşım ve de fatih arkadaşım..3 nüz de çok yardımcı oldunuz..ben o indirdiğim projelerdeki stm32f4xx.h dosyalarıyla bendekileri değiştireyim en iyisi..
Bu kodlar zaten FPU ünitesini etkinleştirmek için.Aynı zamanda bu etkinleştirme işlemini ST Kütüphanesindeki system_stm32f4xx.c dosyasında da yapılıyor.Kolay proje yapabilmek için ST kütüphanelerini kullanmanızı tavsiye ederim.Ama hepten tembellik yok :) Bazı temel işlemleri bilmek gerek, gerisi boşa zaman kaybı olur...
Klein hocam sizin dosyayı indiremiyorum.İlgilenen herkese cok tesekkür ederim.Kart şuan yanımda değil deneyemiyorum malesef.İlk fırsatta deneyeceğim insallah.Tekrardan cok tesekkür edrim.
Klein hocam tekrar yükleyebilirseniz cok sevinirim.Kolay gelsin....
@EMP_Otto: Liink sağlam. kontrol ettim. FireFox veya Chrome ile bir dene.
@cooldoubtless
Benim sürüm 4.22 bu yüzden projeyi açamamış ve default ayarlarla yeniden proje oluşturmuş olabilir. Ayarların farklı çıkması bundan muhtemelen.
Debugger ayarlarını değiştirip yükledim. Çalışmadı. Sebebini zaten biliyorsun. Use_Fpu meselesi. Onu düzeltince çalıştı.
evet o ayarları düzeltince bende de artık çalışıyor her proje yardımlarınız için herkese çok teşekkürler.
Klein hocam indirdim link firefoxta çaılısıyormus:) en kısa zamanda denerim.Cok tesekkür ederim...
Kolay gelsin...
USART3->BRR=0X1112; // 9600 Baud
baud hızını bu şekilde nasıl bulduk.dökümandan pek bişey anlamadım.
Arkadaşlar şöyle bir sorunla karşılaştım;
GPIOA->OSPEEDR = 0xFFFFFFFF; şeklinde ayar yaptıgımda keil GPIOA nın tanımsız oldugunu söylüyor ama dökümanda GPIOx_OSPEEDR şeklinde tanımlamış ,hatalı bi kullanım mı yapıyorum.
Birde GPIOA,GPIOD-> = 0xFFFFFFFF; şeklinde yaptıgımda hata felan vermiyor ,bide bu kullanım dogru mu ?
Şimdiden teşekkür ediyorum,
Yardımlarınızı bekliyorum.
nasıl bir hata veriyorki
SystemInit()
{
.
.
}
GPIOA->OSPEEDR= 0xFFFFFFFF;
systeminit in dışında tanımlama yapıldığında hata verdiğini biliyorumda başka bir nedeni varsa bilmiyorum.
Alıntı yapılan: sseedat - 14 Ağustos 2012, 00:40:45
nasıl bir hata veriyorki
SystemInit()
{
.
.
}
GPIOA->OSPEEDR= 0xFFFFFFFF;
systeminit in dışında tanımlama yapıldığında hata verdiğini biliyorumda başka bir nedeni varsa bilmiyorum.
problem çözüldü defalarca F7 yaptım programı açıp kapattım tekrar derledim hata vermedi. :-\
discovery kit ile kaç tane fırçasız doğru akım motoru sürebiliriz? tabi esc bağlayarak..ama kaç pinden pwm çıkışı alabiliriz acaba?
tim1 üzerinde 4 farklı duty oranında pwm sinyali elde edebilirsin.
This example shows how to configure the TIM1 peripheral to generate 7 PWM signals
with 4 different duty cycles (50%, 37.5%, 25% and 12.5%).
TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock
SystemCoreClock is set to 168 MHz for STM32F4xx devices.
The objective is to generate 7 PWM signal at 17.57 KHz:
- TIM1_Period = (SystemCoreClock / 17570) - 1
The channel 1 and channel 1N duty cycle is set to 50%
The channel 2 and channel 2N duty cycle is set to 37.5%
The channel 3 and channel 3N duty cycle is set to 25%
The channel 4 duty cycle is set to 12.5%
The Timer pulse is calculated as follows:
- ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100
ya aynı duty cycle ile 4 motoru da sürmek istersem? quadrotor projesi için soruyorum
Alıntı yapılan: cooldoubtless - 15 Ağustos 2012, 21:13:42
discovery kit ile kaç tane fırçasız doğru akım motoru sürebiliriz? tabi esc bağlayarak..ama kaç pinden pwm çıkışı alabiliriz acaba?
Tüm timer registerlerini incelemedim ama görebildiğim kadarıyla
TIM1,2,3,4,5,8,9,10,11,12,13,14 timerlerinde output compare modülü var. Muhtemelen hepsinin de 4 kanalı var. 48 PWM çıkışı elde edilebilir anlamına geliyor.
Tabi bazı pinler 2 farklı timer için kullanılabiliyor. Ya birini ya diğerini seçebiliyorsun. Bunun yanında bazı timer çıkışları da farklı pinlere yönlendirilebiliyor. Bu yüzden HARD dokümanı sayfa 51'den başlayan alternatif fonksiyon haritasını detaylı inceleyip , timer pinlerinin haritasını çıkarmadan bu soruya kesin bir cevap vermek zor.
Dokümana Genel bir bakış ile 20'den fazla bağımsız pin olduğunu gördüm. Daha farklı kombinasyonlarla bu sayı artırılabilir.
Alıntı yapılan: cooldoubtless - 15 Ağustos 2012, 23:54:32
ya aynı duty cycle ile 4 motoru da sürmek istersem? quadrotor projesi için soruyorum
Aynı duty oranı ile dört motoru sürsen, quadrocopter nasıl dengede kalacak. Mems sensorlerden alınan bilgiler işlencek 4 farklı duty çıkacak. Buna göre motorlar sürülecek.
Alıntı yapılan: pisayisi - 16 Ağustos 2012, 00:05:37
Aynı duty oranı ile dört motoru sürsen, quadrocopter nasıl dengede kalacak. Mems sensorlerden alınan bilgiler işlencek 4 farklı duty çıkacak. Buna göre motorlar sürülecek.
nasıl yani..havada asılı kalması için 4 motorun da aynı devirle dönmesi gerekmez mi en basitinden..neyse zaten eğer klein hocamın dediği olay varsa buna da gerek kalmaz rahat biçimde sürülebilir..teşekkür ederim herkese..
Teorik olarak 4 motor aynı devirde dönerse , quadrocopter dengede kalır.
Ancak bunun olabilmesi için:
Tüm motorların tamı tamına aynı devirde dönmesi, tüm kolların pervane motor ve diğer aksamlarının tamı tamına aynı ağırlıkta olması ,pervanelerin kusursuz bir şekilde aynı geometriye sahip olması , ağırlık merkezinin hatasız olması vs.. gibi şartlar gerekir.
Bunun yanında rüzgar, basınç farkları gibi etkenlerin hiç olmaması gerekir.
Pratikte bu şartlar hmen hemen hiç karşılanmaz. Bu yüzden tüm kolların farklı devirde dönmesi gerekir.
elbette öle hocam hemen hemen teorik hiç bir bilgi pratiği tutmaz ama yakın olacağı kesindir..en azından 1.motorun %50, 2.sinin %25, 3. sünün %12.5 ,4.sünün %12.5 luk duty cycle ile kontrol ettiğinizde o quadrotoru dengede tutamayacağınız kesindir..yoksa zaten geri besleme, bozucu etkiler için ileri besleme gibi kavramlara kontrolde ihtiyaç kalmazdı :)
Merhaba arkadaslar.Kitle ilgili sorunum devam ediyor.Klein hocam paylaşmış lduğunuz programda çalıışmadı kitte.Fakat keil ile biri,likte gelen blinky programı sorunsuz çalışıyor :'(
Yardımcı olabilirseniz çok sevinirim.
Keil'i kaldırıp 4.22 versiyonu kurup bir dener misin?
TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles.
In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),
since APB1 prescaler is different from 1.
TIM3CLK = 2 * PCLK1
PCLK1 = HCLK / 4
=> TIM3CLK = HCLK / 2 = SystemCoreClock /2
To get TIM3 counter clock at 28 MHz, the prescaler is computed as follows:
Prescaler = (TIM3CLK / TIM3 counter clock) - 1
Prescaler = ((SystemCoreClock /2) /28 MHz) - 1
To get TIM3 output clock at 30 KHz, the period (ARR)) is computed as follows:
ARR = (TIM3 counter clock / TIM3 output clock) - 1
= 665
TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
ARKADAŞLAR BU AÇIKLAMALAR STM NİN PWM UYGULAMASINDAN...ŞİMDİ BU AÇIKLAMALARA BAKIP NEYİN NE OLDUĞUNU ANLAYAN VAR MI YOKSA BENDE Mİ SORUN VAR?:) 3 FARKLI DENKLEM VAR AMA ÇOK BİLİNMEYEN VAR GİBİ GÖZÜKÜYOR..DİYELİM Kİ %50 PWM İSTİYORUM..TIM3CLK=84MHz onu biliyoruz..O halde..
Prescaler = (84000000 / TIM3 counter clock) - 1
ARR = (TIM3 counter clock / TIM3 output clock) - 1
TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
bu 3 denklemi nasıl çözebilirim burda TIM3CLK dışında başka bilinen bişey mi var da ben göremiyorum?
mesaj birleştirme:: 26 Ağustos 2012, 00:47:21
lütfen biri cevap verebilir mi? ???
Tamam hocam denicem :)
ACaba Keil 4.22 linki var mı??
@EMP_Otto
Keil linki sitede vardı. Keil kurulumu ile ilgili bir başlık vardı. oradaolabilir.
@cooldoubtless
Verdiğin açıklamalardan ben de bir şey anlaadım.
Amaç PWM meselesini halletmek ise, daha önce bu başlıkta ve OOP başlığında PWM ile ilgili örnekler ve açıklamalar vermiştim.
Prescaler bildiğin gibi bölücü.
ARR timerin yeniden yükleneceği nokta. Eğer ARR için 1000 değeri verdiysen , counter 1000 olduğunda counter resetlenir, pwm çıkışın 0 olur. CCRx registeri ise, compare değeridir. Yani duty-cycle oranını belirler. Eğer ARR 1000 ise, %50 oran almak için CCRx registerine 500 değeri yüklemelisin.
Hocam evt ben de o şekilde biliyorum ancak uygulamaya gelince kafa karıştıran çok şey oluyor demekki tam oturmamış mantığıma..Bunalmış hocamızın yaptığı pwm örneğinden aldığım bir kısımı sormak istiyorum...
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =839; // Prescaler degerimiz 839, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 84E6 / (840) = 100 KHz
TIM7->ARR =1; // Counter, Decimal 1 olunca basa donsun. Her 20 mikrosaniye de bir timer int olusacak.
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
}
burada arr 1 olduğunda başa dönsün derken sadece 0 dan 1 e geçiş süresi var demektir..yani 1/100 Khz den 10us oluyor..ama bunalmış hocamız 20 us demiş..hatayı nerede yapıyorum acaba?:s
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //Extm
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOE, &GPIO_InitStructure);
Portu 100MHz e kurduktan sonra
while(1)
{
GPIO_SetBits(GPIOE, GPIO_Pin_4); //EXTM
GPIO_ResetBits(GPIOE, GPIO_Pin_4); //EXTM
}
Böyle bir döngü yapıp skopla çıkışı gözlemlediğimde düşenlar daha uzun (54nS) yükselen kenarlar daha kısa (42nS) sürdü.
while(1)
{
GPIO_ResetBits(GPIOE, GPIO_Pin_4); //EXTM
GPIO_SetBits(GPIOE, GPIO_Pin_4); //EXTM
}
Burada ise tam tersi oldu.
Burada aklıma takılan şey iki komut arasındaki değişim süresi daha kısa olması gerekmez miydi?
Ayrıca bu sürelere bakarsak hesaplanan frekans yaklaşık 13.157Mhz çıkıyor.
En başta set edilen 100MHz den bu frekans nasıl çıkıyor bununla ilgili bir bağıntı var mı?
GPIO_ResetBits ve GPIO _SetBits komutları st firmware library komut setine ait dolayısı ile pekçok alt komut işletiliyor bu satırlarda, çıkıştaki frekans ta bu gecikmelere bağlı olarak kestirilemeyebiliyor. En güzeli doğrudan asm ile hatta dma kullanarak port çıkışlarını kontrol ederseniz daha olası üst frekanslara çıkmak mümkün olabilir.
while(1)
{
GPIO_ResetBits(GPIOE, GPIO_Pin_4); //EXTM
GPIO_SetBits(GPIOE, GPIO_Pin_4); //EXTM
}
Alıntı yapılan: pisayisi - 28 Ağustos 2012, 13:28:30
GPIO_ResetBits ve GPIO _SetBits komutları st firmware library komut setine ait dolayısı ile pekçok alt komut işletiliyor bu satırlarda, çıkıştaki frekans ta bu gecikmelere bağlı olarak kestirilemeyebiliyor. En güzeli doğrudan asm ile hatta dma kullanarak port çıkışlarını kontrol ederseniz daha olası üst frekanslara çıkmak mümkün olabilir.
while(1)
{
GPIO_ResetBits(GPIOE, GPIO_Pin_4); //EXTM
GPIO_SetBits(GPIOE, GPIO_Pin_4); //EXTM
}
Haklısınız st firmware kütüphanesindeki ResetBits ve SetBis fonksiyonlarının içine baktım.
Parametreleri kontrol eden assert_param fonksiyonları ile gereksiz yere kodu yavaşlatıyor.
Bu fonksiyonları kullanmak yerine kodu şu şekilde değiştirdiğimde olması gereken zamanlama ile karşılaştım.
GPIOE->BSRRL = GPIO_Pin_4;
GPIOE->BSRRH = GPIO_Pin_4;
Bu assert param fonksiyonları st library deki tüm fonksiyonlarda var hıza önem veren arkadaşların kendi kütüphanesini oluşturmasını gerekirse asm kullanmasını birkez daha hatırlatalım :)
sonuç olarak cevap verildi mi anlayamadım 10us mi 20us mi?
Yaklaşık 8nS ye kadar inebildiğini gördüm.
Yani yaklaşık 100Mhz i buldum. Nasıl mı?
ST nin hazırladığı fonksiyonları kullanmayarak...
Alıntı yapılan: XX_CİHAN_XX - 28 Ağustos 2012, 14:05:41
Bu assert param fonksiyonları st library deki tüm fonksiyonlarda var hıza önem veren arkadaşların kendi kütüphanesini oluşturmasını gerekirse asm kullanmasını birkez daha hatırlatalım :)
Peki CIHAN, GPIOE->ODR=0x10 yapsak "PE_4 High"
BSRR mi yoksa ODR mi daha hızlı deneme şansın var mı?
Alıntı yapılan: digiman - 29 Ağustos 2012, 00:56:17
Peki CIHAN, GPIOE->ODR=0x10 yapsak "PE_4 High"
BSRR mi yoksa ODR mi daha hızlı deneme şansın var mı?
Denedim hız olarak hiç bir fark yok.
#include "STM32F4xx.h"
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55550000; // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
GPIOE->MODER = 0xAA0A0000; // TIM1 CHANNEL1 kullanacagim için e portunu alternatif fonk.seçtim
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
RCC->APB2ENR|=0x00000001; // Timer1 CLK'u aktif edelim (168 Mhz)
TIM1->PSC =1679; // Prescaler degerimiz 1679, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 168E6 / (1680) = 100 KHz
TIM1->ARR =1000; // Periyot 1000
TIM1->CCR1=100; // Duty cycle
TIM1->DIER=0x0001; // Update Int enable
TIM1->CCMR1=0x0070; // PWM Mode 2 yi seçtik bu yüzden '111' yazdik.
TIM1->EGR=0x0001; // UG biti 1 yaptk
TIM1->CR1=0x0081; // Otomatik Reload VE SAYICIYI BASLAT
}
int main()
{
while(1);
}
arkadaşlar artık şu kitle bir bldc nin döndüğünü görmek istiyorum..ancak bir türlü beceremiyorum..system init fonksyonlarımda bir yanlış olduğunu düşünmüyorum..varsa beni uyarırmısınız? ayrıca şimdi bütün sayma işlemlerini karşılaştırma işlemlerini benim için bu registerlar yapıyorsa benim main fonksiyonuna başka ne yazmam gerekecek?
6 fetli sürücünün hangi çıkışı hangi porta bağlı, geribesleme hall sensorleri hangi pinlere bağlı şöyle bir şematik olsa daha anlaşılır olcak...
Klein hocam Keil in 4.22a versiyonunu kurdum göndermiş olduğunuz programı derledim kite yükledim ama yine bi atraksiyon olmadı :)Sonra tekrar 4.53 versiyonunu kurdum birde onda denedim yine olmadı.Derlemede ve kite yüklemede sorun yok.Daha sonra Keil ile birlikte gelen Blinky projesini derleyip kite yükledim çalıstı.
Bu işi bi türlü anlamadım yaaa herkeste çalışan kod bende çalışmıyor.Kitte sorun olsa Blinky projeside çalışmaması lazım diye düşünüyorum.
ARtık yuardım edin demekten utanır oldum :'(
@EMP_Otto Hangi şehirdesin bilmiyorum. Eğer Ankara'da isen, gel bana birlikte halledelim.
Alıntı yapılan: pisayisi - 30 Ağustos 2012, 12:29:14
6 fetli sürücünün hangi çıkışı hangi porta bağlı, geribesleme hall sensorleri hangi pinlere bağlı şöyle bir şematik olsa daha anlaşılır olcak...
şemayı ekliyorum..fırçasız dc motor ile esc kullanıyorum..yani ayrıca sürücü kurmadım..motor kontrolünü geri beslemeli denetim yapmayacağım için ayrıca bir sensör kullanmıyorum sadece vereceğim pwm oranıyla motorun dönmesini istiyorum hepsi bu..TEK KANAL ÜZERİNDEN PWM GÖNDERİYORUM..bu bağlantı da esc nin beyaz kablosuyla gerçekleşiyor..yaklaşık %10 luk bir pwm programda da gördüğünüz gibi..programda ne gibi eklemeler olmalı acaba?(http://postimg.cc/image/qqg5w45jx/%5D%5Bimg%5Dhttp://s14.postimg.cc/qqg5w45jx/SEMA.jpg)
(http://i47.tinypic.com/b4tfh3.jpg)
şema gözükmediği için tekrar yükledim :)
@cooldoubtless pwmi izleyebiliyomusun scop - logic analyzer varmı. Eğer pwm düzgün bir şekilde çıkıyorsa esc nin çalışması için önce pwm sinyalini 1 ms olarak uygulaman lazım esc hazır duruma geçsin sonra yavaş yavaş pwmi arttırmalısın.
TIMx Channel1 duty cycle = (TIMx_CCR1/ TIM3_ARR + 1)* 100
pwm duty oranın yüzde 10 gibi hesaplanıyor bu oranla çıkışta birşey süremezsin,
Prescaler = (TIMxCLK / TIMx counter clock) - 1
örneğin TIMxCLK=21 Mhz ise
PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1=3 olabilir;
prescalar hesabında yanlış gibi duruyor...
st firmware ile yazılmış aşağıdaki örneği incelemeni ve parametreleri firmware kullanmasan bile aşağıdaki gibi belirlemeni öneririm...
/**
******************************************************************************
* @file TIM/PWM_Output/main.c
* @author MCD Application Team
* @version V1.0.1
* @date 13-April-2012
* @brief Main program body
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
/** @addtogroup STM32F4xx_StdPeriph_Examples
* @{
*/
/** @addtogroup TIM_PWM_Output
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint16_t CCR1_Val = 333;
uint16_t CCR2_Val = 249;
uint16_t CCR3_Val = 166;
uint16_t CCR4_Val = 83;
uint16_t PrescalerValue = 0;
/* Private function prototypes -----------------------------------------------*/
void TIM_Config(void);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f4xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
/* TIM Configuration */
TIM_Config();
/* -----------------------------------------------------------------------
TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles.
In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),
since APB1 prescaler is different from 1.
TIM3CLK = 2 * PCLK1
PCLK1 = HCLK / 4
=> TIM3CLK = HCLK / 2 = SystemCoreClock /2
To get TIM3 counter clock at 21 MHz, the prescaler is computed as follows:
Prescaler = (TIM3CLK / TIM3 counter clock) - 1
Prescaler = ((SystemCoreClock /2) /21 MHz) - 1
To get TIM3 output clock at 30 KHz, the period (ARR)) is computed as follows:
ARR = (TIM3 counter clock / TIM3 output clock) - 1
= 665
TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
Note:
SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
function to update SystemCoreClock variable value. Otherwise, any configuration
based on this variable will be incorrect.
----------------------------------------------------------------------- */
/* Compute the prescaler value */
PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 665;
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel4 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(TIM3, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);
/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE);
while (1)
{}
}
/**
* @brief Configure the TIM3 Ouput Channels.
* @param None
* @retval None
*/
void TIM_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOC clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/* GPIOC Configuration: TIM3 CH1 (PC6), TIM3 CH2 (PC7), TIM3 CH3 (PC8) and TIM3 CH4 (PC9) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Connect TIM3 pins to AF2 */
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_TIM3);
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
while (1)
{}
}
#endif
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Alıntı yapılan: SERRO EFE - 31 Ağustos 2012, 09:20:59
@cooldoubtless pwmi izleyebiliyomusun scop - logic analyzer varmı. Eğer pwm düzgün bir şekilde çıkıyorsa esc nin çalışması için önce pwm sinyalini 1 ms olarak uygulaman lazım esc hazır duruma geçsin sonra yavaş yavaş pwmi arttırmalısın.
hayır ne yazıkki logic analyzer yok oyüzden çıkışı izleyemiyorum..
@pisayisi.. evt duty cycle %10 sölemiştim..bu oran yeterli değilse dediğin gibi bu oranı %50 ye çıkariyim..ama prescaler değeri doğru gibi duruyor..168mhz timer1 o yüzden..
mesaj birleştirme:: 31 Ağustos 2012, 22:13:55
esc ler genellikle en fazla 50 mhz ile çalışıyomuş o yüzden hemen düzelttim programı 100mhz den 10mhz e düşürdüm..ancak değişen bir şey yok..:) çok ilginç herkes rc sistemlerle takıp esc leri kumandayla sürmüş bununla ilgili bilgiler mevcut ancak bir mikrodenetleyici üzerinden pwm ile esc ye sinyal gönderip motoru döndüren bir kişi bulamadım..bilgi bulamadım..elbette yapan çok kişi vardır ama forumlardan uzaktır..eminim işi bilen için 10 dakika bile almaz ancak bizim gibi tecrübesizler böyle aylarca uğraşıyor..bu kadar zor olacağını beklemiyordum bir motor döndürmenin :D
Yanlış biliyorsunuz escler "50MHZ" değil 50-60 hz çalışır esc yi çalıştırabilmen için "RC SERVO" sinyali çıkarman lazım denetleyicinle.
(http://pamungkas99.files.wordpress.com/2010/02/servo2.jpg?w=500&h=240)
hadi ya 50 hz miymiş aradaki fark milyonda bir :) teşekkür ederim bilgi için ama ben fırçasız doğru akım motoru süreceğim yani bu şekilde açı açı bilgi girmek zorunda değilim diye düşünüyorum..e sonuçta bu stm32f4 ü boşuna mı aldık okadar pwm çıkışı var onlardan biri bizim yerimize bunlarla uğraşmıyor mu? pwm pininin zaten amacı bu değil mi? "ben alternatif fonksiyonlardan pwm çıkışını bir timer a atıyorum..gerisini o hallediyor.."diyebilmeliydim..ama diyemiyorum :) esc lerin başlangıçta belli bir süre high belli bir süre de low sinyal verilerek dönüşe hazır hale getirilmesi gerektiğini biliyodum..ancak rehber'i neredeyse tamamen hatmettim ama böyle bir bilgi yok..pwm çıkışı almak için de böyle bir not düşülmemiş ben de heralde gerek yok diye düşündüm..zaten bana 20 ns logic 0 ver desen veremem ki bunla..pic değil ki bu..gecikme fonksiyonuyla da birşey yapamıyorsun yine bir sayıcı kullanmam gerekir heralde..nebilim saç baş yolduracak cinsten bir işlemci..her noktası sırlar odası..adam gibi rehber de yok..
Gecikme fonksiyonları için bir SysTick olayı var zaten. kolaylıkla istediğiniz aralığa ayarlıyabilirsiniz. Bu gecikme olayının hazır bir kütüphanede bulunması çok kolaylık olurdu. Birde standart karakter LCD için bir kütüphanesi olsa iyi olurdu vs.vs. Rehber zaten berbat durumda, işlemciyi beğendim ama dökümantasyon ve yardım berbat durumda. Umarım ST buna bir çözüm bulur.
Alıntı yapılan: fatih6761 - 01 Eylül 2012, 19:53:04
Gecikme fonksiyonları için bir SysTick olayı var zaten. kolaylıkla istediğiniz aralığa ayarlıyabilirsiniz. Bu gecikme olayının hazır bir kütüphanede bulunması çok kolaylık olurdu. Birde standart karakter LCD için bir kütüphanesi olsa iyi olurdu vs.vs. Rehber zaten berbat durumda, işlemciyi beğendim ama dökümantasyon ve yardım berbat durumda. Umarım ST buna bir çözüm bulur.
hocam bu SysTick ile istediğimiz aralığı ayarlayabildiğimizi söylemişsiniz..forumda herhangi bir sayfada açıklaması varsa gösterirseniz çok memnun olurum hemen uygulamak isterim..
ST nin kendi Peripheral Examples projelerinde SysTick adlı bir proje olacaktı. Orada herşeyi anlatılmış. Diğer örneklerde de zaten görürsünüz Delay kullanan bütün projelerde var.
Basitçe ST kütüphanesinden SysTick_Config(SystemCoreClock / 1000) ile her 1 milisaniyede bir interrupt oluşturabilirsiniz. Bu kesmeleri SysTickHandler(?) ile yakalarsınız. Zaten kesme stm32f4xx_it.c dosyasında (adından emin değilim ama sonu _it.c ile bitiyor ) rutini bulursunuz.
Alıntı yapılan: fatih6761 - 01 Eylül 2012, 20:41:39
ST nin kendi Peripheral Examples projelerinde SysTick adlı bir proje olacaktı. Orada herşeyi anlatılmış. Diğer örneklerde de zaten görürsünüz Delay kullanan bütün projelerde var.
Basitçe ST kütüphanesinden SysTick_Config(SystemCoreClock / 1000) ile her 1 milisaniyede bir interrupt oluşturabilirsiniz. Bu kesmeleri SysTickHandler(?) ile yakalarsınız. Zaten kesme stm32f4xx_it.c dosyasında (adından emin değilim ama sonu _it.c ile bitiyor ) rutini bulursunuz.
çok teşekkür ederim hocam..hemen bakiyim ben..
@cooldoubtless
ESC sürmeye mi çalışıyorsun ?
Pwm sinyalin 50 hz olması gerek. Başlangıçta Dutylerin 1ms olması gerek (olmazsa escler Ayar moduna girer.)
Esc Sürmek İçin Bu işlemci birkaç boy büyük kaçar.
Sana Tavsiyem Önce bir Servo tester yap.
amaç bir motor sürmek değil tabiki..quadrotor projesinde kullanacağım..elbette ilk adım bir motoru sürebilmek..sonra sensörlerden veri alıp ona göre motorları sürmeye çaıştırmayı başarmak istiyorum..hedeflerim bunlar en azından..daha ilk adımdayım ve de çakıldım..servo tester dan kasıt nedir?
mesaj birleştirme:: 01 Eylül 2012, 22:15:08
gördüm hocam güzel bişeymiş evet sorun programda mı motordamı anlamak için gayet mantıklı bir çözüm..hemen ediniyorum ama yine de programımın yeterli olduğunu düşünmüyorum..
Hocam Satın Almayın. Siz Yapın ki Hem RC servo hem ESC Nasıl Kullanılır Çözebilelim. Bu arada PWM de aradan çıkmış olur.
mesaj birleştirme:: 01 Eylül 2012, 23:27:04
Aslında Konu ile ilgili olarak
hobbyrc.com u ziyaret etseniz ve biraz karıştırsanız RC ile alakalı epeyce bilgi bulabilirsiniz.
mesaj birleştirme:: 02 Eylül 2012, 00:05:14
http://www.fatihinanc.com/diger/stm32f4-discovery-gelistirme-kiti-incelemesi/ (http://www.fatihinanc.com/diger/stm32f4-discovery-gelistirme-kiti-incelemesi/)
hocam ben mesela kendimce bir program yazmaya çalıştım..saçma sapan oldu belki ama register ile kitin her hangi bir pininden %20 lik %30 luk her neyse tek kanal bir pwm sinyali çıkaracak bir program yazmak yazabilmek amaç..
Alıntı yapılan: cooldoubtless - 01 Eylül 2012, 23:30:05
hocam ben mesela kendimce bir program yazmaya çalıştım..saçma sapan oldu belki ama register ile kitin her hangi bir pininden %20 lik %30 luk her neyse tek kanal bir pwm sinyali çıkaracak bir program yazmak yazabilmek amaç..baktım forumumuzda da bu yok..başka forumlarda zaten hiç yok..keşke bunu yapabilsem ya da uğraşan biri olsa çok iyi olurdu..
mesaj birleştirme:: 02 Eylül 2012, 02:01:06
Ararsan forumda her şey var.
https://www.picproje.org/index.php/topic,37420.0.html (https://www.picproje.org/index.php/topic,37420.0.html)
https://www.picproje.org/index.php/topic,37447.0.html (https://www.picproje.org/index.php/topic,37447.0.html)
@klein hocam teşekkür ederim..forumda emin olun pek çok kişinin vakit geçirdiği zamanların toplamından daha fazla bulunuyorum..sizin verdiğiniz linkler yer imlerimdeydi zaten..bana attığınız özel mesajda da bunlardan bahsetmiştiniz..ben c++ hakkında bir şey bilmiyorum..timer init uygulamalarında ise ben sadece register olayından anladığım için bu garip garip cmsis fonksiyonları bana birşey anlatmadı ve gözümü korkuttu ancak sonra yine sizin register-cmsis dönüşümü yaptığınız uygulamalarla bu eksiğimi giderdim..yani şu anda böle bir sorunum yok ama tabiki yer imlerinde kalmış oldu ne yazıkki..tekrar hatırlattığınız için teşekkür ederim..en kısa zamanda deneyip bilgi vericem burada..
denedim arkadaşlar..olmadı ne yazık ki..yazdığım programı ekliyorum içine delay de ekledim ancak yine tepki yok..50hz lik sinyal istediğimden clock ayarlamaları biraz kafa karıştırdı..bu programla (stm nin kendi örnek kütüphane kodlarıyla) çalıştırmayı beceremedim..4 kanallı bir uygulamaydı ben timer ayarlamalarını fln ona göre yaptım ama sadece birinci kanalın ccr1 değerini girdim çünkü amacım sadece motoru döndürebilmek..daha sonra o kanalları da kullanırım..elinde bir esc motor olan biri bu uygulamayı yapıp da bir sonuç aldıysa lütfen bana nerede hata yaptığımı söyleyebilir mi?
#include "STM32F4xx.h"
#define SysClock 168.0L //Sistem 168 Mhz de çalışıyor
#define DELAY_uS(A) _usDelay(((long double) A * ((long double) SysClock)-5.50L) / 21.50L)
void TIM_Config(void);
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07405408; // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
}
void _usDelay(long double Count)
{
u32 i=0;
for(i=0;i< (unsigned long)Count;i++);
}
int main(void)
{
TIM_Config();
GPIOC->ODR|=0x00C0 ;
GPIOB->ODR|=0x0003 ;
DELAY_uS(900);
GPIOC->ODR|=0x0000 ;
GPIOB->ODR|=0x0000 ;
DELAY_uS(20000);
TIM3->CR1=0x0080; // Otomatik Reload,4.bit 0 old için up counter modunda sayar
TIM3->PSC=23999 ; // TIM3_giris=84MHZ,TIM3_çikis=50HZ İÇİN PSC=24000-1 yapip arr yi 700 yapmak zorundaym
TIM3->ARR=700 ; // böylece periyot 20ms oldu..
TIM3->CCR1=350 ; // Duty Cycle orani %50 oldu
TIM3->CCER|=0x0001 ; // Polarity High yaptik..
TIM3->CR1|=0x0001 ; // TIM3 çalismaya baslasin
while(1)
{}
}
void TIM_Config(void)
{
RCC->APB1ENR|=0x00000002 ; // Timer3 CLK'u aktif edelim (84 Mhz)
RCC->AHB1ENR|=0x00000006 ; // GPIOC ve GPIOB clocklari devrede
/* GPIOC Configuration: TIM3 CH1 (PC6) and TIM3 CH2 (PC7) */
GPIOC->MODER|=0x0000A000 ; // Alternatif fonk secimi
GPIOC->OSPEEDR|=0xFFFFFFFF ;
GPIOC->OTYPER|=0x00000000 ; // Push Pull s.148
GPIOC->PUPDR|=0x00005000 ; // s. 149
/* GPIOB Configuration: TIM3 CH3 (PB0) and TIM3 CH4 (PB1) */
GPIOB->MODER|=0x0000000A ;
GPIOB->OSPEEDR|=0xFFFFFFFF ;
GPIOB->OTYPER|=0x00000000 ;
GPIOB->PUPDR|=0x00000005 ;
/* Connect TIM3 pins to AF2 */
GPIOC->AFR[1]|=0x20000000 ; // C7.biti AF2 ile bağladık
GPIOC->AFR[1]|=0x02000000 ; // C6.biti AF2 ile bağladık
GPIOB->AFR[1]|=0x00000002 ; // B0.biti AF2 ile bağladık
GPIOB->AFR[1]|=0x00000020 ; // B1.biti AF2 ile bağladık
}
eğer direk kodların orjinalini çalıştırırsam(yani TIM_PWM_Output örnek projesinden bahsediyorum) şu aşağıdaki hatayı alıyorum..
Build target 'TIM_PWM_Output'
compiling main.c...
..\main.c(24): error: #5: cannot open source
input file "stm32f4_discovery.h": No such file or directory
compiling
stm32f4xx_it.c...
..\stm32f4xx_conf.h(34): error: #5: cannot open source input
file "stm32f4xx_adc.h": No such file or directory
compiling system_stm32f4xx.c...
..\stm32f4xx_conf.h(34): error: #5: cannot open
source input file "stm32f4xx_adc.h": No such file or directory
compiling stm32f4_discovery.c...
stm32f4_discovery.c: Error: #5: cannot open source input file "..\..\..\..\Utilities\STM32F4-Discovery
\stm32f4_discovery.c": No such file or directory
Target not created
TIM10 kullanarak yaptığım pwm örneğini ve hesaplamalarini anlattığım şu yazıyı bir inceleyin isterseniz. https://www.picproje.org/index.php?topic=41911.0
Frekansların Max kullanılması sıkıntı yaratıyor olabilir. Denetleyiciyi yine HSE moduna geçirin ama PLL kullanmayın, sistemi 8 MHz ile besleyip ona göre tekrar ayar yapın. Belkide bölücüler çok büyüktür...
Fatih neyden bahsediyorsun ?
SystemInit fonksiyonunda HSE moduna alınıp PLL ayarlanıyor. Clock Source ayarlanıp sistem 168 MHz ile besleniyor. PLL yi hiç bulaştırmayın. Sistemi direkt HSE yani 8 MHz ile besleyin. Timer ön bölücülerini vs. tekrar hesaplayıp yazın. 50Hz pwm üretmek için 168 MHz hem fazla büyük hemde fazla güç harcar...
tmm belki güç harcar ama sorun olur mu ki olcağını hiç düşünmemiştim..direk hse ile de denerim olmadı dediğiniz gibi..muuzoo hocam bu örneği inceledim zaten ama 32khz değer..50 hz e düşürmek zaten sıkıntı oluyor..çünkü osiloskop da yok ancak motor dönerse çalıştığını anlayabilirim..bu durumda 50 hz e ayarlamam gerekiyor neyazık ki...
mesaj birleştirme:: 04 Eylül 2012, 22:02:50
bir de pll ile 50 hz e inemedim..o yüzden timer ın periyodunu büyüterek 50 hz e ulaşmaya çalıştım..sizce yanlış mı yaptım acaba? ???
Burdaki bütün konuları okudum şuan kitimle uygulamalar yapmaya başladım.aklıma bişey takıldı register a bazen burdaki gibi
RCC->CR |= 0x01000000;
maskeleme ile yazıyoruz; bazen de harhangi bir işleme tabi tutmadan ( &,| gibi operatörler kullanmadan )
FLASH->ACR = 0x00000605;
direk yazıyoruz(gerçi burdaki atama da maskeleme oluyormu bilmiyorum).Bu ikisi arasında ne fark var herikisi de ilgili register a verilen değerleri atamıyormu zaten.Fark var diyelim peki nerden bilcez hangisini ne zman kullancağımızı?
Alıntı yapılan: ergen - 05 Eylül 2012, 22:04:31
Burdaki bütün konuları okudum şuan kitimle uygulamalar yapmaya başladım.aklıma bişey takıldı register a bazen burdaki gibi
RCC->CR |= 0x01000000;
maskeleme ile yazıyoruz; bazen de harhangi bir işleme tabi tutmadan ( &,| gibi operatörler kullanmadan )
FLASH->ACR = 0x00000605;
direk yazıyoruz(gerçi burdaki atama da maskeleme oluyormu bilmiyorum).Bu ikisi arasında ne fark var herikisi de ilgili register a verilen değerleri atamıyormu zaten.Fark var diyelim peki nerden bilcez hangisini ne zman kullancağımızı?
İlk atamada sadece ilgili saklayıcıdaki istediğiniz biti değiştirmiş oluyorsunuz. Diyelim ki CR saklayıcısının içeriği : 0x00000011 olsun. Siz ilk kullanımdaki gibi veya operatörü ile atama yaparsanız saklayıcının içeriği : 0x01000011 olacaktır. Fakat ikinci kullanımdaki gibi atama yaparsanız önceki değerler değişecek ve son atadığınız değer olacaktır. Peki neden böyle kullanıyoruz? Eğer ilgili saklayıcının içeriğinin tamamını değil de sadece belli bir kısmını değiştirmek istiyorsak bu şekilde çeşitli operatörler kullanrak atama yaparız. Yok değeri olduğu gibi yazacaksak ikinci şekli kullanırız.
kendi adıma ilginç bir şey paylaşmak istiyorum..size de paylaştığım pwm programını karta attığımda (ya da herhangi bir program attığımda) sonra pinlerin gerilimlerini ölçtüğümde pc10, pd5, pb4, pb6, pa15, pe3, pb9, pa9 uçlarından 2.5 V gibi bir değer ölçüyorum.....pa9 pininden de 0.4 V ölçüyorum..bir çoğu serbest I/O pini olmasına rağmen(ve benim programımda bunlara bir değer atamamama rağmen) nasıl olur da bu derece yüksek gerilime sahip olabiliyorlar?
Alıntı yapılan: muuzoo - 05 Eylül 2012, 23:22:15
İlk atamada sadece ilgili saklayıcıdaki istediğiniz biti değiştirmiş oluyorsunuz. Diyelim ki CR saklayıcısının içeriği : 0x00000011 olsun. Siz ilk kullanımdaki gibi veya operatörü ile atama yaparsanız saklayıcının içeriği : 0x01000011 olacaktır. Fakat ikinci kullanımdaki gibi atama yaparsanız önceki değerler değişecek ve son atadığınız değer olacaktır. Peki neden böyle kullanıyoruz? Eğer ilgili saklayıcının içeriğinin tamamını değil de sadece belli bir kısmını değiştirmek istiyorsak bu şekilde çeşitli operatörler kullanrak atama yaparız. Yok değeri olduğu gibi yazacaksak ikinci şekli kullanırız.
Çok teşekkür ederim oldukça açıklayıcı oldu bunu ben nasıl düşünemedim o ayrı bir konu neyse anlaşılan daha çok çalısmamız lazim :-[
mesaj birleştirme:: 06 Eylül 2012, 15:26:51
#include "STM32F4xx.h"
// FCPU =168Mhz
// FAHB =FCPU
// FAPB2=FCPU/2
// FAPB1=FCPU/4
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOB->MODER = 0x00000015; // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
GPIOB->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
RCC->APB2ENR|=0x4000; // SYSCFG Enable
}
void EXTI1_IRQHandler ()
{
EXTI->PR|=0x00000002; // EXTIO INT flagimizi silelim
GPIOB->ODR^=0x00000007;
}
int main()
{
// Butona basinca pinimiz H oluyor
GPIOA->MODER &=~0x0000000C; // GPIO pin ancak inp modunda interrupt uretebilir (Rehber 143)
//GPIOA->PUPDR &= 0x00000004;
SYSCFG->EXTICR[0]&=~0x000000F0; // GPIO A1 interrupt uretecek
EXTI->RTSR=0x00000002; // Yukselen kenar tetiklemesi yapacagiz. (EXTI1)
EXTI->FTSR=0; // Dusen kenar tetiklemesi istemiyoruz. (EXTI1)
EXTI->IMR=0x00000002; // EXTI1 Int enable (Rehber 202-203)
EXTI->EMR=0; // Event istemiyoruz
NVIC->ISER[0] = 0x00000080; // NVIC EXTI1_IRQ interrupti acalim
while(1);
}
Bülent hocamızın yapmış olduğu kodlardan yararlanarak toggle işlemini kart üzerinden degilde harici olarak bi buton bagladım ve yine harici bagladıgım üç ledi yakıyorum.Fakat bazı problemler var mesela butona ardarda basınca ledler çok kararlı ve hızlı bir şekilde yanıp sönme işlemi yapmıyo bazen bassamda sönmüyo ve yanmıyo parazitle ilgili olabilir ama yükselen kenardan sonra gecikme eklemek istiyorm bunu hangi satıra eklicem onu kestiremedim.yada bunun başka bir çözümü varmı.birde ekledigim butonun girişini dahili direnç ile pull-down yapmak istiyorum GPIOA->PUPDR &= 0x00000004; bu satırı ekledim ama olmadı yine kendim direnç baglamak zorunda kaldım.yardımcı olurmusunuz çok ihtiyacım var.
Boştayken 2.5 volt görmeniz normal. Dijital mantıkta bildiğin gibi iki değer var : High ve Low. Giriş olarak belirlenen pinler ise bu iki duruma da eşit uzaklıkta yani (5 - 0) / 2 den 2.5 volt olur. Bu değere lojik Float durumu da denir. 0.4 volt gördüğünüz bacaklarda muhtemelen ya çip içinde özel bir donanıma bağlı, ya da kart üzerinde bir elemana bağlıdır...
Yukarda yazdığım mesaja cevap veren yokmu arkadaşlar bilen varsa rica ediyorum.
Gecikmenizi EXTI1_IRQHandler metoduna yazacaksınız.
void EXTI1_IRQHandler ()
{
volatile int i;
EXTI->PR|=0x00000002; // EXTIO INT flagimizi silelim
GPIOB->ODR^=0x00000007;
for(i = 0; i < 0x7FFFF; i++)
;
}
Alıntı Yapprensip olarak
ama neden ?
@gerbay hocam haklısınız interrupt rutinlerini küçük tutmakta fayda var ama bu arkadaşın birşeyleri deneyerke öğrenmesi için faydası olacağını düşündüm. Ona kalırsa while döngüsüyle gecikme yapmakda kötü. SysTick kullanmak ta mümkün. ancak bu iyileştirmelerin hepsi programı daha da karmaşıklaştır. Bırakın da arkadaş bazı şeyleri deneyerek öğrensin :)
@gerbay
Hocam Aslında cevabını Bildiğim Bir Soruyu Açmanızı İstedim. İnterrupt çok kısa tutulmalı çünki başka bir interrupt gelebilir vs. değilmi ama.
gerbay hocam bahsi geçen rtos larda nesne kilitleme ( lock ) mekanizması var mı? Yani paralel işlemle beraber paralel olay işleme?
gerbay hocam çok teşekkürler en kısa zamanda araştırma yapıp bu kodları eklicem..birde ekledigim butonun girişini dahili direnç ile pull-down yapmak istiyorum GPIOA->PUPDR &= 0x00000004; bu satırı ekledim debug yaparken bu satırda register a yazma yapmıyo neden böyle bişey olabilir.
Yazma yapmıyor değil. &= 4 sadece 3.bite AND işlemi uygular. Ayrıca buton girişi zaten donanımsal olarak PullDown'dır. Satır içi Bit-Set/Reset şöyle yapılır:
(REGISTER) |= (1 << BIT); // Set
(REGISTER) &= ~(1 << BIT); // Reset
// Örnek
GPIOA->PUPDR |= (1 << 1); // GPIOA.0 (Buton) Pull Down
Yok hocam Mutex'i kasdetmiyorum. Mesela anlattığınız gibi farklı metodlarda ortak kullanılan nesnelerin "gölge kopya mantığıyla" bir örneğinin iki farklı yerde bulundurulması ve değişme olduğunda nesnenin iki farklı örneğine yazılması. Veya aynı anda nesnelerin aynı anda hem okunup hem yazılması. Bu mekanizmayı bir işletim sistemi projesinde görmüştüm diye hatırlıyorum. Anlattığınız RTOS larda da benzeri mekanizma var mıdır?
Hmm anladım hocam. Şu an hatırlamadığım Unix türevi değişik bir sistemde görmüştüm. Demekki söylediğiniz gibi ekstradan yazılmış bir özellik. Teşekkür ederim...
#include "STM32F4xx.h"
// FCPU =168Mhz
// FAHB =FCPU
// FAPB2=FCPU/2
// FAPB1=FCPU/4
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOB->MODER = 0x00000015; // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
GPIOB->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
RCC->APB2ENR|=0x4000; // SYSCFG Enable
GPIOA->PUPDR |= 0x00000008;
}
static volatile int binarySemaphore1 = 0;
static volatile int countingSemaphore1 = 0;
interruptHandler1()
{
binarySemaphore1 = 1;
}
interruptHandler2()
{
countingSemaphore1++;
}
void EXTI1_IRQHandler ()
{
EXTI->PR|=0x00000002; // EXTI1 INT flagimizi silelim
GPIOB->ODR^=0x00000007;
}
void Delay()
{
unsigned int i;
for(i=0;i<0x800000;i++);
}
int main()
{
// Butona basinca pinimiz H oluyor
GPIOA->MODER &=~0x0000000C; // GPIO pin ancak inp modunda interrupt uretebilir (Rehber 143)
SYSCFG->EXTICR[0]&=~0x000000F0; // GPIO A1 interrupt uretecek
//Delay();
EXTI->RTSR=0x00000002; // Yukselen kenar tetiklemesi yapacagiz. (EXTI1)
EXTI->FTSR=0; // Dusen kenar tetiklemesi istemiyoruz. (EXTI1)
EXTI->IMR=0x00000002; // EXTI1 Int enable (Rehber 202-203)
EXTI->EMR=0; // Event istemiyoruz
NVIC->ISER[0] = 0x00000080; // NVIC EXTI1_IRQ interrupti acalim
while(1)
{
if (1 == binarySemaphore1)
{
binarySemaphore1 = 0;
int1_DoWork();
}
if (countingSemaphore1 > 0)
{
countingSemaphore1--;
int2_DoWork();
}
}
}
Gerbay hocam yukardaki gibi kodları ekledim ama (main.c(81): warning: #223-D: function "int2_DoWork" declared implicitly) şeklinde bir hata veriyor.fonksiyonumu bulamıyo acaba.bu kodlar interrupt ile mi çalışıyor yani bunları interrupt rutini olarak mı eklicem.yazılım kısmını biraz daha açıklama imkanınız varmı.
Gerbay hocam, bu sıkıntılar arkadaşların C yi iyi bilmemesinden kaynaklanıyor. Projelere girişmeden önce en azından bir yere kadar C öğrenseler, bu sıkıntıları yaşamayacaklar. Yani Implicit Declaration'ın ne olduğunu bilmeden program yazmak yerine kitaplardan veya internetten biraz daha C öğrenrek, temel örnekleri uygulayarak kendilerini geliştirseler... Haksız mıyım hocam? Arkadaşlar bu arada yanlış anlamayın tavsiye amacıyla söylüyorum...
fatih hocam ben çok da iyi olmasa da c bildiğimi ZANNEDİYORDUM. ancak bu söylediğiniz implict declararation kalıbıyla nedemek istediğinizi anlamadım..eğer bahsettiğiniz şey daha önce tanımlanmamış fonksiyon ile program karşılaştığında verdiği hata iletisi ise biliyorum ancak ayrı bir anlamı ya da "declaration" ifadesi var ise bilmiyorum..eğer bundan bahseden bir c kaynağı var ise hemen okumak isterim mümkünse link paylaşır mısınız?
Implicit Declaration sadece bir örnek. Türkçesiyle Üstü kapalı bildirim demek. C de ise Method ody'si yani kodları ile tanımlanmamış fonksiyon var anlamına geliyor. Kısaca önceden tanımlanmamış fonksiyon. Bu uyarı/hata(derleyiciye göre değişir) derleme sırasında çıkar. Derleyici bize böyle bir fonksiyon için metod içeriğinin tanımlanmadığını söyler. Eğer bağlama sırasında da derlenmiş dosyalarda bulunamazsa linker hata verir. Bunun gibi C özelliklerinden, bir programın nasıl derlendiği, nasıl çalıştırıldığı gibi konuları bilmeden yazılan programlarda bir sürü hata çıkması normaldir. Bunları açıklayan bir sürü döküman var(çoğunluğu İngilizce maalesef).
Bana kalırsa bunları öğrenmek iki aşamada... İlk aşama yanlış kod yazımı ve hatayla karşılaşma. İkinci aşama ise araştırma yapıp çözümü bulmai sorun hakkında ve ilişkili konular hakkında bilgi edinme. İnternette hata iletisini aramak bile çok faydalı sonuçlar gösterecktir. İyi çalışmalar...
anladım hocam farklı bir anlamı yok yani bildiğimiz gibi bildirimi yapılmamış ya da istenmeyen biçimde yapılmış bildirimler..açıklama için teşekkür ederim hocam..size de iyi çalışmalar..
Alıntı yapılan: gerbay - 11 Eylül 2012, 11:11:58
benim yazdıklarım sanırım tam anlaşılmadı ya da ben tam anlatamadım..
yazdıklarımı direk copy/paste ederek denemeyeceksiniz, onlar biraz pseudo kod olarak, mantığı açıklamak için yazılmış ifadeler..
kendi interrupt handler ınızı kullanacaksınız ve int1_DoWork, int2_DoWork gibi gördüğünüz kısımlarda da ilgili interrupt handler üzerinden yapmak istediğiniz işi yapacaksınız..
interrupt handler lar mümkün olduğunca kısa tutulmak zorunda olduğundan bu şekilde bir yaklaşım ile ilgili interrupt ın işini interrupt context inde değil de CPU nun normal çalışma context inde gerçekleştirmiş oluyorsunuz.
Kendi kodunuza o mantığı uygulayacaksınız..
teşekkürler hocam şimdi daha iyi anladım biraz daha araştırma yapıcam ;)
mesaj birleştirme:: 11 Eylül 2012, 23:49:10
Alıntı yapılan: fatih6761 - 11 Eylül 2012, 14:21:16
Gerbay hocam, bu sıkıntılar arkadaşların C yi iyi bilmemesinden kaynaklanıyor. Projelere girişmeden önce en azından bir yere kadar C öğrenseler, bu sıkıntıları yaşamayacaklar. Yani Implicit Declaration'ın ne olduğunu bilmeden program yazmak yerine kitaplardan veya internetten biraz daha C öğrenrek, temel örnekleri uygulayarak kendilerini geliştirseler... Haksız mıyım hocam? Arkadaşlar bu arada yanlış anlamayın tavsiye amacıyla söylüyorum...
fatih hocam sizinle hemfikir olduğumu söylemek istiyorum ben de şuan sizin bahsetmekte olduğunuz aşamadayım çeşitli uygulamalar yapıyorum c yi ögrenmek içn. bu forumdaki bülent hocamızın yazdığı bütün yazıları okudum ve uyguladım vakit buldukça yeni kaynaklar da arıyorm.ben sorularımın tabiki de tam karşılığını istemiyorum öyle bir lüksüm yok fakat en azından yol göstermesi açısından çok faydalı olduğunu düşüyorum.neyi araştırcağımı ögrenmem yeterli oluyor.her yeni bişey sorduğumda birönceki sorumun ne kadar saçma bir soru olduğunu ben de farkediyorum.bu da öğreniyor olduğumu gösteriyor.ben böyle düşünüyorum yardımlarınızı esirgemezseniz sevinirim.
Interrupt kullanarak yazılımsal PWM sinyalleri üretmek
Aşağıda 8 kanallı yazılımsal olarak PWM sinyal üreten örnek yazılım görülmektedir. RC Servo çalışması yapmak isteyenler için PWM peryodu 20 mili saniye seçilmiş olup her bir PWM 0..1000 aralığında değer alabilir. Programda değişiklik yapıp, PWM kanallarının sayısını dilediğiniz kadar artırabilirsiniz.
#include "STM32F4xx.h"
unsigned short PWM[8]; // PWM registerler
unsigned short SRG[8]; // Shadow Registerler
unsigned short CNTR; // PWM Counter
/*****************************************************************************************************
CPU PLL ile 168Mhz de kosturulur
AHB frekansy 168 Mhz
APB1 frekansy 42 Mhz
APB2 frekansy 84 Mhz
*****************************************************************************************************/
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOD->MODER = 0x55550000; // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
RCC->APB1ENR|=0x00000020; // Timer7 CLK'u aktif edelim (84 Mhz)
TIM7->CR1=0x0080; // Otomatik Reload
TIM7->PSC =839; // Prescaler degerimiz 839, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 84E6 / (840) = 100 KHz
TIM7->ARR =1; // Counter, Decimal 1 olunca basa donsun. Her 20 mikrosaniye de bir timer int olusacak.
TIM7->DIER=0x0001; // Update Int enable
NVIC->ISER[1] = 0X00800000; // NVIC de Timer 7 interrupta izin verelim
TIM7->CR1|=0x0001; // Counter Enable
}
void TIM7_IRQHandler()
{
unsigned short d,i,j;
TIM7->SR=0; // Timer Int Flagini silelim
d=GPIOD->ODR & 0x00FF;
CNTR++;
if(CNTR>=1000)
{
CNTR=0;
for(i=0;i<8;i++)
{
if(PWM[i]>1000) PWM[i]=1000;
SRG[i]=PWM[i];
}
}
j=0x8000;
for(i=0;i<8;i++)
{
if (CNTR>=SRG[i]) d|=j;
j=j>>1;
}
GPIOD->ODR=d;
}
int main()
{
PWM[0]=100;
PWM[1]=200;
PWM[2]=300;
PWM[3]=400;
PWM[4]=500;
PWM[5]=600;
PWM[6]=700;
PWM[7]=800;
while(1);
}
tahmin ettiğiniz gibi bu örnek bunalmış hocamızın yazdığı örnek..başlangıçta rc servo çalışmaları için 20 ms lik periyot demiş ancak daha sonra programda 20us lik periyotlar oluşturmuş..100khz yani..burada minik bir yanlışlık var sanırım..şimdi asıl sormak istediğim şu..burada yazılımsal pwm üretme çabasında değilim..donanımda zaten mevcut ancak sonucta orada da prescaler arr gibi değerler bildirerek bu değerlere ulaşmam gerekiyor..dolayısıyla 84 Mhz lik bir timer ile çıkışta 100 hz lik yani 20 ms lik çıkış veren bir dalga üretmem gerek.. bu durumda prescaler değerim 65 binin üzerinde bir değer oluyor ki bu imkansız . sizce nasıl bir yöntem izlemeliyim?
@coldoubtless zamanlayıcıları hesaplarını tekrar yapsak iyi olur.
İstediğimiz PWM frekansı 50 Hz.
Timer 84 MHz ile besleniyor. PSC ve ARR registerları 16 bit. Yani maksimum 65535 olabilir.
Formül.1 :: Prescaler = (TIM3CLK / TIM3 counter clock) - 1
Burada TIM3CLK 84 MHz oluyor. TIM3 Counter clock ise istediğimiz timer frekansı. Eğer ön bölücü değerini 42.000 olarak ayarlarsak, Timer frekansı 2000 Hz olur.
TIMx->PSC = 41999; // 42000 - 1
Timer 2000 Hz ile çalışıyor. Biz ise 50 Hz istiyoruz.
Formül.2 ::ARR = (TIM3 counter clock / TIM3 output clock) - 1
Burada Counter Clock'u 2000 olarak belirledik. Output clock ise 50 olacak. Formülden
TIMx->ARR = 39; // 2000/50 = 40, 40 - 1 = 39
Ve bu şekilde 50 Hz de, yaklaşık 5,32 bit çözünürlükte ( log2(40) ) bir PWM sinyalimiz oluyor. CCR değerine ise 40 ta X olacak şekilde Duty değerini yüklüyoruz.
Donanımsal PWM nin nasıl çalıştığını biliyorsanız bu hesapları kolaylıkla yapabilmeniz gerekir. Bu PWM sistemini örnek alan 74hc serisinden bir pwm donanımı yapmıştım. Eğer isterseniz devreyi gösterebilirim daha net anlayabilmeniz için.Bu arada 20 ms lik çıkış için 100 hz değil 50 hz kullanmanız gerekir : T = 1/f
sağolun fatih hocam hayır sağolun bu dediğinizi denedim ancak yine esc den tepki alamayınca yanlış olduğunu düşünmüştüm..bu 100 hz olayını da son incelediğim bir kaç örnekte gördüm. özellikle bunalmış hocamızın gösterdiği..burada arr değeri reload yapıldığında tekrar bir okadr sürenin geçtiğini gösteriyor..yanii 10ms beklerken 20ms oluyor..yani direk istediğimiz değer için 1/f yapamıyoruz eğer verilen örnekler yanlış değil ise tabiki..2 ileti önce paylaştığım örnekte de görüldüğü gibi 100khz yani 10mikro saniye oluyor ancak 20 mikro saniye olarak periyot belirleniyor..bu arr sadece 1 olduğunda geçerli olan bir durum mu?
Arr yi bir yapmak zaten yanlış bir durum. İsterseniz ben size sistemi anlatayım.
Sistemden Timer'a 84 MHz lik bir saat sinyali geliyor. Bizim PSC ön bölücümüzün count register'ı her saat sinyali geldiğinde bir artıyor. Ta ki Count = PSC olana kadar. Count = PSC olduğunda Timer Count register'ı bir artıyor. Başta çıkış 0. Timer sayıyor, devam ediyor ve bir anda Count = CCR oluyor. Bu anda çıkış tersleniyor. Yani çıkış 1 oluyor. Saymaya devam ediliyor ve Count = ARR olduğunda çıkış tekrar tersleniyor.
Yani (CCR / ARR) * 100 = % Duty oluyor.
Devre şemasında:
(http://img163.imageshack.us/img163/2410/pwm2.png)
Çalışma sırasında ARR = 8 ve CCR = 2
(http://img189.imageshack.us/img189/4803/pwmu.png)
Resimde de toplam periyot 800 mikrosaniye, Duty süresi ise 200 mikrosaniye. Sistem bu şekilde çalışıyor. Çıkış frekansı PSC ve ARR ile belirleniyor. Çözünürlük ise ARR ile belirleniyor. Önceki mesajımda verdiğim örnekte 40 çözünürlükte ( yaklaşık 5.32 bit ) 50 Hz lik frekansı üretir. Arr yi bir yaparsanız CCR değerine göre ya %50 yada %100 duty üretebilirsiniz. Benim verdiğim hesap ile istediğiniz gibi sürebilirsiniz.
#include "STM32F4xx.h"
// FCPU =168Mhz
// FAHB =FCPU
// FAPB2=FCPU/2
// FAPB1=FCPU/4
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOB->MODER = 0x00000015; // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
GPIOB->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
RCC->APB2ENR|=0x4000; // SYSCFG Enable
GPIOA->PUPDR |= 0x00000008;
}
volatile int countingSemaphore1 = 0;
void EXTI1_IRQHandler ()
{
countingSemaphore1++;
}
void ledyak(void)
{
EXTI->PR|=0x00000002; // EXTI1 INT flagimizi silelim
GPIOB->ODR^=0x00000007; // Toggle islemi
}
int main()
{
// Butona basinca pinimiz H oluyor
GPIOA->MODER &=~0x0000000C; // GPIO pin ancak inp modunda interrupt uretebilir (Rehber 143)
SYSCFG->EXTICR[0]&=~0x000000F0; // GPIO A1 interrupt uretecek
EXTI->RTSR=0x00000002; // Yukselen kenar tetiklemesi yapacagiz. (EXTI1)
EXTI->FTSR=0; // Dusen kenar tetiklemesi istemiyoruz. (EXTI1)
EXTI->IMR=0x00000002; // EXTI1 Int enable (Rehber 202-203)
EXTI->EMR=0; // Event istemiyoruz
NVIC->ISER[0] = 0x00000080; // NVIC EXTI1_IRQ interrupti acalim
while(1)
{
if(countingSemaphore1 > 0)
{
countingSemaphore1--;
ledyak();
}
}
}
Birz araştırma yaptıktan sonra bu kodları yazdım yalnız şöyle bi problem var butona bastığımda interrupt a girip countingSemaphore1 değişkenini 1 artırma yapmıyor o yüzden led yanmıyor.debug yaparken değişkeni artırıyorum bu sefer normal çalışıyor.neden interrupt a girmez anlamadım yardımcı olurmusunuz.
tamam o halde arr yi 1 yapmadığımız sürece iki katı çıkma gibi bir olay da yok her şey bildiğimiz gibi yürüyor diye kabul ediyorum fatih hocam çok teşekkür ederim uğraşıp yazmışsınız o kadar..açıklamalar yeterli oldu ancak eklediğiniz resimler çıkmıyor söleyeyim dedim :)
mesaj birleştirme:: 12 Eylül 2012, 19:04:41
@ergen interruptlara izin verme işlemini SystemInit fonksiyonunun sonunda yaparak denermisin bir de..saymasını istiyorsun ama interrupta programın sonunda izin veriyorsun..çok anlamam ama böyle bakınca sıkıntılı olmuş gibi geldi..hocalarımız daha iyi bilir tabi..
mesaj birleştirme:: 12 Eylül 2012, 20:01:40
fatih hocam dediğiniz ayarlarla da denedim yine motoru döndüremedim..aslında sıkıntı bu esc lerde kaynaklanıyor..yani programda sıkıntı yok belli..bana bu esc lerle çalışmış bir yol gösterici gerek :) aşağıda bu konuda türkçe bulunan tek bilgiyi paylaşıyorum...
ESC'lerin hepsi aynı aralıkta çalışmasa da genelde 0.9ms – 1.8ms high (yani lojik 1) ve ardından göndereceğiniz 20ms'lik low (yani lojik 0) sinyali ve bunun devamlı olarak ESC'ye iletilmesi ile çalışırlar. Güvenlik açısından motorun başlangıçta hızlı dönmeye başlamasını engellemek için kumandanız dahi olsaydı throttle kolunu en aşağı yani minimum düzeye getirerek çalıştırmanız gerekecekti. Minimum throttle konumuna getirilmeyen bir kumanda ile motorların başlaması için gereken sesi duymak mümkün olmayacaktır. (şu beep-biip-beep-biip sesi yani ) İşte bunu mikroişlemciyle de böyle yapmalıyız ki motorlar güvenli bir şekilde çalışmaya hazır olsunlar. Bunun için başlangıçta ESC'nin BEC'inin sinyal ucuna 0.9ms kadar lojik 1 ve 20ms lojik 0 bilgisi göndermeliyiz. Bu aşamada motordan o başlamaya hazır oldugunu bildiren sesi duymalıyız. Ardından motorlar nihayet çalışmaya hazır olacaklar. Tek yapmanız gereken 0.9ms olan lojik 1 bilgisini 0.9ms değerinden daha yüksek bir değere çıkarmak.
Sizce sorun bu mudur? sadece motordan bipp bipp bipp diye sürekli ses geliyor baktım anlamına bu ses "throttle signal is abnormal" diyor..uğraşmış birisi varsa bu konuda lütfen yardım bekliyorum..
Başka bir forumda şöyle denmiş:
Sadece ESC'nin sinyal girişine %10'luk 50hz'de PWM darbesi girmen gerekiyor. Darbe genişliğin 1 ile 2.2 milisaniye arasında olmalı.
Cevap net: %10 luk 50 hz pwm. CCR değerine 4 yükleyip aynı değerlerle tekrar deneyin. Olmazsa yazılımsal PWM kullanarak çalışıyor mu onu görelim..
Not : Resimleri düzelttim...
ne yazık ki olmadı hocam esc de korkunç ısındı çok ilginç gerçekten..motor biipp bipp bipp sesine sürekli devam ediyor her ses geldiğinde de motor sanki döncek gibi bir titriyor ama dönmüyor :s
Elimdeki ESC ve uzaktan kumandadan aldığım ölçümlere göre,alıcıdan ESC ye giden data kablosunda 50 Hz'lik bir PWM var.Başlangıçta %5 genişlikte ve motor hızlandıkça değer artıyor. En fazla %10 oluyor. Bundan yüksek değerler ESC yi yakabilir bence. PWM'in genliği de 5 V.
hocam 5 v genlik ve isterse %100 doluluk oranı olsun en fazla 5v olabilir esc gerilimi..5v ile de yanmaz heralde diye düşünüyorum..en sonunda heralde artık receiver ile kontrol edicem bu motorları..
NOT= %5 ile de denendi..yine tepki yok..
Hocam biraz önce denedim Discovery kartı ile kontrol ettim ESC'yi. 3 volt ile de sinyal iletiliyormuş. 50 Hz %5-%10 PWM ile hız kontrolü yapılabiliyor.
ciddi olamazsın hocam hemen bana bir vidyo resim bir şeyler gönder nasıl heyecanlandım :D kodlar bizim kodlar değil mi yoksa kendin mi yazdın? ben benim vidyoyu ekliyorum izlerseniz bir zahmet motor aynen bole oldgu yerde debeleniyor..
SNC00208 (http://www.youtube.com/watch?v=_UwM005oE0s#)
#include "STM32F4xx.h"
// FCPU =168Mhz
// FAHB =FCPU
// FAPB2=FCPU/2
// FAPB1=FCPU/4
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOB->MODER = 0x00000015; // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
GPIOB->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
RCC->APB2ENR|=0x4000; // SYSCFG Enable
GPIOA->PUPDR |= 0x00000008;
}
volatile int countingSemaphore1 = 0;
void EXTI1_IRQHandler ()
{
countingSemaphore1++;
}
void ledyak(void)
{
EXTI->PR|=0x00000002; // EXTI1 INT flagimizi silelim
GPIOB->ODR^=0x00000007; // Toggle islemi
}
int main()
{
// Butona basinca pinimiz H oluyor
GPIOA->MODER &=~0x0000000C; // GPIO pin ancak inp modunda interrupt uretebilir (Rehber 143)
SYSCFG->EXTICR[0]&=~0x000000F0; // GPIO A1 interrupt uretecek
EXTI->RTSR=0x00000002; // Yukselen kenar tetiklemesi yapacagiz. (EXTI1)
EXTI->FTSR=0; // Dusen kenar tetiklemesi istemiyoruz. (EXTI1)
EXTI->IMR=0x00000002; // EXTI1 Int enable (Rehber 202-203)
EXTI->EMR=0; // Event istemiyoruz
NVIC->ISER[0] = 0x00000080; // NVIC EXTI1_IRQ interrupti acalim
while(1)
{
if(countingSemaphore1 > 0)
{
countingSemaphore1--;
ledyak();
}
}
}
Arkadaşlar bana yardımcı olcak kimse yokmu.hızlı tepki vercek olan led toggle uygulamam debug yapınca çalışıyor ama normalde çalışmıyor anlamadım bi türlü kafayı yemek üzereyim :(
@ergen sen halâ semafor olayında mı kaldın? Şu şekile bir eklemeyle kullanabilirsin...
static volatile int durum = 0;
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOB->MODER = 0x00000015; // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
GPIOB->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
RCC->APB2ENR|=0x4000; // SYSCFG Enable
GPIOA->PUPDR |= 0x00000008;
GPIOA->MODER &= ~(0x0C);
SYSCFG->EXTICR[0] &= ~(0xF0);
EXTI->RTSR = 0x02;
EXTI->FTSR = 0;
EXTI->IMR = 0x02;
EXTI->EMR = 0;
NVIX->ISER[0] = 0x80;
while(1)
{
while(durum == 0)
{
// Interrupt durum değerini set edinceye kadar bekle...
}
GPIOB->ODR ^= 0x00000007; // Toggle islemi
durum = 0;
}
}
void EXTI1_IRQHandler()
{
EXTI->PR|=0x00000002; // EXTI1 INT flagimizi silelim
if(durum == 0)
durum = 1;
}
void main()
{
volatile int i;
while(1)
{
while(durum == 0)
{
// Interrupt durum değerini değiştirene kadar bekle...
}
GPIOV->ODR ^= 0x00000007;
for(i = 0; i < 0x07FFFF; i++)
;
durum = 0; // Durumu sıfırla...
}
}
Alıntı yapılan: cooldoubtless - 13 Eylül 2012, 00:30:32
ciddi olamazsın hocam hemen bana bir vidyo resim bir şeyler gönder nasıl heyecanlandım :D kodlar bizim kodlar değil mi yoksa kendin mi yazdın? ben benim vidyoyu ekliyorum izlerseniz bir zahmet motor aynen bole oldgu yerde debeleniyor..
SNC00208 (http://www.youtube.com/watch?v=_UwM005oE0s#)
Kodları ben yazdım hocam PWM i timer 1 ile ürettim. Dediğim gibi 50 Hz %5 ile %10 arasında değiştiriyorum. Sende frekans sorunu var galiba öyle görünüyor.Timer1 ayar için şunları kullandım.ADC den okuduğum değer ile de duty cycle'i ayarladım. İnternetim yavaş olduğu için vidyo yükleyemiyorum şu an. Daha hızlı bir bağlantı olduğunda yüklüycem.
void timer1ayar()
{
TIM1->PSC = 3281-1; // Prescaler degerimiz Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1)
TIM1->ARR = 1024; // sayıcı=ARR olduğunda sayıcı başa döner (periyot) 15kHz
TIM1->CCR1 = 972; // duty cycle oranı
TIM1->CCR2 = 300;
TIM1->CCR3 = 300;
TIM1->CCR4 = 0;
// TIM1->DIER = 0x0021; // Update Int enable + COM int. etkin
NVIC->ISER[0]|= 0X04000000; // NVIC de Timer 1 interrupta izin verelim
TIM1->CCMR1 |= 0x00006868; //CC1 ve CC2 PWM 1 mod seçildi
TIM1->CCMR2 |= 0x00006868; //CC3 ve CC4 PWM 1 mod seçildi
TIM1->CCER |= 0x0113; // CC1,CC2,CC3 ve CC4 etkin CCP1 türü çıkış(normal PWM)
TIM1->BDTR = 0x00000C800; // MOE etkin AOE etkin OSSR
// TIM1->CR2 = 0x00000FF01; // yükleyiciler etkin OCx1
TIM1->CR1 |= 0x0081; // Counter Enable Otomatik yükleme
}
http://t.co/ZU2SKv0Q (http://t.co/ZU2SKv0Q) şöyle bir fotoğraf yükledim umarım yardımcı olur.
#include "STM32F4xx.h"
// FCPU =168Mhz
// FAHB =FCPU
// FAPB2=FCPU/2
// FAPB1=FCPU/4
volatile unsigned int i;
volatile int durum = 0;
void SystemInit()
{
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOB->MODER = 0x00000015; // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
GPIOB->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
RCC->APB2ENR|=0x4000; // SYSCFG Enable
GPIOA->PUPDR |= 0x00000008;
// Butona basinca pinimiz H oluyor
GPIOA->MODER &=~0x0000000C; // GPIO pin ancak inp modunda interrupt uretebilir (Rehber 143)
SYSCFG->EXTICR[0]&=~0x000000F0; // GPIO A1 interrupt uretecek
EXTI->RTSR=0x00000002; // Yukselen kenar tetiklemesi yapacagiz. (EXTI1)
EXTI->FTSR=0; // Dusen kenar tetiklemesi istemiyoruz. (EXTI1)
EXTI->IMR=0x00000002; // EXTI1 Int enable (Rehber 202-203)
EXTI->EMR=0; // Event istemiyoruz
NVIC->ISER[0] = 0x00000080; // NVIC EXTI1_IRQ interrupti acalim
}
void EXTI1_IRQHandler ()
{
if(durum==0);
durum=1;
EXTI->PR|=0x00000002; // EXTI1 INT flagimizi silelim
}
int main()
{
while(1)
{
while(durum==0)
{
}
GPIOB->ODR^=0x00000007; // Toggle islemi
for(i = 0; i < 0x07FFFF; i++);
durum=0;
}
}
sonunda oldu :D fatih hocam system init içindeki while(1) döngüsü fazlaydı heralde onu kaldırdım birde birkaç syntax hatası vardı düzelttim ve sonuç süper ;D bir de hatamı zannedersem anladım.interrupt fonksiyonunun sonunda EXTI1 INT flag ını silmem gerekiyodu.bu olmadığı için devamlı interrupt a giriyodu diye düşünüyorum.şimdi sıra bunu 16 butonlu bir klavyeye uyarlıcam ve plc ile rs485 üzerinden haberleştircem.teşekkürler fatih hocam.
Rica ederim. Kodları acele yazınca oluyor öyle bir iki hata... :)
Alıntı yapılan: marecrisium - 13 Eylül 2012, 14:39:35
Kodları ben yazdım hocam PWM i timer 1 ile ürettim. Dediğim gibi 50 Hz %5 ile %10 arasında değiştiriyorum. Sende frekans sorunu var galiba öyle görünüyor.Timer1 ayar için şunları kullandım.ADC den okuduğum değer ile de duty cycle'i ayarladım. İnternetim yavaş olduğu için vidyo yükleyemiyorum şu an. Daha hızlı bir bağlantı olduğunda yüklüycem.
void timer1ayar()
{
TIM1->PSC = 3281-1; // Prescaler degerimiz Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1)
TIM1->ARR = 1024; // sayıcı=ARR olduğunda sayıcı başa döner (periyot) 15kHz
TIM1->CCR1 = 972; // duty cycle oranı
TIM1->CCR2 = 300;
TIM1->CCR3 = 300;
TIM1->CCR4 = 0;
// TIM1->DIER = 0x0021; // Update Int enable + COM int. etkin
NVIC->ISER[0]|= 0X04000000; // NVIC de Timer 1 interrupta izin verelim
TIM1->CCMR1 |= 0x00006868; //CC1 ve CC2 PWM 1 mod seçildi
TIM1->CCMR2 |= 0x00006868; //CC3 ve CC4 PWM 1 mod seçildi
TIM1->CCER |= 0x0113; // CC1,CC2,CC3 ve CC4 etkin CCP1 türü çıkış(normal PWM)
TIM1->BDTR = 0x00000C800; // MOE etkin AOE etkin OSSR
// TIM1->CR2 = 0x00000FF01; // yükleyiciler etkin OCx1
TIM1->CR1 |= 0x0081; // Counter Enable Otomatik yükleme
}
http://t.co/ZU2SKv0Q (http://t.co/ZU2SKv0Q) şöyle bir fotoğraf yükledim umarım yardımcı olur.
hocam naptın sen ADC yi niye karıştırdın şimdi :) SystemInit aynı heralde Main de de bu fonksiyonu çağırdın değil mi? ben de denedim şimdi çalışmadı yahu işe bak..timer 1 channel4 den sıfır almam gerekli ama yine gerilim okunuyor..
Alıntı yapılan: cooldoubtless - 13 Eylül 2012, 20:09:03
hocam naptın sen ADC yi niye karıştırdın şimdi :) SystemInit aynı heralde Main de de bu fonksiyonu çağırdın değil mi? ben de denedim şimdi çalışmadı yahu işe bak..timer 1 channel4 den sıfır almam gerekli ama yine gerilim okunuyor..
Bu fonksiyonları main içinde çağırıp timerı kuracaksın evet. Adc ile doluluk oranını ayarlamak daha rahat olur bu yüzden kullandım. Bir de PWM çıkışları için ilgili pinleri alternative function olarak seç ve timer1 in saat kaynağını mutlaka aç yoksa çalışmaz sayıcı.
#include "STM32F4xx.h"
#define GPIO_A(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_B(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_C(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_D(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_E(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
// FCPU =168Mhz
// FAHB =FCPU
// FAPB2=FCPU/2
// FAPB1=FCPU/4
volatile unsigned int i;
volatile int durum = 0;
void SystemInit()
{
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000000F; // GPIO A,B,C,D clock'u aktif edelim
GPIOB->MODER = 0x00000015; // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
GPIOB->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
RCC->APB2ENR|=0x4000; // SYSCFG Enable
GPIOA->PUPDR |= 0x000000A8; //
// Butona basinca pinimiz H oluyor
GPIOA->MODER &=~0x000000FC; // GPIO pin ancak inp modunda interrupt uretebilir (Rehber 143)
SYSCFG->EXTICR[0]&=~0x0000FFF0; // GPIO A1 ve A2 interrupt uretecek
EXTI->RTSR=0x0000000E; // Yukselen kenar tetiklemesi yapacagiz. (EXTI1-EXTI2)
EXTI->FTSR=0; // Dusen kenar tetiklemesi istemiyoruz. (EXTI1-EXTI2)
EXTI->IMR=0x0000000E; // EXTI1 Int enable (Rehber 202-203)
EXTI->EMR=0; // Event istemiyoruz
NVIC->ISER[0] = 0x00000380; // NVIC EXTI1_IRQ interrupti acalim
}
void EXTI1_IRQHandler ()
{
if((durum==0)&& (GPIO_B(0)==0))
{
durum=1;
}
EXTI->PR|=0x00000002; // EXTI1 INT flagimizi silelim
}
void EXTI2_IRQHandler ()
{
if((durum==0)&& (GPIO_B(1)==0))
{
durum=2;
}
EXTI->PR|=0x00000004; // EXTI2 INT flagimizi silelim
}
void EXTI3_IRQHandler ()
{
if(durum==0)
{
durum=3;
}
EXTI->PR|=0x00000008; // EXTI2 INT flagimizi silelim
}
int main()
{
while(1)
{
switch(durum)
{
case 1:
{
GPIO_B(1)=0;
GPIO_B(0)^=1; // Toggle islemi
for(i = 0; i < 0x07FFFF; i++);
durum=0;
break;
}
case 2:
{
GPIO_B(0)=0;
GPIO_B(1)^=1; // Toggle islemi
for(i = 0; i < 0x07FFFF; i++);
durum=0;
break;
}
case 3:
{
GPIO_B(2)^=1; // Toggle islemi
for(i = 0; i < 0x07FFFF; i++);
durum=0;
break;
}
}
}
}
arkadaşlar bu kodlarla üç ledi istedigim gibi kontrol ediyorum fakat modbus ile nasıl haberleştircem bitürlü yapamadım.bülent hocanın dma daki dataları gönderen interrupt ile de dma ya data alan bi örnegi var ama bunun içine modbus ı nasıl dahil etcem.modbus nasıl çalışır bilmiyorum.dökümanlarına baktım çok bişey anlamadım yardımcı olurmusunuz lütfen.
Arkadaşlar yazılan kodları inceleyerek interruptları anlamaya çalışıyorum
NVIC->ISER[1] = 0X00800000; // dökümanlarını karıştırdım ama bu kodu bi türlü anlayamadım :'(
[1] indisi ve 0x00800000 adresi ne anlama geliyo ?
Yardımlarınızı bekliyorum arkadaşlar ve şimdiden teşekkür ederim... :)
NVIC ile ilgili cortex-m3 çekirdeği için bir bilgi vardı.
Rehber 195. sayfada interruplar için bir tablo var. bu tablonun ilk sutunu NVIC->ISERx 'in alacağı değerle alakalıdır.
Öncelikle şunu bilelim NVIC->ISER[0] 0 ile 31 arası interruptlar için ,
NVIC->ISER[1] 32 ile 63 arası interruptlar için kullanılıyor....
Senin sorduğun NVIC->ISER[1] = 0X00800000; koduna bakalım.
ISER[1] kullanıldığı için demekki ikinci 32 interrupt listesinde , 0X00800000 değeri ise registerin 23. biti set edildiği anlamına geliyor.
32+23 =55 , tablodan 55. kesme TIM7 ile alakalı bir kesme olduğunu göreceksin.
Şimdi misal tablodan DMA2_Stream0 ile ilgili bir intterrup oluşturman gerek tabloda 56. sırada ,
56-32 = 24 (24. bit set edilecek anlamına geliyor) 0X01000000 , NVIC->ISER[1] = 0X01000000;
bir aralar bu nvic nedir e cevap için hazırladığım dosya
http://www.4shared.com/file/aGveS2Fm/nvic.html (http://www.4shared.com/file/aGveS2Fm/nvic.html)
Çok Teşekkür Ederim yardımlarınız için çok iyi anladım :)
Peki programda kodlarımızı yazarken bildiğim kadarıyla belli bi mantık sırasına veya düzene göre yazıyoruz . Bazı kodların yerini değiştirdiğimiz taktirde programımız çalışmıyo veya eksik çalışıyo :'( Kodlarımızı hangi mantığa veya düzene göre Nasıl yazmalıyız ? Bu konuda bilgisi olan arkadaşların yardımlarını bekliyorum :)
Ben böyle soruları sormaya başladığım zamanlarda 8 bitlik basic piclerle oynamaya çalışıyordum. Şimdi devir değişti sanırım ilk defa programlamaya 32bitlik hi performance mcu larla mı başladınız merak ediyorum doğrusu :o
Sanırım sorumu yanlış aktardım.
Şöyle sorayım Mesela SystemInt içindeki kodların yerlerini , sırasını değiştirdiğimizde kodlarımız neden çalışmıyo ? Bunu neye göre tayin edeceğiz ?
Alıntı yapılan: Enginar - 02 Ekim 2012, 02:10:07
Peki programda kodlarımızı yazarken bildiğim kadarıyla belli bi mantık sırasına veya düzene göre yazıyoruz . Bazı kodların yerini değiştirdiğimiz taktirde programımız çalışmıyo veya eksik çalışıyo :'( Kodlarımızı hangi mantığa veya düzene göre Nasıl yazmalıyız ? Bu konuda bilgisi olan arkadaşların yardımlarını bekliyorum :)
Enginar bunu başka bir başlık açarak orada konuşsak daha iyi olacak. cortex m leride şişirmemiş oluruz.
Alıntı yapılan: Enginar - 02 Ekim 2012, 12:05:27
Sanırım sorumu yanlış aktardım.
Şöyle sorayım Mesela SystemInt içindeki kodların yerlerini , sırasını değiştirdiğimizde kodlarımız neden çalışmıyo? Bunu neye göre tayin edeceğiz ?
SystemInt fonksiyonu MCU içindeki işlemcimizin ilk çalıştırma paremetrtelerini yüklemek için. Normal şartlarda biz kendi main.c içine SystemInt ile ilgili herhangi bir tanımlama yapmadığımızada bu tanımlamalar MCU ya özel proje anında eklenen startupxxxxx.s dosyasından gelir.
ARM CORTEX-M3 MCU lar ilk çalışmaya başladığında dahili içi RC osilatör ile çalışmaya başlar. Daha sonra ya startupxxxxx.s tanımlamalardan yada bizim main.c dosyamınız ilk kısmına yazdığımız kodlar vasıtası ile ve main fonksiyonu içinde bunu aktif ettiğimizde RC/Xtal/RTC ile çalışır ve iç PLL beslenip hangi frekansta koşacağı ayarlanır.
startupxxxxx.s dosyası genellikle mcu fizksel olark üreten firma tarafından hazırlanır ve OSC, NVIC vb. tanımlamalar bu dosyadadır. KEIL bunları uVison içine ekler.
Forumuzda ki örneklerde bulunan SystemInt kodlarına biraz daha yakından bakalım.
Bizim örneklerimizde sadece MCU çalışma frekansı ile ilgili tanımlamalar var. bunları belirli bir sırada işletilmesi gerekmektedir.
ilk adım PLL besleyecek saat darbesi üretcini seçmek RC/XTAL/RTC
RC = Chip üreticisi tarafından MCU içine kuonulan Direnç ve Kondasatörden oluşan saat darbesi üreteci
XTAL = XTAL pinlerine bağlanan harici XTAL tabanlı saat darbesi üreteci
RTC = MCU içindeki Gerçek zaman saati devresi besleyen RTCXTAL pinlerine bağlanan harici XTAL tabanlı saat darbesi üreteci
ikinci adım seçilen kaynağın PLL e bağlanması
üçüncü adım PLL çarpanının belirlenmesi
dördüncü adım PLL çıkışının Cortex-M çekirdeğine yönlendirilmesi.
Aşağıda NXP firmasının ürettiği LPC1768 işlemcisi için kullandığım OSC ayar rutinlerini içiren koda parçası bulunmakta. her satıra tek tek açıklama yazmaya çalıştım.
void SyatemInt(void)
{
LPC_SC->SCS=0x20; //System Control and Status R/W 0 0x400F C1A0 5. bit 1 yapılıp xtal osc (main) aktif ediliyor
//OSCRANGE 4.bit 0 ise 1Mhz ile 2Mhz arası 1 ise 15Mhz ile 25Mhz arası
//OSCEN 5.bit 0 ise devredışı 1 ise xtal uçlarına bağlı kristali kullanır
//OSCSTAT 6.bit 0 ise osilatör hazır değil 1 ise osilatör hazır (sadece okunur)
LPC_SC->CLKSRCSEL=0x01; //select main oscilator CLKSRCSEL 2 bit uzunluğunda
//00 iç RC kaynağı osilatör olarak seçilmiş
//01 ana osilatörü PLL0 için kaynak seç
//10 iç RTC (gerçek zaman saati) osilatör olarak seç
//11 bu durum kullanımaz rezerve edilmiş bir değerdir.
LPC_SC->CCLKCFG=0x03; //pllclk/4
LPC_SC->PLL0CON=0x01; //pll activeted
LPC_SC->PLL0CFG=0x20031; //msel=49,nsel=2;
LPC_SC->PLL0FEED=0xAA; //pll i beslemek için yazılmalı datasheet te belirtiyor
LPC_SC->PLL0FEED=0x55; //önce 0xAA sonra 0x55 yüklenir
while(!(LPC_SC->PLL0STAT&(1<<26)));
LPC_SC->PLL0CON=0x07;
LPC_SC->PLL0FEED=0xAA; //pll i beslemek için yazılmalı datasheet te belirtiyor
LPC_SC->PLL0FEED=0x55; //önce 0xAA sonra 0x55 yüklenir
LPC_SC->PCLKSEL0=0;
}
zaman gecikmesi rutinlerini nasıl yapıyorsunuz ?
for ile kurduğumuz bir rutin, her bir artım için 3asm komutu işletiyor.
(Yanlış hatırlıyor olabilirim ARM da her asm komutunun işlem saykılı aynı değildi sanırım)
zaman hesaplamasını nasıl yapıyorsunuz ? Yada Debug esnasında Keilde görebiliyormuyuz ?
Arkadaşlar USART_BRR registerinde baud hızını nasıl ayarlıyoruz ? Dıv mantissa ve Dıv fraction gibi terimler var tam anlayamadım. Bilen arkadaşların yardımlarını bekliyorum :)
STMF4 de FLASH erişme wait statini neden 5 waitstate seciyoruz. Bu işlemcinin komut işleme suresini yavaslatıyor. Daha kucuk secersek ne olur ?
Alıntı yapılan: Enginar - 12 Ekim 2012, 23:55:26
Arkadaşlar USART_BRR registerinde baud hızını nasıl ayarlıyoruz ? Dıv mantissa ve Dıv fraction gibi terimler var tam anlayamadım. Bilen arkadaşların yardımlarını bekliyorum :)
Genellikle baud registerleri tamsayı olduğu için ne yaparsak yapalım istediğimiz hızı tam tutturamayız. Bunun için bazen kristal değiştirmek bile gerekebilir. İşte o zaman şu bölücü register tam sayı olmasaydı ondalık sayılar da kullanabilseydik deriz. İşte fraction tam bu işe yarıyor.
Örneğin:
Fck = 8MHz.
ihtiyacımız olan baud hızı 9600.
Baud hızı = fck/(16xbölücü değeri) (oversampling =0 iken)
bölücüyü 52 yaparsak baud hızımız 9615 olur.
bölücüyü 53 yaparsak baud hızımız 9433 olur.
Tam hızı yakalamak için bölücümüzün 52.083333 olması gerek. Bunu sağlamak için fraction registerinden yararlanıyoruz.
Peki 52.08333 değerini nasıl yakalayacağız?
fraction registeri 4 bit. yani noktadan sonraki hanemiz en fazla 16 değer alabilir.
şimdi hesaplayalım.
mantissa = 52
fraction = 0.0833333 * 16 = 1.33333 en yakın tam sayı değer 1.
mantissa 52 fraction 1 olduğuna göre bölücü değerimiz 52.1
şimdi baud hızımızı tekrar hesaplayalım
baud = fck/(16*div) = 8000000/(16*52.1) = 9596.9
Görüldüğü gibi tam sayı register ile çalışırken istediğimiz baud ile gerçek baud arasındaki fark 15 iken fraction kullandığımızda fark 3.1 oldu.
@alisoy, rehber dökümanı incelersen orada bir tablo var. 168 MHz de minimum WaitState 5 olabilir. Frekansı düşürürseniz bu değeri arttırmanız mümkün...
@ Klein
hocam çok sağolun ben elazığdayım.Sorunumu hallettim.Ama bu kezde error:Flash download failed -'Cortex M4 ' hatası veriyo :(
Sorunumun çözümü burada ------------- https://www.picproje.org/index.php/topic,42626.0.html (https://www.picproje.org/index.php/topic,42626.0.html) ---------
startup_stm32f4xx.s dosyasını değiştirdim oldu :)
Tekrar başladım çalışmalara.Herşey için çok tesekkür ederim .Sagolunnn...
hocam tüm sorunlarımı hallettim.
error:Flash download failed -'Cortex M4 ' hatası için Utilities bölümünden Use Target Driver Flash programming ---settings den Add deyip STM32F4xx Flash ekledim.Sorun düzeldi.
HErkese kolay gelsin :)
STM32 embedded graphic object/touchscreen library (http://www.youtube.com/watch?v=PL3enedXTs4#ws)
Muthittin visual tft görsel olarak daha düzgün sonuçlar veriyor. Tek sorun keil, iar gibi derleyiciler için çıktı vermiyor. Mikroe compiler ı kullanman gerekir.
Hocam geçen ay lcd aldım basit uygulamalarla başlayacağım. sonrasında seçim aşamasında bunları öğrenmemiz gerekecek..
Arkadaşlar SPI uygulamasında anlamadığım noktaları sizinle paylaşmak istiyorum ve yardımlarınızı bekliyorum :)
1-)GPIOE->BSRR registeri hangi amaç için kullanılıyo ?
2-) Readchar rutininde SPI1->DR=((Adr&0x3F)|0x80)<<8; ve Wrintechar rutininde SPI1->DR=((Adr&0x3F)<< 8) |Data; kodlarının görevleri nelerdir ?
BSRR registeri bit set ve bit reset registeridir. Portlar üzerinde bit işlem yapmak için kullanılır. Alt 16 bit set üst 16 bit resettir.
BSSR nin 0. bitini set edersen ilgili portun 0. pini set edilir. Aynı şekilde 16. bitini set edersen porton 0. pini resetlenir.
SPI DR registeri hem spi aygıtına yazacağımız hem de oradan okuyacağımız bilginin bulunduğu register. Bu registere veri yazdığımız anda bilgi karşı taraftaki aygıta yazılmaya başlar.
Daha önce başka bir arkadaş sormuştu.
https://www.picproje.org/index.php/topic,35794.975.html (https://www.picproje.org/index.php/topic,35794.975.html)
Aslında kod karışık değil. Ama bunu anlamak için biraz SPI haberleşme yapısını bilmen gerek.
Bu örnekte 16Bit haberleşme kullanılıyor.
üst 8 bit hangi adresten okuma veya yazam yapacağımız bilgisini alt 8 bit de veriyi tutuyor.
SPI1->DR=((Adr&0x3F)|0x80)<<8;
Burada olan şu Okuma yapmak istediğimiz adresi 0x3F ile and işlemine sokuyoruz ki son 2 bitte 1 değeri varsa bu değerleri 0 yapalım ve kalan 6 bitin değeri ile oynamayalım. Sonra bunu 0x80 sayısı ile veyalıyoruz. Yani en son biti 1 yapıyoruz. Bu bit1 olunca karşı taraf okuma yapmak istediğimizi anlıyor. Sonra elde ettiğimiz bu sayıyı 8 bit sola kaydırıyoruz. Çünkü adres ve oku-yaz bitleri üst 8 bitlik kısımda olacak , karşı taraf da bu bilgiyi alınca alt 8 biti göndereceği sayı ile dolduracak.
SPI1->DR=((Adr&0x3F)<<8 |Data;
Burada da yine aynı şeyi yapıyoruz. Yazmak istediğimiz adres ile 0x3F sayısını ve yapıyoruz. Ancak burada 0x80 ile orlama yapmıyoruz. çünkü okuma değil yazma yapacağız. Bunları 8 bit sola kaydırıyoruz. Sonra da yazmak istediğimiz veri ile veyalayıp veriyialt 8 bite yerleştiriyoruz.
Heh anladım şimdi hocam Teşekkür ederim :)
Herhangi bir STM32 serisi işlemcinin SystemInit Rutinini Nasıl Hazırlanır?
Adı üstünde SystemInit.
Bu işlemcinin öncelikle clock kaynağını seçeceksin.
PLL varsa bunu istenen değere kitleyeceksin.
Kullanılacak donanımları clk ile besleyeceksin.
Veri yollarının hızlarını belirleyeceksin.
Portlardan I/O olarak kullanılacakları, ilave fonksiyonlara ait giriş çıkışları belirleyeceksin.
Timer, ADC, PWM vs kullanılacaksa bunları ayarlayacaksın.
Bu böyle devam eder. Fakat olmazsa olmaz iki ayar ilk iki ayardır. Diğerleri yeri geldikçe ayrıca da ayarlanabilir.
Tüm bunları yapabilmek için de bu çipin registerlerini anlatan dokumanın ilgili bölümlerini dikkatlice okumak gerekecek.
Arm mimarisini bilmek işleri kesinlikle kolaylaştırır.
Alıntı YapArm mimarisini bilmek işleri kesinlikle kolaylaştırır.
evet sanki sıkıntım buradan kaynaklı.
neyse bugün kendime görev seçtim. 32f100 ün sistem ayarlarını yapıp DAC dan belli bir gerilim alacağım.
mesaj birleştirme:: 20 Ekim 2012, 18:17:27
system_stm32f10x.c
dosyası bu systeminit i yerimize yapıyor sanırım
mesaj birleştirme:: 20 Ekim 2012, 22:10:33
#include <stm32f10x.h>
void SystemInit(void)
{
RCC->CR |= 0x00010000; //HSEON=1 High Speed External Osc ON
while(!(RCC->CR & 0x00020000)); //Harici osilatörün stabil olması için bekleniliyor(6 komut çevrimi)
RCC->CIR |= 0x00080000; //HSERDYC: HSE ready interrupt cleared
RCC->CR |= 0x00080000; //Clock security system Enabled.
RCC->CIR |= 0x00800000; //CSSC: Clock security system interrupt cleared.
RCC->CR |= 0x00040000; //HSE bypassed.
RCC->CFGR |= 0x00000080; //AHB configuration -> 1000: SYSCLK divided by 2
RCC->CFGR |= 0x00002000; //APB2 configuration -> 100: HCLK divided by 2
RCC->APB2ENR |= 0x0000001C; //PORT C,A,B Clock Enabled.
//-------------------------------------------------------------------------------------------------
RCC->APB1ENR |=0x20000000; //DAC Enable
GPIOA->CRL &= 0x00000000; //Aportu analog giriş
GPIOA->CRL |= 0x00000000;
GPIOA->CRH &= 0x00000000;
GPIOA->CRH |= 0x00000000;
DAC->CR |=0x00000003; //DAC Channel1 Enable, Buffer Disable
//-------------------------------------------------------------------------------------------------
GPIOC->CRL &= 0x00000000;
GPIOC->CRL |= 0x33333333; //PC0-7 Çıkış olarak ayarlandı (Max 50MHz)
GPIOC->CRH &= 0x00000000;
GPIOC->CRH |= 0x33333333; //PC8-15 Çıkış olarak ayarlandı (Max 50MHz)
}
void delay(int Z)
{
while(--Z);
}
main ()
{
while (1) // sonsuz döngü
{
Deger++;
GPIOC->ODR=0xFFFFFFFF;
delay(0x00000FFF);
GPIOC->ODR=0x00000000;
delay(0x00000FFF);
DAC->DHR12R1=0x000000FF;
/*
DACoutput=VREF * (DHR12R1 / 4095)
*/
}
}
Herhalde oldu.
Yanlız Hocam cm4 de sizin yazdığınız dac tan kopya çıkarttım keza datasından birşey anlamadım. (epey inceledim ama)
DAC->CR |=0x00000003; de siz buffer enable demişsiniz datasında 1 değer verildiğinde disable yazıyor.
Arkadaşlar SPI haberleşmesinin mantığını öğrenip yazılan kodlarla karşılaştırıp kavramaya çalışıyorum.Kavrayamadığım noktalar var.Yardımcı olursanız sevinirim :)
Full duplex iletişimde shift registerin Tx , Rx bufferla ve SPI_DR ile olan ilişkisi nasıldır ? full duplexte bi bit veri yollandıgı zaman karşıdanda bi bit veri geliyo diye biliyorum.ama bu bilgiyi yukarda adı geçen registerlerle bağdaştıramadım bi türlü :'(
dökümandan anladığım kadarıyla 2 tane 8 bitlik shift register var ? 1. shift registere 1 bit bilgi yazılınca 2. shift registerdende 1 bit bilgi okunuyo ?
Aydınlanmaya ihtiyacım var :)
SPI_DR hem alma hem de gönderme için kullanılan register. SPI haberleşmede Master tarafı CLK verdiği sürece registerde data varsa datayı gönderir. Aynı zamanda girişi de okur. Ve aynı registere yazar.
SPI master veri göndermeye başladı. İlk biti pine çıktı. CLK pininden darbeyi verdi. 1. bit gittiğinde 1. bitin yeri boşaldı. Buraya da giriş pinindeki bilgiyi yazdı. Bu bilgi genelde ilk 8 bit için 1 olacaktır. Çünkü karşı taraf bizim ne istediğimizi bilmiyor. İlk 8 bit gittikten sonra karşı taraf bizim ne istediğimizi biliyor artık. Biz halen clk basmaya devam ediyoruz. Karşı taraf da her darbede bize bilgiyi gönderiyor. Gelen veri de SPI_DR registerine yazılıyor. 8 darbe sonunda SPI_DR registerini okuyoruz. Eğer birden fazla bilgiyi peşpeşe göndermesini istemişsek , clk basmayı kesmiyoruz ve her 8 veya 16 darbeden sonra SPI_DR registerini okuyoruz.
Klein Hocam verdiğiniz bilgiler için teşekkür ederim kafamdaki başka bi soruya cevap buldum ama sorduğum soru için tatmin olamadım :)
Asıl öğrenmek istediğim Rx Tx buffer ve Shift registerin bu iletişimde nasıl bir rol üstlendikleri ?
Şöyle:
İki tane shift register var. TX buffere bağlı olan paralel giriş seri çıkış. RX buffer e bağlı olansa seri giriş paralel çıkış. CLK kaynakları aynı. shift registere clk verildiğinde tx bufferdeki bir bit seri çıkışa ötelenirken , seri girişteki bit de rx buffer'e aktarılıyor. Ancak bu TX ve RX bufferler ayrı ayrı değil. İkisi de aynı. SPI_DR registeri. SPI_DR registeri bir yandan ötelenerek boşaltılırken , diğer yandan da girişteki bilgi ile dolduruluyor.
Heh hocam istediğim yanıt buydu teşekkür ederim :).Dökümanlardan inceledimde biraz kafam karışmıştı şimdi oturdu :)
kod korumasını nasıl yapacağız ?
@muhittin kitimi yedin :)
STLink Utility ile kod koruması atayım dedim. Option bitini programlarken işin yarısında program uçtu.
Şimdi kart ile bağlantı kurulamıyor.
Yok Aklıma Geldi. Nasıl Yaparız Bu işi ?
Bir ara kartımı bende uçurmuştum. Daha sonra kendimce bir yöntemle kurtardım ve nasıl yaptığımı yazmıştım.
Bitbanding tartışması içinde diye hatırlıyorum. Gene bir başka arkadaş bir kurtarma şeklini yazmıştı. (Ama forumda nerede?)
Evet o tartışmayı hatırlıyorum ama bulamadım.
SWD pinlerinin program içinde kullanılması sonucu oluşan boot sorununu , boot0 pinini VDD'ye çekip, resete basılı tutup, program komutu verir vermez reseti bırakarak çözmüşler.
evet ben yaşamıştım. SWD pinlerini programdan değiştirmiş ve program atamamıştım. sonrasında Reset e basılı tutup olayı çözmüştüm.
şimdi program başlamadan bir gecikme koyuyorum (System init içerisinde ki gecikmelerde bu açıdan yararlı)
Benimki boot bini ile ilgili değil. Muhtemelen Write protectlerle ilgili veya bootloader uçtu.
Senin kod koruma sorusu ile uğraşırken oldu ,çözümü de senden bekliyorum :)
Çalışmadığım Yerden Soruyorsunuz Hep.
DFU kullanarak kurtarabilirsiniz belki...
DFU kullanabilmek için , önce bootloader kodlarını atmak gerekmiyor mu?
hocam st util ile bağlantı kurabiliyormusunuz
Hayır. Zaten o getirdi bu hale.
denemişsinizdir ama, option byte da değişiklik yaptınız mı
Alıntı yapılan: Klein - 04 Kasım 2012, 13:07:37
DFU kullanabilmek için , önce bootloader kodlarını atmak gerekmiyor mu?
bootloader gömülü zaten siz istesenizde o bölgeyi elleyemiyorsunuz...(diye biliyorum)
bir arkadaşım jtag pinlerini iptal etmişti seri port bootlader ile kurtardık kartını...
Şu zamana kadar korumayı aktif hale getirmedim. Yakında benim de korumayı devreye almam gerekecek.
Koruma, daha önce kullandığım çipler gibiyse keyleri iyi saklayın. Keyleri unutursanız bir daha asla çipi kurtaramazsınız. Keyler varoldukça muhakkak bir şekilde kurtulması lazım.
hangi key ?
Seri porttan programlamak için flasher aradım ama bulamadım.
Seri porttan programlamak için aşağıdaki programı kullanabilirsiniz.
http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/SW_DEMO/stm32-stm8_flash_loader_demo.zip (http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/SW_DEMO/stm32-stm8_flash_loader_demo.zip)
Kartlarımız üzerinde bulunan STlink i hariçte bulunan işlemciyi programlayabilirmiyiz ?
Alıntı yapılan: muhittin_kaplan - 07 Kasım 2012, 09:45:34
Kartlarımız üzerinde bulunan STlink i hariçte bulunan işlemciyi programlayabilirmiyiz ?
Hocam hiç denemedim ama araya jumper koydukları için ve pinleri header şeklinde çıkardıkları için swd' yi başka işlemcileride programlamak amaçlı koydukları düşünüyorum . Denemek lazım . Ben bir yerden kit almıştım . JTAG programlanıyordu bende jtag programlayıcı yok stm32f4discovery üzerindeki swd pinlerine göre ayarlayın programlayın demişlerdi . Denemedim daha . USB DFU mode kullanarak atıyorum şimdi ...
İyi Çalışmalar Dilerim .
Alıntı YapUSB DFU mode kullanarak atıyorum şimdi
Burayı biraz açarmısınız ?
Muhittin hocam ben hep o şekilde yapıyorum. Discowerymin birini programlayıcı olarak ayırdım :) SWD pinlerini PA13-PA14-GND şeklinde bağlayıp farklı işlemcileri programlıyorum.
Alıntı yapılan: muhittin_kaplan - 07 Kasım 2012, 10:06:51
Burayı biraz açarmısınız ?
Hocam USB üzerinden yazılım güncelleme ile alakalı Hocam . Device Firmware Upgrade ( DFU ) . ST'nin DFU programı mevcut . Bu program yardımı ile ilk olarak hex dosyasını dfu dosyasına çeviriyoruz . Sonrasında yine st'nin bir programı yardımıyla işlemci içerisine program atıyoruz . USB üzerinden programlayıcıya gerek kalmadan yazılımı güncelleyebiliyoruz .
Hocam aşağıda bir kaynak mevcut .
http://blog.elektrotasarim.com/?p=204 (http://blog.elektrotasarim.com/?p=204)
işlemciye daha önceden herhangi bir program yüklemesi yapıyormuyuz. Başka bir programlayıcı ile
@Klein Hocam,
MCU xtali söküp direkt JTAG veya SWD ile normal bir kod atmayı deneyin. Erase Chip yapacaktır. Ardından Xtali takıp normal kullanıma dönebilirsiniz.
Olmadı. Kristali söktüm. Halen bağlanmıyor. İçerideki kod halen çalışmaya devam ediyor.
Osilatörü EXT ayarlamış olmama rağmen kodun çalışması da ilginç.
Ya osilatör ayarını düzgün yapamamıştım, bu yüzden hep internal çalışıyordu, ya da harici osilatör hatası oluşunca dahili osilatöre geçiş yapıyor.
Dahili OSC ye geçme ihtimali mantıklı gelmiyor, ciddi sonuçlar doğurabilir saha şartlarında.
Şu an vaktim yok ama kodları gönderebilirseniz, ben de kilitleyip deneme yapabilirim sanırım. Bu vesile ile dokümanlara da bakmak zorunda kalırım, hala bakabilmiş değilim:). Bu sorun hepimizin başına gelebilecek ve önemli bir konu, çözmek lazım.
Kilitlemeyi kodla yapmadım. ST-Link Utility ile kilitledim. Option bitlerinni ayarladım, Read Protect yaptım ( Write protect bile yapmadım) Programlarken ST-Link kilitlendi, kapandı. Sonra karta bir daha erişilemedi.
Program , örnekler kısmında yayınladığım Usart echo örneği.
Kristal yokken alet çok garip şeyler yapıyor.
Enerjiyi kesip verdiğimde , 0.5 saniyede 1 flash yapan led, 4 saniye civarında flash yapıyor. Timer 7'nin hızı yaklaşık 1/8 düşüyor. Ancak Seri port aynı hızda çalışmaya devam ediyor. Osilatör haritasını daha incelemedim. CLK kaynaklarının farklı olması ile ilgilidir muhtemelen.
Enerjiyi kesmeden "Reset" butonu ile resetlersem , Timer normal hızına dönüyor. Usart3 te bir değişiklik olmuyor.
Ayrıca Boot0 pinini VDD'ye Boot1 pinini de GND'ye çekip resetliyorum, alet halen kodu çalıştırmaya devam ediyor. Seri porttan da ulaşılmıyor yani.
Öyle bir durum var ama kodları incelemek gerek.
RCC->CIR |= 0x00080000; //HSERDYC: HSE ready interrupt cleared
RCC->CR |= 0x00080000; //Clock security system Enabled.
RCC->CIR |= 0x00800000; //CSSC: Clock security system interrupt cleared.
ile HSE çalışmadığında işi HSI devralıyormuş
Denemedim Doğrulamaya Muhtaç
Alıntı yapılan: muhittin_kaplan - 07 Kasım 2012, 17:26:58
işlemciye daha önceden herhangi bir program yüklemesi yapıyormuyuz. Başka bir programlayıcı ile
Evet Hocam ön bir program yüklenmesi gerekiyor .
Alıntı yapılan: serhat1990 - 08 Kasım 2012, 08:27:52
Evet Hocam ön bir program yüklenmesi gerekiyor .
Ozaman Benim işime gelmez keza programı yükleyeceksem doğrudan yüklerim.
Alıntı yapılan: muhittin_kaplan - 08 Kasım 2012, 08:47:06
Ozaman Benim işime gelmez keza programı yükleyeceksem doğrudan yüklerim.
Anladım Hocam, bir kere SWD pinlerinden programlarsanız sonrasında USB DFU mode ile programı atarsınız diye düşünmüştüm ben .
İyi Çalışmalar.
Alıntı yapılan: muhittin_kaplan - 08 Kasım 2012, 00:07:25
Öyle bir durum var ama kodları incelemek gerek.
RCC->CIR |= 0x00080000; //HSERDYC: HSE ready interrupt cleared
RCC->CR |= 0x00080000; //Clock security system Enabled.
RCC->CIR |= 0x00800000; //CSSC: Clock security system interrupt cleared.
ile HSE çalışmadığında işi HSI devralıyormuş
Denemedim Doğrulamaya Muhtaç
Evet hocam HSI devralıyor. (Bende denemedim ama dökümanlarda açıkça böyle olduğu yazıyor.)
ADC ile kullanabileceğim PORTlar hangileri bir türlü bulamadım.
Çözüldü.
mesaj birleştirme:: 09 Kasım 2012, 08:31:41
Yeni Soru.
HSI yerine neden HSE kullanayım. Yada HSE yerine neden HSI kullanayım.
(elimde 32f100rb var. HSI da 8mhz HSE de 8mhz oradan PLL ile 24mhz yapıyorum.)
ADC1->SQR3 |= 0x00000008; // Çevrime ilk girecek kanal 8. (PB0)SQR registerleri hangi kanalın hangi sırayla çevirime gireceğini seçmemizi sağlar. Register 5'er bitlik alanlara ayrılmıştır. Her bir SQR registeri 6 tane kanalın sıralamasını seçmemize izin verir. SQR3 registeri ilk 6 sıra, SQR2 7- 11 arası SQR1 de 12-15 arası olmak üzere toplam 16 kanalın sırasını seçmemize olanak verir.
SQR1 reg isterini diğer SQR registerlerinden ayıran özellik ise, Bu registerin 20-21-221 ve 23. bitlerinden scan modda kaç kanalın taranacağını seçebiliyor olmamızdır.
Örneğimiz tek kanal olduğu için sadece İlk sıraya kanal numarası girdik diğerlerine bir şey girmedik. PB0 8. kanal olduğu için bu registere 8 yazdık.
hocam burda SQR3 ile 8. kanalı nasıl seçtik .dökümana baktığımda;
Bits 9:5 SQ8[4:0]: 8th conversion in regular sequence 8 . kanal SQR2 de gözüküyor.
Yanlış!
SQR registerleri çevirime girecek kanalların sırasını belirliyor. SQR2 registerindeki 8. sıra , 8. kanalı ifade etmiyor. çevirime 8. sırada hangi kanalın gireceğini seçiyoruz. Buraya 1 yazarsak, 8. sırada çevirime girecek kanal 1 dir. buraya 8 yazarsak 8. sırada çevirime girecek kanal 8 olur.
Çevirime ilk girecek 6 kanalın seçimi SQR3 registerinden yapıldığı için buraya 8 yazdık.
Alıntı YapBits 9:5 SQ8[4:0]: 8th conversion in regular sequence 8 . kanal SQR2 de gözüküyor.
SQR2'de görünen 8 , 8. kanal değil. 8. sırada çevirime girecek kanal.
anladım şimdi teşekkürler hocam.buarada ADC&DMA ile yapmış olduuğunuz bir uygulama varmı?
https://www.picproje.org/index.php/topic,43472.0.html (https://www.picproje.org/index.php/topic,43472.0.html)
teşekkürler görmemişim orayı.
stm kiti üzerinden veriyi gönderip PB10 ile PB11 i birbirine bağlayıp veriyi tekrar okumaya çalışıyorum fakat bi türlü veriyi alamadım kodlar şu şekilde nerde hata yapıyorum acaba?
#include "STM32F4xx.h"
#include "Delay.c"
#include "HD44780.c"
#include "stdio.h"
void SystemInit()
{
unsigned int i;
for (i=0;i<0x00100000;i++); // OSC oturtma ve kurtarma rutini
RCC->CFGR |= 0x00009400; // AHB ve APB hizlarini max degerlere set edelim
RCC->CR |= 0x00010000; // HSE Xtal osc calismaya baslasin
while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim 168 Mhz
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
RCC->AHB1ENR |= 0x0000001F; // GPIO A,B,C,D,E clock'u aktif edelim
GPIOD->MODER = 0x55000055; // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
GPIOB->MODER = 0x00000500; // GPIOB 4 ve 5 i çıkış yaptık.
GPIOA->OSPEEDR= 0x00000000; // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
GPIOB->OSPEEDR= 0x00000000; // AYnı şey GPIOB içinde geçerli
GPIOC->OSPEEDR= 0xFFFFFFFF;
GPIOD->OSPEEDR= 0x00000000;
}
void usart_init()
{
RCC->APB1ENR|=0x00040000;
GPIOB->MODER|=0x2AA00000;
GPIOB->AFR[1]=0x07777700;
USART3->BRR=0X1112; // 9600 Baud
USART3->CR1|=0x0000202C; // USART3 enable
}
void ilet(char *veri)
{
while(*veri)
{
while(!(USART3->SR&0x80));
USART3->DR=*veri++;
}
}
char oku()
{
while(!(USART3->SR&0x20));
return(USART3->DR);
}
int main()
{
unsigned char diz[]="";
usart_init();
lcd_init();
ilet("veri");
while(1)
{
lcd_git(1,1);
sprintf(diz,"%c",USART3->DR);
lcd_yaz(diz);
}
}
Alıntı yapılan: muhittin_kaplan - 20 Ekim 2012, 13:43:52
GPIOA->CRL &= 0x00000000; //Aportu analog giriş
GPIOA->CRL |= 0x00000000;
GPIOA->CRH &= 0x00000000;
GPIOA->CRH |= 0x00000000;
DAC->CR |=0x00000003; //DAC Channel1 Enable, Buffer Disable
//-------------------------------------------------------------------------------------------------
GPIOC->CRL &= 0x00000000;
GPIOC->CRL |= 0x33333333; //PC0-7 Çıkış olarak ayarlandı (Max 50MHz)
GPIOC->CRH &= 0x00000000;
GPIOC->CRH |= 0x33333333; //PC8-15 Çıkış olarak ayarlandı (Max 50MHz)
Yukarıdaki kodda 0x00 ile
and leyip yine 0x00 ile
or luyor. Bir altında 0x00 ile
and leyip, 0x333.. ile
or luyor.
Bunların yerine ilkinde 0x00 a
eşitlesek, ikincisinde de 0x333.. e
eşitlesek olmaz mı?
GPIOA->CRL = 0x00000000; //Aportu analog giriş
GPIOA->CRH = 0x00000000;
DAC->CR |=0x00000003; //DAC Channel1 Enable, Buffer Disable
//-------------------------------------------------------------------------------------------------
GPIOC->CRL = 0x33333333; //PC0-7 Çıkış olarak ayarlandı (Max 50MHz)
GPIOC->CRH = 0x33333333; //PC8-15 Çıkış olarak ayarlandı (Max 50MHz)
9 satır kod için aslında bu 5 satır yeterli değil mi?
Hocam Hatırlmıyorum ama denemiş bir problem görmüş (belki oradan kaynaklı değildi) değiştirmemiştim.
Olması gerekir.
Alıntı YapYukarıdaki kodda 0x00 ile and leyip yine 0x00 ile or luyor. Bir altında 0x00 ile and leyip, 0x333.. ile or luyor.
Bunların yerine ilkinde 0x00 a eşitlesek, ikincisinde de 0x333.. e eşitlesek olmaz mı?
Olur.
GPIOA->AFR[0] demek GPIOA->AFRL demek midir?
abiler cok cahilce bir soru olacak ama stm32 bir mcu ile 1adc 10giriş 10 çıkışlı birşeyler yapmak istiyorum.
yazılımdam önce en kaba kılıfta örnek projerlerden faydalanabileceğim bir mcu secmek istiyorum.
burdan sonra sorunlarım başlıyor kitle çalışrken takıyorum usb kablu at kodu gidiyo kendi tasarladığım pcbde kodumu atmam için gerekli olan nedir debug yapma şansım varmı.
yalansöylemiyeyim balık cevaplar çok işime gelir ama en azından bir mcu belirleyip datasheetin neresine kafayı gömecem ona yardımcı olsanız o bile süper olur.
yani kit haricinde kullanırken minimum gereksinimlerimiz nedir.
stm32discover kitindedi örnekler ve kütüphaneler başka mcular için yardımcı olurmu.
MCU, 5-6 adet kondansatör 3.3v kaynak,
Diskovery kitin varsa yükleyiciye ve debugger e de ihtiyacın yok.
Üstatlarım kolay gelsin
STM32F4 ile vaktim oldukça bi şeyler yapmaya çalışıyorum bu gün Bülent hocanın forumdaki uart örneklerinden birini birazcık değiştirdim yani pc den gönderdiğim karaktere göre kit üzerindeki istediğim ledi yakıyorum fakat ledi bi kez yaktıktan sonara söndürmek için kod gönderdiğimde led tam olarak sönmüyor cok az da olsa bi yerlerden akım çekiyor bunun nedenini bi türlü anlamadım.. usb-rs232 dönüştürü olarak daha önce de piclerle de sorunsuz kullandığım tusb3410 entegreli bi dönüştürücü kullanıyorum. bu durumun sebebi ne olabilir yardım edebilirmisiniz
Alıntı yapılan: muhittin_kaplan - 01 Şubat 2013, 23:51:18
MCU, 5-6 adet kondansatör 3.3v kaynak,
Diskovery kitin varsa yükleyiciye ve debugger e de ihtiyacın yok.
hocam kit sizlere ömür birde aklıma şöyle bişi geliyor basicle hobisine bişiler yaptım mikroişlemcilerle tanışmış oldum.
biraz avr asm olayına gireyim dedim gerbay hocamın deyimiyle sonrasına bir faydası olmayacak arm ağır geliyor.
ben en iyisi armdan önce bir stm8 kiti alıp onla biraz c idmanı yapıp döneyim.
arm kiti yakında bir abim getirecek ama benim için hala çok zor sanki stm8 örnekleri daha acemilere göre.
fikirleriniz görüşleriniz benim için çok önmli basit sorunlarıda forumda yazmak istemiyorum.
c öğren gel falan gibi cevaplar alıyorum.
kendim bişiler tasarlamak istiyorum c öğrenmek amacıyla.
Benim soru kaynadi mi arada?
C idmanini elinde pic varsa onunla da yapabilirsin.
Alıntı yapılan: ilhan_mkp - 02 Şubat 2013, 00:41:42
hocam kit sizlere ömür birde aklıma şöyle bişi geliyor basicle hobisine bişiler yaptım mikroişlemcilerle tanışmış oldum.
biraz avr asm olayına gireyim dedim gerbay hocamın deyimiyle sonrasına bir faydası olmayacak arm ağır geliyor.
ben en iyisi armdan önce bir stm8 kiti alıp onla biraz c idmanı yapıp döneyim.
arm kiti yakında bir abim getirecek ama benim için hala çok zor sanki stm8 örnekleri daha acemilere göre.
fikirleriniz görüşleriniz benim için çok önmli basit sorunlarıda forumda yazmak istemiyorum.
c öğren gel falan gibi cevaplar alıyorum.
kendim bişiler tasarlamak istiyorum c öğrenmek amacıyla.
Amacın ARM 32 ile çalışmaksa hiç uğraşma 8 e felan.
sana önerim şu olur. her halukarda bir debugger programmer gerekli. STM discovery kitin neresi bozuldu ? PC ye taktığında ST link i görmüyormu yoksa sadece işlemcimi gitti.
bir adet expkit in yada elektrotasarımın çevirici PCB sinden al işlemcine göre. bende 32f103rb nin lqfp64 paketine göre olanı var onu kullanıyorum. Böyle bir çalışma yapabilirsin. C gözünde büyüteceğin kadar zor değil. Halledilir.
Kolay gelsin
mesaj birleştirme:: 02 Şubat 2013, 10:02:50
Alıntı yapılan: LukeSkywalker - 01 Şubat 2013, 20:52:55
GPIOA->AFR[0] demek GPIOA->AFRL demek midir?
Evet Mantık Olarak Aynı, Ama AFRL olarak Kullanımını Görmedim. KOntrol gerektirir.
Nasıl bir kontrol gerektirir?
Debug ederek deneme yapmak lazım.
arkadaşlar ben konuları yeni okuyorum. Keil i yeni indirdim ve sanırım varsayılan kütüphane dosyaları bende farklı. Derlerken hata vermiyor fakat led yakma uygulaması bile çalışmıyor. Burdaki projeleri indirip indirdiğim projelerde yer alan kütüphane dosyalarını kullandığımda yine derleniyor ve çalışmaya başlıyor.
Bu işlemin sebebini bilen bir arkadaş var mıdır? Kütüphane dosyasını program dizininde bulup eski dosyayı atmaktan daha iyi bir çözüm arıyorum.
Merhaba arkadaslar.Stm32 ile program yazmaya başlayalı cok oldu.Yavas yavas ilerlerken sıra geldi LIS302DL çipine.Bülent hocanın kodlarına baktım.Ref manuelden spi donanımına baktım.Anlamadığın nokta SPI1->DR=((Adr&0x3F)<<8 )|Data; ve SPI1->DR=((Adr&0x3F)|0x80)<<8; . Neden her seferinde adresi 0x3F ile and işlemine sokuyor.0x3F nerden geldi.Bu satırları acıklayabilirseniz cok sevinirim.
Kolay gelsin...
SPI1->DR=((Adr&0x3F)<<8 )|Data; ve SPI1->DR=((Adr&0x3F)|0x80)<<8;
değil de
SPI1->DR=(Adr<<8 )|Data; ve SPI1->DR=(Adr|0x80)<<8;
yazmış olsaydık bu kodları barındıran fonksiyona 3F den daha büyük değer yollamayın diye uyarı yapmamız gerekirdi.
3F ile andleyince kardeşim ne gönderirsen gönder eğer verin 3F den büyükse verini kırparım ayağını denk al diyerek fonksiyona parametre yollayacak şahısa inisiyatif vermemişiz.
Nedeni için SPI çipin DR registerine bakman gerekir. Bakarsan adres alanının 6 bit olacağını görürsün. (Dokümana bakmadım ama 3F ile andlemekdeki amaç bu)
Çok sağolun hocam.Çok teşekkür ettim.
merhaba arkadaşlar stm32f4 de kesme kullanırken aynı donanım biriminin kesmelerinde sadece bir tanesini mi aktif edebiliyoruz yoksa istediğimizi aktif edebiliyormuyuz.
örnekğin
USART_ITConfig(USART3,USART_IT_TXE,ENABLE);
USART_ITConfig(USART3,USART_IT_TC,ENABLE);
USART_ITConfig(USART3,USART_FLAG_RXNE,ENABLE);
USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
bunları u şekilde aktif etmemde sorun varmı
Problem yok dogru yapıyorsun kesme içerisinde hangisinden gelmiş kontrol etmek kalıyor sadece.
merhaba arkadaşlar.size bir sorum olucak konu dışıysa kusuruma bakmayın lütfen.ben uzun süre ccs c ile programladım ama arma geçtikten sonra z hocamın örneklerindeki register kullanımı çok hşuma gitti ve register okumanın mantığını çok daha iyi anladım.ama internetde gezerken kullanıcıları çoğunun paylaştığı kodlarda gpıo kütüphanesi gibi kütüphaneler çağırılmış ve register kullanımı yerine standart c kodlarına dönüş olmuş.benim size sormak istediğim şey şu arm programlamanın iki farklı yüzümü var.
teşekkürler arkadaşlar.
keil ve daha bir çok derleyicinin kütüphaneleri yakın zamanda gelişti ve insanı oldukça zorlayan registerlara boğulma ve okunması zor olan kodlardan kurtardı.
Çevre birimlerini çalışır hale getirmek için "init" fonksiyonları hazır. Hamallık yapmak yerine esas işimizle daha fazla ilgilenebiliyoruz.
Nette gezen kodların eski olanlarını okumak oldukça zordur, hele bir de register işlemlerine açıklama koymadıysa vay haline, düzenleme yapmak istediğinde açarsın datasheeti gözlerin kör olur kodu anlayana kadar.
evet 2 farklı yüzü var, hazır kütüphaneleri kullanabilirsin, ya da her bir ayarı registerlara müdahale ederek tek tek kendin yaparsın.
merhaba arkadaşlar.Z hocanın anlattıkları konularla arm a başladım.Anlayamadığm kaç nokta var
Discovery kitindeki işlemcimiz resetlendiğinde, Boot0 ve Boot1 pinlerinin konumu gereği Flash rom 0x0800.0000 adresinden 0x800.0??? (Daha sonra kesinleştireceğim) a kadar adreslerdeki veriler aynen 0x0000.0000 adresine yansır. Yani bu adres aralığındaki veriler birbirinin aynı olur. Bu olaya mirror yada ReMap işlemi denir.
1-Boot0 ve boot1 farklı bir kombinasyonda olsaydı flash rom 0x0800.0000 adresinden değilde başka adrestenn mi başlayacaktı
2-bu flash rom yazdığımız kodun çalıştığı yer mi oluyor.
3-Arm mimarisinde Boot işlemi 0x0000.0000 da olur da ondan . Boot işlemi sistemin çalışması için gerekli kodların okunduğu böllge mi oluyor?
1- Hayır.Flash rom'un adresi değişmez.Boot0 ve Boot1 e göre nerden boot edileceği seçiliyo.Örneğin USB,Uart,I2C vs..
2-Evet bizim yazdığımız kod flash rom'da tutulur.
3-Boot işlemi sonucunda Program Counter kodların bulunduğu bölgeye sıçrar ve yazdığımız program çalışmaya başlar.Eğer Kodlar dışarıdan okunuyosa USB,UART vs.İlk olarak okunur rom a yazılır ve rom'un ilk adresine gidilir.Eğer zaten flash'tan boot ediyosan bunlara gerek kalmaz direk flash'a sıçranır.
NOT:"Flash rom 0x0800.0000 adresinden 0x800.0??? (Daha sonra kesinleştireceğim) a kadar adreslerdeki veriler aynen 0x0000.0000 adresine yansır. Yani bu adres aralığındaki veriler birbirinin aynı olur" En başta böyle bir olay oluyo mu ondan pek emin değilim geçenlerde konusu tekrar geçmişti ama tam olarak netleştiremedik.Bana göre böyle bir olaya gerek yok ama yanılıyo da olabilirim.Bilen biri cevaplayabilirse güzel olur.
Anladım teşekkürler açıklamalar için
FLASH->ACR = 0x00000605; // Flash ROM icin 6 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55) Mecburen bunu yazacağız
Bu ifade de ben kendim clock ayarlarını yaparken hiç aklıma gelmedi .
-6 Wait state olmasının anlamı nedir (yada başka seçenek)
- Bu tür ayarlamaları nerden bileceğiz ? Diğer işlemcilerde de böyle birşey var mı
ARM larda var. İşlemcinin Hızıyla Alakalı, Hızlandıkca Bu değeri Yükseltmen gerekir.
anladım teşekkürler hocam.
Datasheeten anladığım kadarıyla bu register yazdığımız kodu flash memory den çekip işleme mi sokuyor? doğru anlamışmıyım
Meraba,
Stm32f4 disco ile bir türlü yıldızımı tam barışmıyor.Bir dargın bir barışık durumdayız.
Ben kodumu yazıyorum, yüklüyorum (Ide yüzünden sadece debug ile yükleyebiliyorum) ama programım çalışmıyor.Halbu ki aynı programı daha önce çalıştırdım.
Bazen kit üzerindeki debuggera da erişim olmuyor.Ben de stlink utulity ile çipi komple sildim.Sonra ide ile debug yapabilmeye başladım.Ama programım yine çalışmıyor.Başka basit blinky projesini yüklüyorum çalışıyor.Benim yüklediğim çalışmıyor.
Acaba çipi silmekle hata mı yaptım?Çip üzerinde bootloader falan var mıydı?
Çip fabrika çıkışlı halde kit üzerinde iken bir boot loader vs yüklü mü geliyor?
Not: Kullandığım ide EmBlocks.
Bu arada Coide ile ne program yükleyebildim ne de debug yapabildim.
bootloader silinmiş olsaydı blinky programını nasıl yüklüyor ki?
Alıntı yapılan: yldzelektronik - 27 Haziran 2014, 08:37:07
Meraba,
Stm32f4 disco ile bir türlü yıldızımı tam barışmıyor.Bir dargın bir barışık durumdayız.
Ben kodumu yazıyorum, yüklüyorum (Ide yüzünden sadece debug ile yükleyebiliyorum) ama programım çalışmıyor.Halbu ki aynı programı daha önce çalıştırdım.
Bazen kit üzerindeki debuggera da erişim olmuyor.Ben de stlink utulity ile çipi komple sildim.Sonra ide ile debug yapabilmeye başladım.Ama programım yine çalışmıyor.Başka basit blinky projesini yüklüyorum çalışıyor.Benim yüklediğim çalışmıyor.
Acaba çipi silmekle hata mı yaptım?Çip üzerinde bootloader falan var mıydı?
Çip fabrika çıkışlı halde kit üzerinde iken bir boot loader vs yüklü mü geliyor?
Not: Kullandığım ide EmBlocks.
Bu arada Coide ile ne program yükleyebildim ne de debug yapabildim.
Bootloader bulundğu bölge ile flash memory ayrı yerler.Yani chip'i sildiğinde sadece flash memory'i silmiş oluyorsun.Bootloader'a hiçbişey olmuyo.
Hocam benim bir sorum var ben arm a yeni basladım yazıları okuyorum dediğiniz şeyleri yaptım kartın üstünde debug modda led yaktım ancak bu kodu stm ye atamadım st-link var hazırkodlar(samples ) daki kodlar atılıyor ancak buradaki kodları atmayı basaramadım yardımcı olurmusunuz
Hocam keil size ne hata veriyor sorunlari yazarmisiniz
hocam keil 5 ile yapmaya çalışmıştım olmamıştı ancak 4 ile deneyince basardım teşekkür ederim ilginiz için
hocam galiba ben keil 5 de proje açarkenki ayarları yapamadım
hocam merhabalar. Programın başına #include "stm32f4_discovery.h" yazdıgım zaman fatal error uyarısı alıyorum ve stm32f4_discovery.h dosyasının bulunamadıgı söyleniyor. Bunun sebebi ne olabilir? Teşekkürler
Alıntı yapılan: turti - 02 Eylül 2015, 02:45:09
hocam merhabalar. Programın başına #include "stm32f4_discovery.h" yazdıgım zaman fatal error uyarısı alıyorum ve stm32f4_discovery.h dosyasının bulunamadıgı söyleniyor. Bunun sebebi ne olabilir? Teşekkürler
Proje ayarlarında include klasörlerini ayarladın mı?
Alıntı yapılan: CoşkuN - 02 Eylül 2015, 10:02:00
Proje ayarlarında include klasörlerini ayarladın mı?
nerden yapmam gerekiyor?