Arduino'suz Atmega328P ve DS1307 ile Dijital Saat Projesi

TA3UIS

Doğan
Katılım
15 Kasım 2023
Mesajlar
3,056
Arduino kartı olmadan, mikrodenetleyicinin kendi kapasitesini kullanarak sıfırdan inşa etmeye çalıştığım bir Dijital Saat projesi hazırladım.

Bu proje benim için sadece bir saat değil; kristal osilatörden RTC haberleşmesine, register seviyesinden ISP programlamaya kadar elektronikte bir yolculuuk gibi oldu.:)

Neden Bağımsız?
Hazır bir Arduino Uno üzerine shield takmak yerine, Atmega328P-PU çipini breadboard üzerinde tek başına çalıştırdım. Kendi 16MHz kristalini, kapasitörlerini ve reset devresini kurmak, projeden aldığım keyfi katladı.

Malzemeler:
Mikrodenetleyici
Atmega328P-PU
Zamanlayıcı DS1307 RTC Entegresi + 32.768 kHz Kristal (Gerçek zamanlı saat için)
Görüntüleme 4 Haneli 7 Segment Display (Ortak Katot)
Osilatör 16 MHz Kristal + 2x 22pF Seramik Kondansatörr,
Programlayıcı CH341A USB Programlayıcı
Dirençler Segmentler için 7x 220R, Pull-up/down hatları için 10k Ohm dirençler.
Güç 5V DC

Teknik Detaylar ve Karşılaştığım Zorluklar:
Projenin en can alıcı noktalarından biri, işlemciye kod yüklemeden önce Chip Erase yapmanın önemiydi. Eski verileri temizlemeden çoğu durumda kararlı bir çalışma elde edilemiyor. Ayrıca saatin saniyelerini temsil eden o yanıp sönen nokta için Atmega nın 15. fiziksel bacağını konfigüre ettim.
Saat modülü (DS1307) I2C protokolü üzerinden işlemciyle haberleşiyor.
Pil desteği sayesinde elektrik kesilse bile zaman akmaya devam ediyor. Ayar butonları ile dakika ve saati anlık olarak güncelleyebiliyorum.

Yazılım Özellikleri
Kodda SevSeg kütüphanesini optimize ederek kullandım. Baştaki sıfırların titrememesi için Leading Zero Blanking özelliğini kapattım ve saniyede bir yanıp sönen noktayı millis() fonksiyonu ile asenkron hale getirdim.


Breadboard üzerindeki kablo karmaşası içinde o ilk 12:00 yazısını görmek ve noktanın yanıp söndüğünü izlemek çok keyifliydi.



WhatsApp Image 2026-02-10 at 03.42.00.jpeg
WhatsApp Image 2026-02-10 at 03.42.13.jpeg
 
Son düzenleme:
Yanlış anlarsınız diye bayadır kendimi tutuyorum ama artık soracağım, kusura bakmayın lütfen. Neden son zamanlardaki mesajlarınız LLM çıktısı gibi? Forum postlarınızı chatgpt yazıyor gibi.
 
Yanlış anlarsınız diye bayadır kendimi tutuyorum ama artık soracağım, kusura bakmayın lütfen. Neden son zamanlardaki mesajlarınız LLM çıktısı gibi? Forum postlarınızı chatgpt yazıyor gibi.

Haklısın valla ne diyeyim.

Proje aşamasında takıldığım yerlerde teknik dokümanları anlamak ve bağlantıları şemaya dökmek için bazen yapay zekadan destek alıyorum. Yazıyı hazırlarken de derli toplu olsun diye yardım isteyince ortaya böyle bir metin çıkıyor.

Ama devreyi kuran, masadaki kablo karmaşasıyla boğuşan, dumanı üstünde test eden, hatayı breadboard üstünde arayan ve gerilen sinirler tamamen organik, yani bana ait.

Bu devreyi kurmak, test etmek ve çalışır hale getirmek mesela gece 04:00’e kadar sürdü. Toplamda yaklaşık 6 saatimi aldı.

Yani LLM klavyede, ben breadboard/lehim, prob ve ölçüm tarafındayım diyelim.
 
Son düzenleme:
Arduino IDE menüden Sketch - Export Compiled Binary ile oluşturulan bootloader olmayan hex dosyasını kullanacağız.

CH341A ile bu hex dosyasını açıp Atmega328P yi programlamak gerekiyor.


Arduino kod kısmı aşağıdaki gibi.
SevSeg kütüphanesinin yüklenmesi gerekiyor.


C++:
#include <Wire.h>
#include "RTClib.h"
#include "SevSeg.h"



RTC_DS1307 saat_modulu;
 SevSeg ekran;

void setup() {
  if (!saat_modulu.begin()) while (1);
 
  if (!saat_modulu.isrunning()) {
    saat_modulu.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }


  byte hane_sayisi = 4;
  byte hane_pinleri[] = {10, 11, 12, 13};
 
  byte segment_pinleri[] = {2, 3, 4, 5, 6, 7, 8, 9};
 
  ekran.begin(COMMON_CATHODE, hane_sayisi, hane_pinleri, segment_pinleri, true, false, true, false);
  ekran.setBrightness(90);
 
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
 
}



void loop() {
  DateTime su_an = saat_modulu.now();
  int goruntulenecek_zaman = (su_an.hour() * 100) + su_an.minute();

  if (digitalRead(A0) == HIGH) {
    saat_modulu.adjust(DateTime(su_an.unixtime() + 3600));
    delay(200);
  }

 
  if (digitalRead(A1) == HIGH) {
    saat_modulu.adjust(DateTime(su_an.unixtime() + 60));  
    delay(200);
  }



  static unsigned long son_yanma_vakti = 0;
  static bool nokta_durumu = false;
 
  if (millis() - son_yanma_vakti >= 500) {
    son_yanma_vakti = millis();
    nokta_durumu = !nokta_durumu;
  }



  if (nokta_durumu) {
    ekran.setNumber(goruntulenecek_zaman, 2);
  } else {
    ekran.setNumber(goruntulenecek_zaman, -1);
  }
 

  ekran.refreshDisplay();



 
}
 
16MHz frekansı ve sinüsü skopta görüyorum, sinüsteki çok hafif bozulma atmeganın 10. Pininden aldığım jumper kablonun paraziti.
Skop Bw limit düşürünce sinüs daha düzgün görünüyor ama frekans 15.9996MHz seviyesine düşüyor.

Değerler bence iyi çıktı.


10010.jpg
10012.jpg


10019.jpg
 
Saat için kullanılan yanıp sönen saniye ledi için bir öneride bulunayım. Ortadaki segmentlerin birisini tesrs çevirin. Ortada üst üste 2 ledli alışılmış saat görüntüsü çıkacaktır. Gerçi aradaki boşluk biraz fazla olacak ama.

Bu arada elinize sağlık. Bu tarz hedef odaklı projeleri yaparken farkında olmadan çok fazla şey öğreniyorsunuz.
 
Bu tarz hedef odaklı projeleri yaparken farkında olmadan çok fazla şey öğreniyorsunuz.
Gece yarısı Atmegayı defalarca ch341a ile programlamayı denedim defalarca o kabloları sök tak pc ye bağla belli bir süreden sonra tam da yarına kalsın demeden önce atmegayı tamamen silip ardından kodları yazdırınca çalıştığını gördüm.

Atmegaya program yazmadan önce tamamen silmem gerektiğini yorgun gözlerle tecrübe etmiş oldum :)

Projenin bitiş saati 7 segment üstünde görülüyor.
 
Son düzenleme:

Forum istatistikleri

Konular
8,899
Mesajlar
144,620
Üyeler
3,580
Son üye
Andy_098790

Son kaynaklar

Back
Top