7 Ocak 2017 Cumartesi

RTOS (REAL TIME OPERATING SYSTEM)


RTOS (REAL TIME OPERATING SYSTEM)

Mikrodenetleyiciler, aynı anda bir komut satırını işletebilen entegrelerdir.

 Yukarıda sonuz döngü içine giren mikrodenetleyici ilk olarak birinci komut satırını işler sonra ikinci komutu daha sonra üçüncü komutu işler. Yani işleri sırayla yapar.


Örneğin; ardiuno’da loop fonksiyonun içine iki adet sonsuz döngü yerleştirelim. Mikrodenetleyici ilk sonuz döngüye girdiğinde oranın içindeki komutlaru sırayala işler fakat ikinci sonuz döngüye birinci döngüden çıkamadığı için oradaki görevleri işletemez.  

RTOS, mikrodenetleyicilerin içine gömülen bir işletim sistemidir aynı windows, linux gibi. RTOS’un en önemli özelliği görevleri parelelmiş gibi yapma yeteneği olmasıdır, bu özelliğiyle FPGA benzetebiliriz. Örneğin, Bilgisayarda müzik dinliyorsunuz spotify’de bir yandada internette gazete okuyorsunuz. Bilgisayarda bu işler parlelmiş gibi yapılıyor. İnternette gezereken internet sayfanız donsa bile veya internet sayfanız geç açılsa bile arka tarafta siz şarkınızı gayet akıcı bir şekilde dinliyor olacaksınız. Bu iki görevi yani yazılımda sanki iki farklı while sonsuz döngüsünde olduğunu düşünün. Yani bilgisayar iki farklı sonuz döngüyü aynı anda çalıştırıyor. Aynı bu yapıyı mikrodenetleyicilerdede RTOS sayesinde yaptırabilirz.

RTOS, sayesinde iki veya daha fazla sonsuz döngüyü aynı anda çalıştırabiliriz.




Yukarıdaki resimde RTOS ile çalışan iki farklı sonsuz döngü içersinden alınan iki sinyal görülmektedir.

Birinci sinyal sdkart’a data yazma zamanını, ikinci sinyalde her 6 ms’da ekg devremizden örnekleme aldığımızı düşünelim. Burada yapılan iş 6 ms örnekleme alıp onu sd kart’a yazmak fakat bunu RTOS’suz yaparsak 1.sinyalde A1’den A2’ye kadar lojik bir seviye olmuştur. Yani, sd karta yazma işi uzun sürmüş yaklaşık  60 ms. RTOS’suz yaptığımız düşünürsek 60 ms’de biz 6 adet ekg verisini kaybetmiş oluruz çünkü tek bir sonuz döngü içinde olacak önce ekg datasını okucayacak sonra onu sd kart’a kaydedecek. Kaydetme işi uzun olduğundan okuma yapıyacak ve bu durumda datalar eksik yazılacaktır.

Fakat bunu RTOS kullanarak yaparsak bu başımıza gelmeyecek. İkinci sinyalde de bu görülmektedir. A1 ve A2 süresi uzun sürse bile biz örnekleme alacağız yani datalarımız kaybolamayacak.  Burada iki farklı sonsuz döngü olacak. Birinci döngüde sd karta yazacak, ikinci döngüde örnekleme alacağız kesintisiz.     

6 Ocak 2017 Cuma

Köprü Tipi Doğrultucu Tasarımı

Köprü Tipi Doğrultucu Tasarımı


Merhabalar, bu yazımda sizlere köprü tipi doğrultucu devre tasarımı yapacağım PSPICE programını kullanarak. 
 


 Bu devre tasarımındaki amacım ilk olarak verilen devre şemasını Pspice programında simüle etmek ve daha sonra çıkış gerilimini 10V'a zener diyot kullanarak sabitlemek.


1.adım
İlk olarak devremiz için Pspice kodunu yazalım;

VS    1 0  SIN 0 20 50
Rzout 1 2  50
DR1   2 4  D1N4002
DR2   0 4  D1N4002
DR3   3 0  D1N4002
DR4   3 2  D1N4002
RL    4 3  4k
CL    4 3  10u
.model D1N4002 D (IS=14.11E-9 N=1.984 RS=33.89E-3 IKF=94.81 XTI=3 EG=1.110
+ CJO=51.17E-12 M=0.2762 VJ=0.3905 FC=0.5 ISR= 100.0E-12 NR=2 BV=100.1 IBV=10 TT=4.761E-6)
.tran 1u 80ms 0 0.1ms
.PROBE

.END

2.Adım
Simülasyon sonuçlarımızı gösterelim;


Yukarıdaki resimde kahve rengi ile çizilen sinyal giriş sinyalimiz, yeşil sinyalimiz ise çıkışımızdır. Görüldüğü gibi sinüzoidal giriş sinyalimizi ortalama gerilimi 0V'dan yukarı çıkardık.

3.Adım
Devre çıkışını 10V'a çekmek için zener diyotlu devremizi kuralım daha sonra simüle edelim.





















Yukarıdaki kahve rengi sinyalimizde görüldüğü gibi çıkışı 10V'a zener diyotlu devremiz sayesinde sabitledik.


5 Ocak 2017 Perşembe

FPGA ile Yapay Sinir Ağı Tasarımı


FPGA İLE  BASİT NÖRON TASARIMI




Bu yazımda,  bu dönem Yıldız Teknik Üniversitesi Elektronik ABD Doç. Dr. Burcu ERKMEN hocamın vermiş olduğu programlanabilir lojik devre tasarımda dersinde Mehmet Özgen Özdoğan arkadaşımla beraber almış olduğumuz FPGA'de basit bir nöron tasarımı projemizi anlatacağım. 

Öncelikle bu projemizde emeği geçen değerli hocamız Doç. Dr. Burcu ERKMEN ve Arş. Gör. Ali Rıza YILMAZ hocamıza ve aynı zamanda proje arkadaşım Mehmet'e emeğinden verdiği emekten dolayı teşekkür ederim. 

Bu proje sayesinde yapay sinir ağı hakkında daha önce bilmediğim bilgileri bu proje sayesinde hem öğrenmiş hemde fpga gibi zor bir platformda nasıl uygulanacağı hakkında bilgilere sahip oldum. 

Bu projemizde ISE Design Suite 14.7 programını ve Xilinx Spartan 3E eğitim kitini kullandık ve sonuçları kit üzerindeki LCD ekran üstünde hexadecimal sayı olarak görüntüledik.

Yapay Sinir Ağı Nedir ?

Kısaca, yapay sinir ağı insanın beynini taklit eder. Burada hücreyi modeleyerek tasarım yapılıyor. 






Yandaki resimde hücre yapısı görülmektedir. İşte bu hücre yapısı modellenerek YSA oluşturulmuştur.  Burada dendritlere gelen bilgiler hücre gövdesi içersinde değerlendirilerek bir çıkış elde edilir ve o çıkış akson boyunca akson çıkış uçlarına yönlendirilir ve oradan diğer hücrelerin dendritlerine gider. 




Yapay sinir hücreleri biyolojik sinir hücrelerine benzer yapıdadır. Yapay nöronlar aralarında bağ kurarak yapay sinir ağlarını oluştururlar. Aynı biyolojik nöronlarda olduğu gibi yapay nöronların da giriş sinyallerini aldıkları, bu sinyalleri toplayıp işledikleri ve çıktıları ilettikleri bölümleri bulunmaktadır.

Bir yapay sinir hücresi beş bölümden oluşmaktadır;
  • ·         Girdiler
  • ·         Ağırlıklar
  • ·         Toplama Fonksiyonu (Birleştirme Fonksiyonu)
  • ·         Aktivasyon fonksiyonu
  •             Çıktılar 




Giriş ve ağırlık değerleri ondalıklı sayılarda işlem yapacağımız için IEEE 754 standardına göre 32 Bit FloatingNumber yapılarak işlemler bu şekilde ilerledi. FPGA donanımı üzerinde ondalıklı sayılarla işlem yapamadığımız için bu yönteme başvurduk. IPCORE ile fl_carpma ve fl_toplama blokları oluşturduk. Bu blokları 32 Bit tasarladık. Bu sayede giriş değerleri ile ondalıklı olabilecek ağırlıkları ile çarpıp sonunda toplama işlemini yaptırmış olduk. Ağırlıklarını ise W1,W2,W3,W4 sırasıyla 0.5, -0.7, -0.5, 0.32 ayarladık.






Bu ağırlıklar ile çarpım ve toplamlardan sonra elde edilen değeri ise transfer fonksiyonundan geçirmek gerekmekteydi. Burada Sigmoid Fonksiyonu kullandık. Bu sigmoid fonksiyonu 16 bit olduğundan ve 32 bit elde ettiğimiz sonucu kafamıza göre bölemezdik. Çünkü bu kodlama mantığında ilk bit işaret biti sonrasındaki eksponansiyel ağırlıkları ve sonrasında sayı bulunan bir sistemdi. Bu yüzden yine Xilinx ISE Design Studio içerisindeki IPCORE yardımıyla 32 Bit’ten 16 Bit’e düşüren floatingpoint – floatingpoint çevirici ve ardından çıkan sonucu tekrar 32 bit görebilmek için 16 Bit’ten 32 Bit’e çeviren modül tasarladık. Toplama çarpma işlemlerinin 32 Bit sonucu 16 bit sonuca düşürüldü ve ardından sigmoid fonksiyonundan geçirildi. Ardından 16 bit çıkış tekrar 32 Bit’e dönüştüren blok sayesinde 32 Bit yapılarak çıkışa atandı.





Sigmoid fonksiyonu  yaklaşımındaki 16 bit değerlerinin ayrıca sigmoid_rom.vhd bloğunda tutularak ilgili durumlarda adreslere göre değerlerin çekilmesi üzerine oluşturulmuştur.




Bu projenin Spartan 3E 1600E kartına atılıp ve kartın üzerindeki LCD 16x2 ekranında görünmesi için elde ettiğimiz bu 32 Bit sayıyı dörderli gruplara ayırrdık. LCD ekranda HEX değeri okumak için böyle bir işlem uyguladık. 0000 1111 0000 1000 0001 … 32 Bit uzunluktaki sayıyı ekranda okuması zor olacağından HEX değeri yapılarak sonuca gittik. 0x0F081… ekranda yazması daha kolaylık sağlayacaktır. Burada karttaki programın çıkışını LCD’de görmemiz için gerekli komutları ana_modul.ucf dosyası içine tanımladık. Girişleri 4 switch üzerine atadık. Reset için buton kullandık. Ayrıca saat girişi olarak 50 MHz kart üzerindeki clock aktif edildi.




Bu projemizde 4 adet giriş butonu ile giriş değerleri değiştirilmiştir. Bu giriş değerleri kendi katsayıları ile çarpılarak daha sonra aktivasyon fonksiyonunda geçirilmiş ve sonuç LCD'de gösterilmiştir.  





Bu projede sayede ileri yayılım algoritmasını kullandık, geri yayılım algoritmasını fpga üzrinde deneyemedik proje zamanımızın 2 hafta olmasından dolayı. 

Geri yayılım algoritmasının amacı; biz önce sisteme rastgele  W1,W2,W3 ve W4 katsayılarını veriyoruz sonra ileri yayılım algoritması ile çarpma daha sonra toplama ve sonra aktivasyon fonksiyonundan geçirdikten sonra bir çıkış elde ediyoruz. Bu çıkış değeri beklenen değerden farklıdır yani çıkışta hata vardır. Bu hata değeri geri yayılım algoritmasını kullanarak W1,W2,W3 ve W4 otomatik olarak tekrar güncellenir. Bu güncellemeyi sistem kendi kendine yapar. Yani sistem öğrenme durumuna gelir. Bu işlem sistem öğrenene kadar devam eder.  İşte insan beynine benzetilmesinin nedeni de budur. Yani sistem kendi kendini eğite biliyor olmasıdır. 


Sonuçlar



Tüm girişlere lojik 1  değeri verdiğimizde simülasyon sonucu ;



Uygulama sonucu;




   

Kaynaklar 

1.  http://www.ibrahimbayraktar.net/2013/11/sinir-sisteminin-yaps-ve-islevleri.html 
2.  http://mehmetozgenozdogan.blogspot.com.tr/
3. https://www.quora.com/What-is-the-sigmoid-function-and-what-is-its-use-in-machine-learnings-neural-networks
4.http://www.aliosmangokcan.com/index.php/makaleler/46-ysa-ile-xor-uygulamasi
5.http://bilgisayarkavramlari.sadievrenseker.com/2008/10/05/ozel-veya-problemi-xor-problem-exclusive-or/
6.http://www.idt.mdh.se/utbildning/exjobb/files/TR0825.pdf
7.http://www.ijser.org/paper/A-Survey-on-FPGA-based-MLP-Realization-for-On-chip-Learning.html
8.http://www.emo.org.tr/ekler/b8a21b630fcd49a_ek.pdf
9.http://ethesis.nitrkl.ac.in/4217/1/FPGA_implementation_of_artificial_neural_networks.pdf
10.http://www.alicavuslu.gen.tr/wp-content/uploads/2014/02/tez.pdf
11.http://blog.aliekberyacin.net/?p=305#prettyPhoto
12.http://trace.tennessee.edu/cgi/viewcontent.cgi?article=3725&context=utk_gradthes
13.http://web.itu.edu.tr/ayhant/dersler/ysa/dn/ozden.pdf


23 Aralık 2016 Cuma

Pspice Programını Kullanarak Zener Diyot Simülasyonu



Merhabalar, uzun zamandır ders ve parttime olarak çalıştığımdan dolayı çok meşguldüm o yüzde pek fazla bloğuma vakit ayıramamıştım. Bu yazımda sizlere pspice programını kullanarak simülasyonun nasıl yapılacağını anlatacağım.


  • Pspice programı ile şematik çizim yerine devreyi kodlayarak simülasyon yaptırıyoruz.

  • Örneğin;15 Voltluk bir gerilim kaynağını, VS    1 0  DC 15 olarak yazıyoruz.Burada; VS  kaynak adıdır. Bu isim Vin de olabilirdi fark etmez. 1 'in anlamı Vs nin yanıdaki ilk düğüm noktam, onun yanındaki 0 ise ikinci düğüm noktam. Yani kaynak adından sonra kaynağımın bağlanacağı düğüm noktalarını yazıyoruz. Daha sonra DC nin anlamı bu bir dc kaynak olacak ve gerilimi 15V olacaktır.

  •  Bir AC kaynak yazmak istersek bunu kullancağız; VS   1 0  SIN 0 20V 50Hz.
  • Şimdi pspice'da bir zener diyot tasarım örneği yapalım.


  • Tasarım parametrelerimiz şunlardır; Vdc=15V, V2=10V'tur. Yani 15V'tan 10V'adüşüreceğiz. R2=10k, ve onun üstünden geçmesi gereken akım 1mA olarak istenmektedir. 
  • İlk olarak bu iş gerekli olan zener diyot'u bulalım. 




  • Yukarıdaki tabloda da görüleceği üzerine bizim kullanmamız gereken zener 1n4740'tır. 10V gerilim elde etmemiz için  zener diyot üzerinden 25mA geçmesi gerektiğini bize söylüyor. Bizde tasarımımız yaparken bu değeri göz önünde bulunduracağız. 
  • R1 direncini bulalım. R1=(V1-VZ)/IR1'dir.  IR1=IR2+IZ=1mA+25mA=26mA'dir. 
  • R1=192 ohm 'dur. 
  • Pspice kodumuzu yazalım;

Pspice Kodu



  • Sonuçlar
Vout 


Iz



Kaynaklar
1.www.diodes.com/downloads/10295, 1N4728A - 1N4761A - Diodes Incorporated
2. http://espice.ugr.es/espice/src/modelos_subckt/spice_complete/cadlab.lib








26 Temmuz 2015 Pazar

74HC595 Kullanımı






74 HC 595 entegresi piyasada çok sık kullanılan entegrelerden biridir.  Bu entegre seri olarak girilen verinin veya datanın paralele dönüştürmesini sağlar. [1]  Bu entegre, 8-bit seri giriş, paralel çıkış ve 8-bit D tipi flip-floba (latch) sahiptir. Bu entegre 8-bit seri olarak verdiğimiz dataları içinde depolar sonra  onları biz istediğimiz zaman parelele dönüştürür. Yani 75HC595 entegresinin DS pinine bir mikrodenetleyici tarafından 8-bit veri gönderilir ve sonra onlar Q1’den Q7 kadar o seri bit çıkışta gösterilir.  Tabi bunlar benim böyle anlattığım gibi direk olmuyor. Bazı kurallar var onlara göre yapmak gerekir. 




Özellikleri:

  •   İşlem yapması için gerekli çalışma gerilimi minimum 2V, maksimum 6V olamalıdır.

  •    Maksimum çekeceği akım bu entegrenin 80 uA’dir.

  •   Kaskad bağlama özelliğine sahiptir. 74HC595’in 9.pini yardımıyla bir başka 74HC595 ile kaskad bağlanabilir.

  •   Kaydırma frekansı 100Mhz.
 
 



 
Yukarıda 74HC595 hakkında pin açıklamaları verilmiştir. Gayet açık bir şekilde her bir pinin ne işe yaradığını belirtiyor tablo. Bizimyapmamız gereken şey, DS pinine seri olarak datalarımızı göndermek ama bunu yaparken her data için bir clock gerekiyor. Clock SH_CP pinine uygulanır. Her yükselen kenar clock’unda  seri olarak gönderdiğimiz datalar 74HC595 kabul eder. Sonra 8-bit data seri olarak gönderildikten sonra ST_CP lojik 1 durumuna çıkarılır çıkışlar gönderdiğimiz datalara göre aktif olur. Şunu unutmamız gerekir, datalar seri olarak gönderilmeye başladığında ST_CP lojik 0, dataların hepsi gönderildikten sonra lojik 1 yapılır.
 
Bu entegrenin kullanım amaçları şunlar; Kullandığınız mikrodenetliyice pin sıkıntısı sorunu varsa siz bu entegreyi kullanarak o sorunu çözebilirsiniz. Yani, mikrodenetleyicinizin minimum üç pini kullaranak  siz  74HC595 yardımıyla 8 pine çıkarabilirsiniz. Mikrodenetleyicilerde satır LCD ekran sürmek için çok fazla pine ihtiyaç vardır ama bu entegre yardımıyla  satır LCD ekran sürebilirsiniz. Led uygulamalarında kullanılabilir, örneğin dot matrixli uygulamalarda.
Ben bu çalışmamda mikrodenetliyici olarak st firmasının ürettiği STM32F429-DISCOVERY kullanacağım ve yapacağım çalışma mikrodenetleyicinin sadece üç pinini kullanarak 74HC595 ile  8 adet led süreceğim. Bunları yaparken  SPI(Serial Peripheral Interface)   donanımında yararlanacağım. Bu donanımdan stm32f429 altı tane SPI’a sahiptir.
Kısaca devre şeması aşağıdaki gibi oluyor.
 
 
 
 
 
Yazılım Keil uVision5 ile yazılmıştır. SPI modu kullanılarak yazılımıştır.
#include "stm32f4xx.h"
#include "defines.h"
#include "tm_stm32f4_delay.h"
#define KIRMIZI_LED_YAK  GPIO_SetBits(GPIOG,GPIO_Pin_14)
#define YESIL_LED_YAK  GPIO_SetBits(GPIOG,GPIO_Pin_13)
void gpio_config(void);
void spi_config(void);
void send_byte(uint8_t val);
uint8_t say=0;
int main() {    
                        SystemInit();
                   TM_DELAY_Init();
                        gpio_config();
                        spi_config();
                        while(1){         
                                                KIRMIZI_LED_YAK ;
                                                send_byte(say);
                                                YESIL_LED_YAK;
                                                say++;
                                                Delayms(100);
                                                if(say==256) say=0;
                        }
 
}
void gpio_config(void){
                        GPIO_InitTypeDef GPIO_InitStructure;         
                        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
                        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
                        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
 
                        /*PG13 VE PG14 CIKIS YAPILDI*/
                         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
                          GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
                          GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14;
                          GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
                          GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
                          GPIO_Init(GPIOG,&GPIO_InitStructure);
 
                        /*PB0 CIKIS YAPILID*/
                          GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
                          GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
                          GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
                          GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
                          GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
                          GPIO_Init(GPIOB,&GPIO_InitStructure);
                       
                          GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
                          GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
                          GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_7;
                          GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
                          GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
                          GPIO_Init(GPIOA,&GPIO_InitStructure);
                        /*PA5 VE PA7 SCK VE MOSI YAPILDI*/         
                          GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_SPI1);
                          GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_SPI1);
}
 
 
void spi_config(void){
                          SPI_InitTypeDef SPI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);           SPI_InitStruct.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_4;
                           SPI_InitStruct.SPI_DataSize=SPI_DataSize_8b;
                           SPI_InitStruct.SPI_FirstBit=SPI_FirstBit_MSB;
                           SPI_InitStruct.SPI_Mode=SPI_Mode_Master;
                           SPI_InitStruct.SPI_Direction=SPI_Direction_1Line_Tx;
                          SPI_InitStruct.SPI_CPOL=SPI_CPOL_High;
                           SPI_InitStruct.SPI_CPHA=SPI_CPHA_1Edge;
                           SPI_InitStruct.SPI_NSS=SPI_NSS_Sof;
                           SPI_Init(SPI1,&SPI_InitStruct);
                 SPI_Cmd(SPI1,ENABLE);
}
 
void send_byte(uint8_t val){
    GPIO_ResetBits(GPIOB, GPIO_Pin_0); // ST_CP low
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    SPI_SendData(SPI1, val);
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
    GPIO_SetBits(GPIOB, GPIO_Pin_0); // ST_CP high
}
 
 
Bu kod,  say değişkeni 100ms aralıkla 0’dan 255 kadar sayıp onları ledlerle ifade ediyor. Örnegin, eğer say 255 eşit olduğunda bütünledler yanar veya say 1 eşit olduğunda sadece QA’ya bağlı led yanar veya 2’ye eşit olduğunda  QB yanar.   
 
ÇALIŞMA VİDEOSU
 
 
 
HAKAN  AYDIN
 
Kaynaklar
[1].PIC PROGRAMLAMA TEKNIKLERI VE PIC16F877A, ALTAŞ YAYINCILIK
4. https://github.com/devthrash/STM32F4-examples/blob/master/SPI/main.c
 
 

13 Haziran 2015 Cumartesi

STM32F429 RTC BİRİMİ İLE SAAT





    Bu çalışmam da stm32f429 discovery kitini kullanarak analog ve dijital saat tasarımı yapıp bunu lcd ekranda göstermek. Bunun için stm32f429 entegresi içindeki RTC(Real Time Clock) birimini kullanarak yapmak. Bu çalışma da saat için  TM STM32F4 RTC kütüphanesinden yararlanıldı.

   DS1307 saat entegresini kullanarak saat tasarımı yapanlar bilirler ki bu iş için  32768 Hz bir kristal gereklidir. Aynı kristal yine bu çalışmamda kullanıldı. Tek farkı bu kristal stm32f429 entegresi içinde var veya eğer  siz bu kristali dışarıdan bağlamak isterseniz benim yazılım için bunu PC14, PC15 girişlerine bağlayarak yapabilirsiniz. DS1307 entegresi üzerinde Vbat girişi bulunur. Bu aynı girş yine  stm32f429 entegresinde de vardır.

   Benim yazdığım kod sadece basit bir saat tasarımı içindir. Bu kütüphaneyi kullarak daha iyi ve kararlı bir saat tasarımı yapabilirsiniz.

  Yine bu yazılım için Keil programı kullanıldı ve bu yazılım üzerinde oynanarak daha iyisi yapılabilir.

Keli Kod;
#include "stm32f4xx.h"
#include "defines.h"
#include "tm_stm32f4_rtc.h"
#include "tm_stm32f4_delay.h"
#include "tm_stm32f4_disco.h"
#include "tm_stm32f4_emwin.h"
#include "button.h"
#include "DIALOG.h"
#include
#include
#define TWO_PI 6.28318530717958647693
#define HALF_PI 6.28318530717958647693/4.0


int x0 = 120;
int y0 = 120;
float k;
float s ;
float m ;
float map(float x, float in_min, float in_max, float out_min, float out_max);
void gosterge_cizdir(void);
void gun(void);
char buf[50];

TM_RTC_Time_t zaman; 
int main(void) {

 /* Initialize system */
 SystemInit();

 /* Initialize delay functions */
 TM_DELAY_Init();

 /* Initialize LEDs */
 TM_DISCO_LedInit();

 /* Initialize emWin */
 if (TM_EMWIN_Init() != TM_EMWIN_Result_Ok) {
  /* Initialization error */
   while (1) {
      /* Toggle RED led */
      TM_DISCO_LedToggle(LED_RED);
      /* Delay */
      Delayms(100);
    }
 }
 /* Initialize RTC with internal 32768Hz clock */
 /* It's not very accurate */
 if (!TM_RTC_Init(TM_RTC_ClockSource_Internal)) {
  /* RTC was first time initialized */
  /* Do your stuff here */
  /* eg. set default time */
 }

 /*Çalistirilmaya baslamadan once ilk olarak asagidaki yerleri doldurun*/
     zaman.hours = 00;//00 ile 23 aras1nda secilir
   zaman.minutes = 42;//00 ile 59 aras1nda secilir
   zaman.seconds = 00;//00 ile 59 aras1nda secilir
   zaman.year = 15;
   zaman.month = 6;
   zaman.date = 13;
   zaman.day = 6;  // 1 den  7'ye. Sirasiyla  pazartesi,......,pazar

 TM_RTC_SetDateTime(&zaman, TM_RTC_Format_BIN);
 /* Her 125 ms'de bir kesme üreterek TM_RTC_RequestHandler() bu fonksiyona girer ve günclemeden yard1m eder */
 TM_RTC_Interrupts(TM_RTC_Int_125ms);


 GUI_SetBkColor(GUI_GRAY); // arka plan rengi
  GUI_Clear();

 GUI_SetPenSize( 5 ); // Dis cemberin kalinligi
 GUI_SetTextMode(GUI_TM_TRANS);
  GUI_SetFont(&GUI_FontComic18B_ASCII);
  GUI_SetColor( GUI_BLUE );// dis cember rengi
 
  GUI_SetTextMode(GUI_TM_TRANS);
  GUI_SetFont(&GUI_FontComic18B_ASCII);
  GUI_DrawArc( x0,y0,110, 110,0,360); //dis cemberi cizdir
 
 while (1) {
     gosterge_cizdir();// cember icinde olan noktalari ve sayilari çizdir.

      TM_RTC_GetDateTime(&zaman, TM_RTC_Format_BIN); /* STM32F429 ICINDEKI RTC BOLUMUNDEN
      zaman ile ilgili olan saat, dakika, saniye gibi bigileri almak icin kullanilir*/

    GUI_SetColor( GUI_RED );
    sprintf(buf, "TARIH: %02d.%02d.%04d\n", zaman.date, zaman.month,zaman.year + 2000);
    GUI_DispStringAt(buf, 10, 300);
     sprintf(buf, "SAAT: %02d:%02d:%02d\n",zaman.hours,zaman.minutes,zaman.seconds);
    GUI_DispStringAt(buf, 10, 280);
    GUI_SetColor( GUI_GRAY );
       GUI_SetPenSize( 4 );
     GUI_DrawLine( x0,  y0, cos(s)*60+120 , sin(s)*60+120);
    GUI_DrawLine( x0,  y0, cos(k)*40+120 , sin(k)*40+120);
    GUI_SetPenSize( 3);
    GUI_DrawLine( x0,  y0, cos(m)*50+120 , sin(m)*50+120);

       k = map(zaman.hours%12, 0, 12, 0, TWO_PI)-HALF_PI;
     /*Map fonk 0 ile 12 olan sayilar1 0 ile iki pi arasina uygun olarak ayarlar */
      s = map(zaman.seconds, 0, 59, 0, TWO_PI)-HALF_PI;
    m = map(zaman.minutes, 0, 59, 0, TWO_PI)-HALF_PI;
     /*Asag1daki ko parcas1nda cember 1c1ndeki akrep,yelkovan cizildi ve bunun icin
       trigonometriden yararlan1ld1*/
    GUI_SetColor( GUI_BLUE );
       GUI_SetPenSize( 4);
      GUI_DrawLine( x0,  y0, cos(s)*60+120 , sin(s)*60+120);
    GUI_SetPenSize( 3);
    GUI_SetColor( GUI_RED );
    GUI_DrawLine( x0,  y0, cos(m)*50+120 , sin(m)*50+120);
    GUI_SetColor( GUI_BLACK );
       GUI_SetPenSize( 4);
     GUI_DrawLine( x0,  y0, cos(k)*40+120 , sin(k)*40+120);
   
    gun();
 }
}
void gun(void){
   switch (zaman.day){
        case 1: GUI_DispStringAt("PAZARTESI", 10, 250);break;
        case 2: GUI_DispStringAt("SALI", 10, 250)     ;break;
     case 3: GUI_DispStringAt("CARSAMBA", 10, 250) ;break;
     case 4: GUI_DispStringAt("PERSEMBE", 10, 250) ;break;
     case 5: GUI_DispStringAt("CUMA", 10, 250)     ;break;
     case 6: GUI_DispStringAt("CUMARTESI", 10, 250);break;
     case 7: GUI_DispStringAt("PAZAR", 10, 250)    ;break;
       }
}
void gosterge_cizdir(void){
 char ac[4];
 int i;
 for (i=1; i<= 12; i++) {
     float a = (i*30)*3.1415926/180;
     int x = 100*cos(a)+x0;
     int y = 100*sin(a)+y0;
  
      if (i%3 == 0)
    GUI_SetPenSize( 5 );// saat 12,3,6 ve 9 1c1n büyük nokta
      else
      GUI_SetPenSize( 4 );// digerleri 1c1n 1se kucuk nokta koy
  
      GUI_DrawPoint(x,y);
    
     if (i%3 == 0) { //saat 12,3,6 ve 9 say1lar1 yazd1r 
          x = -80*cos(a)+x0;
          y = 80*sin(a)+y0;
          sprintf(ac, "%d", i);
          GUI_SetTextAlign(GUI_TA_VCENTER);
          GUI_DispStringHCenterAt(ac,y,x);
      }   
    } 
}
void TM_RTC_RequestHandler() {
       TM_DISCO_LedToggle(LED_RED | LED_GREEN);
    GUI_ClearRect(0, 250, 240, 300);
}

float map(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
/* User handler for 1ms interrupts */
void TM_DELAY_1msHandler(void) {
 /* Call periodically each 1ms */
 TM_EMWIN_UpdateTouch();
}


Çalışma Videosu