STM32F4 - Kolay programlama - ZIOS

Başlatan z, 26 Aralık 2013, 17:28:23

z

ARM çiplerle tanışmak isteyenlerle biraraya gelip, geçmiş dönemde STM32F4 Discovery kiti satın almış ve sanal dersane ortamında çalışmalar yapmıştık. Eminimki, elektronik yada işlemci camiasına yeni adım atmış ya da hiç adım atmamış arkadaşlar için bu çalısma ağır kaçmış ve çok da faydası olmamıştır.

Zaten o derslerin en başında, anlatıları kavrayabilmek için en azından bir işlemci uzerinde deneyim sahibi olmak ve bununla bir yada iki proje geliştirmiş olmak şart gibi bir ifade kullandığımı hatırlıyorum.

Bu yazımda ise, C dili ile PC de kod yazabilen fakat hiç elektronik tecrübesi olmayan arkadaşlara, sanki PC de proje geliştirir gibi doğrudan  donanıma mudahale etmeden  ("register"larla vs uğraşmadan) STM232F4 Discovery kitinde proje geliştirmelerine yardımcı olacak ZIOS kütüphanesinin kullanımını anlatacağım.



Bu calışmada STM32F4 Discovery kit üzerindeki STM32F407 çipini tanımanız gerekmiyor.
Karmaşık ve uzun uzun satırlar yazmayı gerektiren CMSIS fonskiyonlarıyla hiç işiniz yok.

İhtiyacınız olan donanım, STM32F4 Discovery kiti. Bunun dışında SD kart takabileceğimiz bir konnektor, 2x16 LCD, kablo parçacıkları, lehim ve havya. Tabiki istek.

STM32F4 Discovery başlı başına bir mikro bilgisayar. Bununla elektrikli cihazları on-off edebilir, SD karttaki bir dosyayı okuyabilir, SD kartda dosya olusturabilir, dosya içine bir şeyler yazabilir, 2x16 LCD de mesaj verebilir, mouse butonuna benzer yapıda kullanacağımız çok fonksiyonlu mavi butonu okuyabilir, ADC den voltaj ölçümü yapabilir, seri porttan veri alıp gönderebilirsiniz. Bunları yapmak icin mevcut bilgileriniz size yetecek. İlave hiç bir şey bilmenize gerek kalmayacak.

Tüm bu işler icin sadece 4Kb civarında yer kaplayan ZIOS kutuphanesini projemize dahil etmemiz gerekiyor. Bir de havya kullanarak Discovery kitin bazi pinlerine bir kaç kablo lehimleyip bu tellere kart okuyucu, LCD vs bağlayacağız. Bunları da resim ve gerekiyorsa videolarla açıklayacağım.

Yaşasın C, sen sağ ol varol.

Bu arada ZIOS, Z's Input Output System demek.

ZIOS ne ise yarar?

PC donanimini dusunun. Konuyu, eski zamanlardaki  taaa XT-AT gibi PC donemlerinden hatirladigim orneklerle aciklayayim;

"PC"de timer 8253/54 diye bir cip bulunur(du).  Bunun icinde 3 tane Timer/Counter unitesi vardır. BIOS/DOS gelistirilirken adamlar demislerki atiyorum Timer 1 system tick icin kullanilsin, Timer 2 duduk sesi icin, Timer 3 DRAMlari refresh etmek icin. (Rakamlara takilmayin yanlis hatirliyorumdur onemli değil)


Boyle bir kabul yapınca yani hangi donanımın hangi işte kullanilacağı kesinleşince her şey kolaylaşıyor.
Boyle bir kabul yapildiktan sonra DOS yada PC ye uygulama programi yazanlar ben bu siralamaya uymayacagim ben Timer 1 şu amaçla kullanacagim dememisler. Boylece bazi standartlar olusmus.

Kullanıcı programı yazanlar donanımla ilgili rutinler yazmayıp DOS'daki ya da BIOS'daki alt rutinleri çağırır olmuşlar.

BIOS, donanımla ilgili fonksiyonları barındıran temel program parçacıklarını içerir. Örneğin, keyboard controller ile haberleşip herhang bir tuşa basıldı ise bunu okuyan program parçacığı ya da ekranda mesaj vermeye yarayan fonksiyonlar BIOS'da mevcuttur.  Ekran kartı ile ilgili temel programlar da BIOS içinde mevcutdur.


STM32F407 gibi ici tika basa timerlar, seri portlar, IO portlar, ADC ler vs vs olan cipimiz var.  Bu çiple proje geliştirirken şu timer şu ise yarasin, ADC nin su pini kullanılsın şeklinde kendimizce görev paylaşımı yapıyoruz.

Ardından da bu tanımlara uygun register yapılandırmaları yapiyoruz. Yani initialize rutinleri yaziyoruz.

Iste bu noktada isler yeni baslayanlar icin cetrefilli bir hal aliyor.

Çipin registerlerini anlatan binlerce sayfalik dokuman var. Ustelik Ingilizce.
Arkadasimiz cipi zaten tanimiyor. Eger daha once bu tip ciplerle de calismadi ise bilgi denizinde bogulmaya mahkum kalmaktadir.

Bir çipin registerlerini öğrenseniz bile, bir başka çiple çalışacaksanız gene bir bocalama dönemi olmaktadır.

Adamlar bu isleri basitlestirmek adina CMSIS (Cortex Microcontroller Software interface Standart) diye bir seyler yapmislar. Siz bunu bir kez ogrendinizmi artik hangi cipi kullanırsaniz kullanın çipin içi daha oncekilerden cok cok farkli bile olsa register initialize islemlerini bu CMSIS kod parcalari kendi basina yapiyor. Sizin detaylari bilmeniz gerekmiyor.

Iyi tamam da bu CMSIS de iki üç sayfalık dokumanla açıklanmıyor ki.  Hiç bir şey bilmeyen için, CMSIS de kocaman bir öcü.

Isin ozu, ARM sistemlerle bir iki basit deneme yapmak isteyen fakat daha once islerle hic uğraşmamış birisinin ağrısız sızısız bir şeyler yapması pek mümkün görünmüyor. Ya hazır program parçaları bulup uzerinde oynayacak ya kafayı takacak bu işleri adım adım ögrenecek yada şimdi anlatmaya calistigim ZIOS kutuphanesini kullanacak.

ZIOS ahım şahım bir sey değil.  STM32F407 içindeki bazı donanımlara el koydum. Bunların hangi amaçla kullanılacağına karar verdim, initialize rutinlerini yazdım, bu donanımların C ile bağlantılı komutlarıyla ilgili rutinlerini de hazırladım ve kütüphane şekline getirdim alın size ZIOS. 

Yani BIOS (Basic Input Output System) rutinlerinin STM32F4 Discovery'deki karşılığına ZIOS dedim.


Keil'de ZIOS'u projenize dahil edip derleme ardından kodunuzu çalıştırdığınızda, reset işlemi ardından main satirina gelinceye kadar geçen ara süreçte  farkına bile varılmayacak pek cok initialize işlemi çoktan yapılmış olmaktadır.

Bu durumda daha main'in ilk satirinda Lcd_Msg(0,0,Merhaba Dunya") yazarsaniz 2x16 LCD ekranda Merhaba Dunya yazısını görürsünüz.

Ya da mainin ilk satırında zlist(&File,0) yazarsaniz SD kart icindeki Root klasorundeki dosyalardan ilk 16 tanesinin ismi File buffer içinde hazır olacaktır.

ZIOS kullanmasaydık aynı işlemleri yapabilmek için SystemInit fonksiyonu içine kullanılan donanım parçacıklarının init işlemlerini yapan kodları yazmamız gerekecekti. Keza LCD, SD kart gibi orta seviyede ara kodlama gerektiren donanım parçacıkları içinde oku/yaz türü program parçacıklarının programımıza dail edilmesi gerekecekti.

İşte ZIOS, bu SystemInit ve temel I/O donanımları ile ilgili fonksiyonları içinde barındırmakta, ilk başlarda acemilik döneminde kabus gibi görünen bu rutinlerin ayak bağı olmamasını sağlamaktadır.

Sizin ne SD kart donanimini init eden rutini ne de LCD yi init rutinini cagirmaniz gerekmektedir. ADC de o anki cevrilmis degeri okumak icin ADC nin yapilandirilmasi ile ugrasmaniz gerekmemektedir. Cunku o anki deger hazir olarak okunmayi beklemektedir.

Kisacasi ZIOS programınızın donanımla ilgili iletişimini üstlenir bu kısımlara kafa yormanıza gerek kalmaz.  Size sadece, amaca yonelik C kodlama yapmak kalir.

Peki cip icindeki tum donanimlari init ettim mi? Hayir. Lazım oldukca ZIOS'a ekleyebilirim. Yada işin içine girip olayları kavradıkça register bazlı kodlamalarınızı yada CMSIS kodlarınızı ZIOS ile birlikte kullanabilirsiniz.

Sistemde kaza (crash) istemiyorsaniz işin başlarında donanıma ulaşmamaya çalışın. Bırakın ZIOS sizin için yapsın. Kendinizi hür hissetmeye başladığınızda ZIOS'a ihtiyacınız kalmayacak ve ARM ciplere %100 kendi kodlarinizi yazabileceksiniz.

Yeterki merakiniz olsun ve gayret edin....

Eger yazimin icinde Zlib gibi bir ifade gorurseniz yadirgamayin, bu bir dil surcmesidir. Cunku ZIOSun bebeklik haline Zlib adini vermistim. ZIOS yada Zlib ayni anlama gelmektedir.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

#1
STM32F4 Discovery kitimizi masamizdaki metal objelerin ustune koymuyoruz. Kitin altindaki pinlerin metal nesnelerle temas etmesine engel olacak cozumler getiriyoruz. Mesela;

STM32F4 Discovery

KEIL Programinin kurulmasi

ARM işlemcilere program yazmak, derlemek, derlenmiş kodları çipe aktarmak, çipteki yazılımı koşturmak ve yazdığımız kodlardaki hataları ayıklamak için Keil programı kullanacağız.

Keil profesyonel ve pahalı bir yazılım ancak, 32 KByte uzunluğa kadar deneme amaçlı program yazımına imkan tanıyan ücretsiz sürümü http://www.keil.com/ sitesinden indirip kurabilir ve güncellemeleri takip ederek deneme sürümünüzü güncel tutabilirsiniz.

https://www.keil.com/arm/demo/eval/arm.htm adresini tıklayarak karşınıza gelen tabloyu doldurup yollayın. Bu  işlem ardından kurulum dosyasını bilgisayarınıza indirin ve kurulumu başlatın.



Kurulum biraz zaman alıyor. 

Asagidaki linkten Discovery kitin PC tarafindan taninmasi icin gerekli driver'i indirin ve kurun.

http://www.st.com/st-web-ui/static/active/en/st_prod_software_internet/resource/technical/software/utility/stsw-link004.zip

mesaj birleştirme:: 29 Aralık 2013, 01:12:34

Ilk uygulamamiz tahmin edeceginiz gibi yanip sonen LED programi.

Discovery kitin uzerinde kullanicinin yakip sondurebilecegi mavi, yesil, kirmizi ve kavun ici olmak uzere 4 adet led var.

Kitimizin iki kenarina siralanmis pinlerin ustune dikkat ederseniz PA1, PB2, PC1, PD5, PE1 gibi minik yazilar goreceksiniz.

PA, PB, PC, PD, PE islemcimizin I/O portlaridir.  Herbirinde 16 tane I/O pini vardir.

Kart uzerinde sozunu ettigimiz ledler PD15, PD14, PD13 ve PD12 pinlerine baglidir.

Ilk deneme programimizi yuklemek icin asagidaki linki tiklayin ve bilgisayariniza yukleyin, RAR'ı patlatıp icinden Discovery klasorunu cikartin. ZIOS.lib Proje dosyalarının içinde mevcut. (ZIOS V1.02)
ZIOS versiyonu değiştiğinde yeni versiyonu gene bu linktden indirebilirsiniz.

http://www.cncdesigner.com/wordpress/wp-content/uploads/Discovery_V1.02.rar

Discovery proje dosyasini cift tiklayip projenin KEIL icinde acilmasini saglayin.

main.c ana programi icerisinde asagidaki satirlari goreceksiniz.

/*   Yanip sonen led  */

#include "Zystem.h"


void delay()
{
volatile int i;
          
    for(i=0;i<10000000;i++);   // 0'dan 10 milyona kadar birer birer say       
}

int main()
{
    while(1)               // Asagidaki komut satirlarini surekli tekrarla
      {
         pinset('D',15);   // GPIOD 15 (D15) pinine bagli mavi ledi yak
         delay();          // Delay rutinine git ve bekle         
         pinclr('D',15);   // GPIOD 15 (D15) pinine bagli mavi ledi sondur
         delay();          // Delay rutinine git ve bekle         
      }              
}


Asagidaki videodan programin derlenmesini, kite yuklenmesini ve kodun calistirilmasini izleyebilirsiniz.

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

z

Yukaridaki ornek icin sorulan ilk sorulardan birisi ledin yanip sonme suresi ile delay parametresi olan 10000000 sayisi arasindaki bagintinin ne oldugu.

Bilmiyorum. Ama kisaca acikliyayim. C derleyici 1 den 10000000'a kadar sayan C satirinin makine kod karsiligini, istenen optimizasyon seviyesini de dikkate alarak uretti. Islemcimiz 168 Mhz hizda kosarken bu sayma islemi bilmem kac saniye zaman aldi.

Programi ilk calistirdigimda parametre 10000 idi. Ledin yanip sonme hizina baktim begenmedim cunku ledin yanip sondugu belli bile olmuyordu. Parametreyi kafadan artirdim eksilttim. En sonunda evet bu iyi oldu deyip 10000000 degerinde biraktim.

Peki hep boyle deneme yanilmayla mi yapacagiz?

Elbette hayir. Bundan sonraki gecikme rutinlerini ilk ornegimizdeki gibi değil asagidaki programdaki gibi yapacagiz.

Ikinci programimiz, kirmizi ledi 100 mili saniye yakip ardindan 900ms boyunca sonuk tutmaktadir.

/*   Yanip sonen led  */

#include "Zystem.h"

volatile short MyDelay;

void BirMiliSaniye() // V1.03 den sonra Milisecond adını aldı
{
    if(MyDelay) MyDelay--;     
}

int main()
{
    while(1)             // Asagidaki komut satirlarini surekli tekrarla
      {
         pinset('D',14);                // GPIOD 14 (D14) pinine bagli kirmizi ledi yak
         MyDelay=100; while(MyDelay);   // MyDelay=100 yap ve bunun sifir olmasini bekle
         pinclr('D',14);                // GPIOD 14 (D14) pinine bagli kirmizi ledi sondur
         MyDelay=900; while(MyDelay);   // MyDelay=900 yap ve bunun sifir olmasini bekle
      }              
}


Bu ornekte sureyi dilediginiz gibi ve oldukca dogru olarak belirleyebilirsiniz.

BirMiliSaniye fonksiyonu ZIOS tarafindan bir mili saniye araliklarla periyodik olarak cagrilir. Dolayisi ile bu rutin icine koyacaginiz minik kod parcalari her bir milisaniyede 1 kez calisacaktir.

Bu fonksiyonun icine zaman alici kodlar koymamalisiniz. Cunku bu bir interrupt fonksiyonudur.

Led ve Delay kullanimi ile ilgili son bir ornek daha yapalim.

Peryodik olarak;

Mavi led 50 ms boyunca yanacak 400ms boyunca sonecektir.
Yesil led ise 30ms boyunca yanacak 600 ms boyunca sonecektir.
Kirmizi led ise 60ms boyunca yanacak 2sn boyunca sonecektir.

/*   Yanip sonen led  */

#include "Zystem.h"

volatile short Tm,Ty,Tk;

void BirMiliSaniye()
{
    Tm++; if(Tm>=450)  Tm=0;
    Ty++; if(Ty>=630)  Ty=0;
    Tk++; if(Tk>=2060) Tk=0;          
}

int main()
{
    Tm=Ty=Tk=0;
          
    while(1)    
      {
         if(Tm<=50) pinset('D',15); else pinclr('D',15);
         if(Ty<=30) pinset('D',12); else pinclr('D',12);
         if(Tk<=60) pinset('D',14); else pinclr('D',14);
      }              
}




mesaj birleştirme:: 29 Aralık 2013, 00:59:13

Peki 1 mili saniyeden daha kucuk surelerde gecikme istersek ne yapacagiz?

100 mikrosaniye ve katlari icin YuzMikroSaniye diye bir fonksiyonumuz daha var.

void YuzMikroSaniye()
{
}


Yukaridaki fonksiyon her yuz mikro saniyede bir kez periyodik olarak cagrilir. Bu da, BirMiliSaniye gibi bir interrupt fonksiyonudur ve icinde zaman alici kodlar calistirmamalisiniz.

BirMiliSaniye ve YuzMikroSaniye fonksiyonlarin doğruluğu üzerine önemli bir uyarı da bulunmam gerekli.

Gelisiguzel bir zamanda bu fonksiyonlari cagirirsaniz;

Bu fonksiyonda degeri bir eksiltilen degiskene ornegin 1 yuklemis olalim. Bu andan itibaren interrupt olusuncaya kadar gecen sure degiskene ne zaman 1 yuklediginizle alakalidir.

1MiliSaniyeFonksiyonu icin konusursak;

Değişkene değer yukledikten hemen sonra Değişken bir eksiltilebilecegi gibi 1ms sonra da eksiltilebilir.

Bu belirsizlikten dolayi gercekten 1ms referans zamana ihtiyaciniz varsa degiskene 1 yukleyip bekleyin. Sifir oldugunda bu sizin 0 ms aninizdir. Tekrar degiskene 1 degeri yukleyin. Degisken 0 oldugunda tam 1 ms zaman gecmis demektir.

Birden cok degisken interrupt rutininde 1 eksiltilmek istenebilir. Bu nedenle degiskene deger yuklendigi anda timeri da sifirlama yoluna gitmedim.

Gelişigüzel bir zamanda  Delay değişkeninize örneğin 10 değeri yüklediyseniz elde edeceğiniz gecikme 9..10ms aralığında olacaktir. (-1...0) ms hatanız olacaktr.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Yukaridaki mesajlardan birisinde PA,PB,PC,PD gibi GPIO (General Purpose Input Output) portlardan dan bahsettik.

Bu GPIO portlar sadece 1-0 seklinde bilgi cikmaya yaramaz. Dis dunyadaki 1-0 tipindeki voltaj bilgilerini okumak icin de bu portlardan yararlaniriz.

Cip dokumanlarinda bu GPIO girislerinin pek cogunun 5 volta dayanikli oldugu soylense de siz girislere negatif voltaj ve 3 voltdan buyuk voltaj uygulamamaya ozen gosterin.

Zira GPIO pinleri sadece kartin kenarina dizilmis pinlere gitmemekte, bazilari kart uzerindeki yardimci ciplere de baglidir.

ZIOS kutuphanesi 4 adet ledin bagli oldugu GPIOD de PD15...PD6 arasindaki tum pinleri cikis moduna ayarlar.

PD15, PD14, PD13 ve PD12 ledlere baglidir. PD11, PD10, PD9, PD8, PD7 ve PD6 ise ileride kitimize baglayacagimiz 2x16 LCD display icin ayrilmistir.
Ben LCD'mi bu bacaklara baglamak istemiyorum ben baska bacaklara baglayacagim derseniz ZIOS size yardimci olmaz.

PA5, PA6, PA7, PE7  pinleri MEMS çipi için alıkonulmuştur. SD kart için ise PC12, PC11i PC10 ve PD0 pinleri de SD kart okuyucu için ayrılmıştır.

Bunlarin disinda kalan pinleri kendi ozel amaclarimiz icin kullanabiliriz. Gene de bu asamada keyfi pinlerle calismayip derslerimizde kullandigimiz pinlerle calisin. Zira daha once de dedigim gibi GPIO pinlerinin pek cogu kart uzerindeki ciplere baglidir. Bu ciplere 1/0 tipi bilgiler uygulamak sorun yasatabilir. Ciplerin cikisina zit seviyede voltaj verme durumumuz varmi bunu ilk firsatta arastiracagim. (Kendime Odev)

Dis dunyadan 1/0 tipi bilgi okumak.

Bu amacla hic kablo vs baglantisi yapmadan kart uzerindeki hazir mavi butonun uretecegi 1/0 bilgisini okuyup butona basildi ise mavi ledi yakan, basili değilken mavi ledi sonduren programi yazalim.

Mavi buton GPIOA nin 0 nolu pinine (PA0'a) baglidir. Butona basildiginda PA0=1, basilmadiginda PA0=0 olmaktadir. ZIOS kutuphanesi PA0 pinini output olarak değil input olarak tanimlamistir. Dolayisi ile bizim bu pin icin herhangi bir init islemi yapmamiza gerek kalmamaktadir.


#include "Zystem.h"

int main()
{
    while(1)    
      {
         // Mavi butona bastiginiz surece mavi led yanar  
         // Bir baska ifadeyle GPIOA 0 pini 1 ise mavi led yanar                
         if(pininp('A',0)==1) pinset('D',15); else pinclr('D',15); 
      }              
}


mesaj birleştirme:: 29 Aralık 2013, 03:45:22

pinset, pinclr ve pininp fonksiyonlarinin her birisi hata dondurme yetenegine sahiptir.

Hata degeri 2 olarak geri donulduyse olmayan bir GPIO dan yada olmayan bir pin numarasindan bahsediyoruz demektir.

pinset('J',0) yada pinclr('A',20) 2 hatasi ile geri donuse neden olur.

Yukaridaki program PA0 pinini input olarak kullaniyordu. Simdi de PC7 pininden 1/0 bilgisi girelim. Fakat bu kez parmak yalayacağız.

#include "Zystem.h"

int main()
{
    while(1)    
      {
         // GPIOC 7 pini 1 ise mavi led yanar                
         if(pininp('C',7)==1) pinset('D',15); else pinclr('D',15); 
      }              
}


Programi derleyip calistirin. Baş ve işaret parmağınızı yalayın. Başparmağınızı PC7 pinine, işaret parmağınızı da 3v pinine dokundurun.
Ya da parmaklarınıza toplu iğne vs ince bir metal alıp PC7 pinine dokunun. İlginç değil mi?

C bilmiyor ve yazılarımı öylesine okuyorsanız size bir trick vereyim.

C dili ozellikle de ZIOS fonksiyonlari kitap okunur gibi okunur.

Örneğin aşağıdaki komut satırını okuyalım ve Türkçeye çevirelim.

if(pininp('C',7)==1) pinset('D',15); else pinclr('D',15);

Eger, PC7 pin girisi 1 ise D15 pinini set et. değilse D15 pinini sil.


Bakın C ne kadar kolaymış değil mi? Bence sizler de takip edin C yi kavrayacaksınız.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Herhangi bir GPIO pininin giris/cikis tanimini yapmak.

ZIOS cikis amacli kullanacagi pinleri (alıkonan pinler) zaten cikis olarak tanimlamaktadir. Alikonmamis tum diger pinler input olarak tanimlidir.

Bu dersimizde input tanimli bir pini output tipine cevirmeyi, yada tersine output tanimli pini input tipine cevirmeyi gorecegiz.

Bu arada yeri gelmisken onemli bir uyari yapacagim.

PA14, PA13 ve PB3 pinlerine, pinset yada pinclr ile mudahale etmeyin yada simdi anlatacagim pinmod fonksiyonu ile tanım yapmayın.
Bu pinler islemciye program yuklemeye yarayan ozel pinlerdir. Bu pinlere müdahale yaptığinız takdirde kartınıza bir daha program yükleyemeyebilirsiniz. (Kurtarma işlemi gerekir)

Şimdi pinmod komutunu göstereceğim. Artık Discovery kitimize bir seyler bağlamanın vakti geldi. Pinlerden birisine ilave LED baglayalım.Fakat daha önce havya nasıl kullanılır, lehim nasıl yapılır onu göstermem gerekecek.

http://youtu.be/s-KhwVNLD5k

Havya kullanımını artik bildiğimize göre bir de LED den bahsedeyim. Discovery kitimizin GPIOC7 pinine led nasıl bağlanır onu da videoda göstereyim.

(Anlayış gösterin, bu dersler PC programcılarına yönelik. Bu arkadaşlar belki de bugüne kadar ellerine hiç havya, lehim teli, led, direnç almadılar.)

Video çekimleri gerçekten bilgi ve tecrübe istiyor. Ortamın aydınlatılması yanısıra çekim yapan kişinin ne zaman zoom yapacağı ne zaman uzak çekim yapacaği ortaya çikan işin kalitesi açısindan çok önemli.

Yardımcı olmaları için hanımdan (kendi hanımımdan) yada oğlumdan destek alıyorum ve kavga gürültü kopuyor. Kimse benim videomu çekmek istemiyor. Cünkü sonuç kötü olunca kızıyor köpürüyorum çekimi tekrar yapıyoruz. Bu sefer evde yardımcı olacak kimse yoktu ve mikroskop kamera ile tek başıma video çektim. Ortaya hiç de iyi bir sonuç çıkmadı.

Kusuruma bakmayın.

PC7 Led

Videoda renkleri görünüyor olsa da belirtmeyi unutmuşum, kullandığım 220 ohm değerindeki direncin renkleri kirmizi kirmizi kahverengi.

Elinizde farkli renklerde dirençler varken hangisinin 220 ohm olduğunu bu renklerden tanıyacaksınız. Hemen belirteyim ki 220 ohm yerine 330 ohm da kullanabilirsiniz. Bu durumda ışığın parlaklığı biraz düşebilir.

Videodaki kadar uğraşa ne gerek var, lede direnci baglarım sonra voltaj verip hangi ucun + hangi ucun - olduğunu tespit ederim de diyebilirsiniz tabiki...
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

PC7 pinini output tanımlamak ve bu pine bağladığımız ledi yakip sondürmek.


#include "Zystem.h"

volatile short T;

void BirMiliSaniye() // V1.03 den sonra Milisecond adını aldı
{
   if(T) T--;          
}

int main()
{
    pinmod('C',7,output); // PC7 Pini artik cikis oldu.
          
    while(1)    
      {
         pinset('C',7);
         T=50; while(T);       
         pinclr('C',7);
         T=950; while(T);       
      }              
}


PC7 Yanıp sönen led
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Artik Discovery kitimizde her hangi bir pini nasil output nasil input tanimlayabilecegimizi, bir pinden nasil 1/0 bilgisi çıkartabileceğimizi yada bir pindeki 1/o bilgisini nasil okuyabilecegimizi biliyoruz.

Şimdi ogrendiklerimizi pekiştirmek adına  ses uygulamasi yapalim. Bunun için 100nF lik bir kondansator ve bilgisayarlara baglanan amplifikatorlu hoparlore ihtiyacımız olacak.

Discovery ses uygulaması

Ses efekti uygulaması

#include "Zystem.h"

short YariPeryod;

void YuzMikroSaniye() // V1.03 den sonra Microsecond adını aldı
{
   if(YariPeryod) YariPeryod--; 
}

void Duduk(short Peryod, short Tekrar)
{
short n;
          
    for(n=0;n<Tekrar;n++)
      {        
        pinset('C',7); YariPeryod=Peryod>>1; while(YariPeryod && pininp('A',0)); 
        pinclr('C',7); YariPeryod=Peryod>>1; while(YariPeryod && pininp('A',0));
      }
}

int main()
{
short T=0;
          
    pinmod('C',7,output);
    
    while(1) 
      {
         while(!pininp('A',0)); // Mavi buton basili değilse beklemede kal
         while(T<20){Duduk(T,T & 7); T++;}
         while(T)   {Duduk(T,T & 7); T--;}                  
      }              
}
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

getch komutu ile mavi butonlu klavyeyi okumak

// getch komutu
 
#include "Zystem.h"

#define Mavi 15
#define Yesil 12
#define Kirmizi 14

int main()
{
char Tus=0;
          
    while(1) 
      {
         switch(getch()) 
           {
              case 0: {break;}         // Tanimsiz       
              case 1: {Tus^=1; break;} // Tek  Tik
              case 2: {Tus^=2; break;} // Cift Tik
              case 3: {Tus^=4; break;} // Uzun sureli Tik
           }
         if(Tus&1) pinset('D',Mavi);    else pinclr('D',Mavi); 
         if(Tus&2) pinset('D',Kirmizi); else pinclr('D',Kirmizi); 
         if(Tus&4) pinset('D',Yesil);   else pinclr('D',Yesil); 
      }              
}

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

z

Discovery kitimize 2x16 LCD display bağlamak.

2x16 LCD dedigimiz malzeme, iki satir 16 sutunda,  alfanumerik karakterleri gosteren aşagidaki gibi bir malzeme.

Bunun mavi olani, yesil orani, sari olani, arkadan aydinlatmasi olani olmayani var.



Sifirdan montaji anlatan video cekmek cok zamanimi alacak. Bunun yerine baglanti semasini verecegim.



Satın aldığınız LCD yukarıdakinden daha farklı ise bağlantıları yukarıdaki gibi yapmadan önce "LCD"nizin fotoğrafını çekip yada linkini verip bacak bağlantısı için forum üyelerinin fikrini alınız.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

LCD displayde istenen satır ve sütunda mesaj vermek, değişken değerini göstermek, ekranı silmek.

Lcd ekran

#include "Zystem.h"
#include "stdio.h"

char kbhit()
{
     return(pininp('A',0));     
}

int main()
{
int i;
char s[17];          
          
    while(1) 
      {
         if(kbhit()) display(0,0,"Parmagini ceksen");
         while(kbhit());       
                
         display(0,0,"Merhaba Dunyali");
         display(0,1,"Mavi tusa bas");

         getch(); // Mavi tusa basilmasini bekle;
         cls();   // Ekrani temizle
                
         for(i=1500;i>=0;i--)
           {
             sprintf(s,"Sayac:%d",i);        
             display(0,0,&s[0]);        
           }                     
           
         display(0,0,"Hoslandin mi?"); 
         getch();  
      }              
}
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

ZIOS ile GPIOA1 pininden gürültüsüz patırtısız ADC dönüşümü yapma

Bu uygulamayı yapmak icin "ZIOS"un yeni versiyonununun indirilmesi gerekiyor.

ADC dönüşümü yapmak için herhangi bir komut işletmeye gerek yok. 1ms aralıklarla update edilen short tanımlı Analog değişkenini okumanız yeterli.

Ayarlı voltaj için trimpot denen malzemeden yararlandim. Bu malzeme ayarli bir direnç olup değeri, vidasının  döndürülmesiyle değiştirilir.

Trimpotun en dıştaki bacaklarından birisine GND, diğerisine de + 3v bağladiğımızda orta bacaktan değeri değiştirilebilen voltaj elde ederiz. Orta bacak PA1 pinine bağlanmıştır.
Bu uygulamada 100K değerinde trimpot kullanılmıştır. 10K, 22K, 47K gibi değerleri de kullanabilirsiniz.



#include "Zystem.h"
#include "stdio.h"
#include "string.h"

short T;
float V;

void BirMiliSaniye() // V1.03 den sonra Milisecond adını aldı
{
    if(T) T--;                
}

int main()
{
char s[17];          
          
/*  ver komutu ZIOS versionunu getirir. (V1.01)
    Program derlenmiyorsa yeni ZIOS'u indirmeniz gerekir.*/

    while(1) 
      {
         T=250; while(T);                   // Her 250 mili saniyede ADC sonucunu stringe cevir
         V=(float)Analog*3/4095;           
         sprintf(s,"V = %1.3f volt",V);     
         display(0,0,&s[0]); 
         if(!strcmp(s,"V = 2.014 volt")) display(0,1,"MUTLU YILLAR"); 
         else display(0,1,"");       
      }              
}


ZIOS ile ADC uygulaması

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

z

#11
Analog sinyal üretmek

Analog sinyaller digital sinyaliller gibi sadece 0-1 degerlerinden olusmaz.
Örnekteki program PA4 pininde 0...3 volt araliginda 3/4096 adimlarla trapez dalga formunda voltaj üretir.

DAC

// PA4 pininde 3v genlikte Trapez dalga uretir

#include "Zystem.h"


int main()
{
short a;
         
/*  ver komutu ZIOS versionunu getirir. (V1.01)
    Program derlenmiyorsa yeni ZIOS'u indirmeniz gerekir.*/
          
    ver();          
              
    while(1) 
      {
        for(a=0;a<4096;a++) dac(a);     // Yokus Cik
        for(a=0;a<4096;a++) dac(4095);  // Duz git    
        for(a=4095;a>=0;a--)dac(a);     // Yokus in
        for(a=0;a<4096;a++) dac(0);     // Duz git 
      }              
}

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

z

#12
otomobiller için emniyet kemeri uyarısi.

DAC sayesinde analog sinyaller uretmeyi ogrenmistik. Bu kez ding sesi uretecegiz.

Emniyet kemeri uyarisi

// PA4 pinine amplifikator baglayin

#include "Zystem.h"

volatile int T,T1;

int main()
{
short a,a0,a1,a2;
         
/*  ver komutu ZIOS versiyonunu dondurur.
    Program derlenmiyorsa yeni ZIOS'u indirmeniz gerekir.*/
          
    ver();          
    
    while(1) 
      {
        while(!pininp('A',0))
          {                  
            a0=720; a1=0; a2=32767;          
            for(T=0;T<80000;T++)
              {        
                for(T1=0;T1<100;T1++);
                a=((((a0*32734))>>14) - a1); a1=a0; a0=a;
                a2=(a2*32767)>>15;       
                a=(a*a2)>>15;       
                dac((a>>3)+2048);  
              }
          }    
      }              
}


Daha önceki hoparlor bağlantısını PC7 pininden yapmıştık. Bu kez PA4 pininden bağlantı yapacağız.

Jack uçlarına kablo bağlantısı yapmayla ilgili videoyu bir kez daha veriyorum.

http://www.youtube.com/watch?v=l51R6myCzGY#ws
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

#13
ZIOS ile USART uygulaması (Asenkron Seri Data alıp verme)

PB10 Tx pini
PB11 Rx pini


Bu amaçla 2 komutumuz var.

serinit(int BaudRate);
sersend(char Data);

Seri portun stop biti yok 1 olsun yok 2 olsun, yok parity odd olsun even olsun süsü püsü ile ugrasmadim. (İhtiyaç olduğunu da sanmıyorum.)

8 data bit, 1 stop bit, non parity kullanıyor. Baud rate'i dilediginiz gibi verebilirsiniz.

Ornegin 9600 baud icin serinit(9600), 1000 baud icin serinit(1000) gibi.

serinit komutu ardindan seri port iletişime hazır olur.

sersend komutuyla  8 bitlik deger yollayabilirsiniz.

Ornegin 0x17 yollamak icin sersend(0x17);

Peki gelen veriler hangi komut ile okunacak?

Bunun için komut kullanmıyoruz. Seri portdan bir data gelirse okunuyor ve dogrudan SerDataReady() fonksiyonu cağrılıyor.

Siz bu rutin içinde datanızı doğrudan kullanıyorsunuz.

Aşağıdaki ornekte gelen data geri yollanıyor. SerDataReady rutininde 16 derinlikli dairesel bir buffer (FIFO) kullandım. Siz bunu ister 1 byte yapın ister 1Kbyte.
Veriler gelirken siz bambaşka bir döngüde dahi kalsanız circular buffer kendi kendini ezmediği sürece orada oyalanabilirsiniz.

SerDataReady bir interrupt fonksiyonudur ve bu rutin içinde zaman alıcı işler yapmamalısınız.

#include "Zystem.h"

char i, RxBuf[16];


void SerDataReady(char RxData)
{
     RxBuf[i]=RxData;
     i++; i&=0x0F;       // Dairesel buffer                 
}
 

int main()
{
char j;
          
      ver();            // ZIOS versiyon kontrolu
          
      serinit(9600);    // 9600 baud, 8 data, 1 stop, no parity
          
      i=0; j=0;
          
      while(1)
        {
           while(i==j);          // Data gelinceye kadar bekle  
           sersend(RxBuf[j]);    // Gelen datayi geri yolla
           j++;  j&=0x0F;
        }
}
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

#14
MEMS çipi okuma komutu

#include "STM32F4xx.h" 
#include "Zystem.h"
#include "string.h"
#include "stdio.h"
 
int main() 
{ 
char s[17];          

   if(ver()<0x102)
    {
      display(0,0,"ZIOS-1.02 gerekli");   
      while(1); // ZIOS 1.02 yuklu değil             
    }       
          
   while(1)
     {   
       mems();               

       sprintf(s,"X:%3d",_X);
       display(0,0,&s[0]);  
               
       sprintf(s,"Y:%3d",_Y);
       display(0,1,&s[0]);       
     }
}


MEMS

MEMS çipini okumayla ilgili bir problem olduğunu düşünüyorum ancak sorunu bulamadım.
Videodan da goreceğiniz gibi kart masaya paralel iken X ve Y degerleri yaklaşık 0 iken, kartta +/- 90 derecelik aci değişimi yapilirsa MEM cipinden okunan register değerleri  0..+/- 50 civarinda oluyor.

Bu degerlerin +/- 127 civarında olması gerekmez mi?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com