7 SEGMENT DISPLAY ILE KRONOMETRE

C++:
byte _10ms = 0;
byte sn = 0;
byte dk = 0;
byte sa = 0;

ISR(TIMER1_COMPA_vect) {

  _10ms++;

  if (_10ms == 100) {
    sn++;
    _10ms = 0;
  }

  if (sn == 60) {
    dk++;
    sn = 0;
  }

  if (dk == 60) {
    sa++;
    dk = 0;
  }

  if (sa == 99) {
    sa = 0;
  }
}

unsigned char _7seg[] =
{ //nGFEDCBA
  0b11000000,//sıfır/0
  0b11111001,//bir/1
  0b10100100,//iki/2
  0b10110000,//üç/3
  0b10011001,//dört/4
  //nGFEDCBA
  0b10010010,//beş/5
  0b10000010,//altı/6
  0b11111000,//yedi7
  0b10000000,//sekiz8
  0b10010000,//dokuz9
  0b00000000,//lamba TEST10
  0b11111111,//lamba OF11
};


int a = 0;
void setup() {
  DDRD = B11111111; //büTÜN D PORTI ÇIKIŞ
  DDRB = DDRB | B00001111;//8-9-10-11 çıkış


  noInterrupts();
  TCCR1A = 0;
  TCNT1 = 0;
  OCR1A = 16000000 / (100 * 64) - 1;
  TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  interrupts();

  a = 76;
}

void loop() {

  int onlarms = _10ms / 10;
  int birlerms = _10ms % 10;

  int onlars = sn / 10;
  int birlers = sn % 10;
 
  //------------1098
  PORTB = 0B00000111;//11 iletimde 10 yalıtımda
  PORTD = _7seg[onlarms];
  delay(9);//tarama ayar

  //------------1098
  PORTB = 0B00001011;
  PORTD = _7seg[birlerms];
  delay(5);//tarama ayar
 
 
  //------------1098
  PORTB = 0B00001101;
  PORTD = _7seg[onlars];
  delay(5);//tarama ayar

  //------------1098
  PORTB = 0B00001110;
  PORTD = _7seg[birlers];
  delay(5);//tarama ayar

}
 
Tarama ve yazdırma işini kesmeye alman lazım. Ana döngüde olmaz o iş. En baştan tasarımın gereği bu.
 
Bir de bölmeden kurtulmak için her salise, saniye, dakika, ve saati de ayrı ayrı hanelere bölebilirsin. Böylece doğrudan ne yazdıracağın belli olacak, hesap kitap olmayacak. Buna BCD (binary coded decimal) kodlama da deniyor.
 
C++:
byte _10ms = 0;
byte sn = 0;
byte dk = 0;
byte sa = 0;

int onlarms = 0;
int birlerms = 0;

int onlars = 0;
int birlers = 0;

unsigned char _7seg[] =
{ //nGFEDCBA
  0b11000000,//sıfır/0
  0b11111001,//bir/1
  0b10100100,//iki/2
  0b10110000,//üç/3
  0b10011001,//dört/4
  //nGFEDCBA
  0b10010010,//beş/5
  0b10000010,//altı/6
  0b11111000,//yedi7
  0b10000000,//sekiz8
  0b10010000,//dokuz9
  0b00000000,//lamba TEST10
  0b11111111,//lamba OF11
};


void hesap() {
  _10ms++;

  if (_10ms == 100) {
    sn++;
    _10ms = 0;
  }

  if (sn == 60) {
    dk++;
    sn = 0;
  }

  if (dk == 60) {
    sa++;
    dk = 0;
  }

  if (sa == 99) {
    sa = 0;
  }
}

void yaz() {
  onlarms = _10ms / 10;
  birlerms = _10ms % 10;

  PORTB = 0B00000111;//11 iletimde 10 yalıtımda
  PORTD = _7seg[onlarms];
  delay(1);//tarama ayar

  //------------1098
  PORTB = 0B00001011;
  PORTD = _7seg[birlerms];
  delay(4);//tarama ayar

  onlars = sn / 10;
  birlers = sn % 10;

  //------------1098
  PORTB = 0B00001101;
  PORTD = _7seg[onlars];
  delay(4);//tarama ayar

  //------------1098
  PORTB = 0B00001110;
  PORTD = _7seg[birlers];
  delay(4);//tarama ayar
}

ISR(TIMER1_COMPA_vect) {
  hesap();
  yaz();
}

int a = 0;
void setup() {
  DDRD = B11111111; //büTÜN D PORTI ÇIKIŞ
  DDRB = DDRB | B00001111;//8-9-10-11 çıkış

  noInterrupts();
  TCCR1A = 0;
  TCNT1 = 0;
  OCR1A = 16000000 / (100 * 64) - 1;
  TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  interrupts();
}

void loop() {}

Voidlere böldüm hesapları ilgili bölüm yazılacakken yaptırdım şuan çalışıyor
 
Aşağıdaki kodda BCD kullanarak arttırma yaptım. En kötü durumda (yani 99 dan 00 a geçişte) arttırma işlemi 1.2 μs sürüyor.

C++:
#define THEPIN 6

static unsigned char salise[2];
static unsigned char saniye[2];
static unsigned char dakika[2];
static unsigned char saat[2];

static void bcd_inc(unsigned char* bcd)
{
  ++bcd[0];
  if (bcd[0] == 10)
  {
    bcd[0] = 0;
    ++bcd[1];
    if (bcd[1] == 10)
    {
      bcd[1] = 0;
    }
  }
}

void setup()
{
  pinMode(THEPIN, OUTPUT);
}

void loop()
{
  noInterrupts();

  while (1)
  {
    PORTD = 0x40;

    bcd_inc(salise);

    PORTD = 0x00;
  }
}

1656147773332.png
 
Aşağıdaki kodda BCD kullanarak arttırma yaptım. En kötü durumda (yani 99 da 00 a geçişte) arttırma işlemi 1.2 μs sürüyor.

C++:
#define THEPIN 6

static unsigned char salise[2];
static unsigned char saniye[2];
static unsigned char dakika[2];
static unsigned char saat[2];

static void bcd_inc(unsigned char* bcd)
{
  ++bcd[0];
  if (bcd[0] == 10)
  {
    bcd[0] = 0;
    ++bcd[1];
    if (bcd[1] == 10)
    {
      bcd[1] = 0;
    }
  }
}

void setup()
{
  pinMode(THEPIN, OUTPUT);
}

void loop()
{
  noInterrupts();

  while (1)
  {
    PORTD = 0x40;

    bcd_inc(salise);

    PORTD = 0x00;
  }
}

17995 eklentisine bak
Bir süre'de buna bakayım bunuda anlarım
 
++bcd[1];

bunu anlamadım normlade ben arttırmak için önüne + koyuyordum arkasına koyunca değişen ney oluyor
 
aklım bulandı yine ben gidip pillerimi şarja takayım dönüşte anlamış olurum
 
++bcd[1];

bunu anlamadım normlade ben arttırmak için önüne + koyuyordum arkasına koyunca değişen ney oluyor

Önde olursa işlem öncesi arttırıyor, sonda olsursa işlem sonrası arttırıyor. Burada ifade içinde işlem olmadığı için önü arkası farketmiyor.

Voidlere böldüm hesapları ilgili bölüm yazılacakken yaptırdım şuan çalışıyor

Kesmenin süresini kısaltmak için paralıyoruz burada kendimizi, sen gitmişsin kesmenin içine dev delayler koymuşsun :) O delayler olmaz.
 
Önde olursa işlem öncesi arttırıyor, sonda olsursa işlem sonrası arttırıyor. Burada ifade içinde işlem olmadığı için önü arkası farketmiyor.



Kesmenin süresini kısaltmak için paralıyoruz burada kendimizi, sen gitmişsin kesmenin içine dev delayler koymuşsun :) O delayler olmaz.
Orda bi amatörlük yaptım abi.
Ama onlar olmadan bütün displayler'de 8 yani bütün segmanlar yanar konumda oluyor anlamlı bir görüntü oluşmuyor
 
C++:
static void bcd_ms(unsigned char* bcdms)
{
  ++bcdms[0];//bcd geldiyse 1 arttır
 
  if (bcdms[0] == 10)//birler basamağı 10 olduysa
  {
    bcdms[0] = 0;//birler basamağını sıfırla
   
    ++bcdms[1];//onlar basamağını 1 arttır
   
    if (bcdms[1] == 10)//onlar basamağı 10 olduysa
    {
      bcdms[1] = 0;//onlar basamağını sıfırla
     
      bcd_s(1);          //diğer basamağa +1 ver
    }
  }
}

static void bcd_s(unsigned char* bcds)
{
  ++bcds[0];//bcd geldiyse 1 arttır
 
  if (bcds[0] == 10)//birler basamağı 10 olduysa
  {
    bcds[0] = 0;//birler basamağını sıfırla
   
    ++bcds[1];//onlar basamağını 1 arttır
   
    if (bcds[1] == 60)//onlar basamağı 10 olduysa
    {
      bcdms[1] = 0;//onlar basamağını sıfırla
                 //diğer basamağa +1 ver
    }
  }
}
Doğru anlamışmıyım abi

edit yanlış yazmışım
 
Son düzenleme:
Tek fonksiyon olacak
 
Sanki verdiğin örneklerde tuzaklar sezdim abi :)
C++:
static void bcd_m(unsigned char* bcdm)
{

  ++bcdm[0];//bcd geldiyse 1 arttır

  if (bcdm[0] == 10)//birler basamağı 10 olduysa
  {
    bcdm[1]++;
    bcdm[0] = 0;//birler basamağını sıfırla
    //bcdm[1]++;//onlar basamağını 1 arttır
  }
  if (bcdm[1] == 10)//onlar basamağı 10 olduysa
  {
    bcdm[1] = 0;//onlar basamağını sıfırla
  }
    //------------1098
 // PORTB = 0B00001011;
 PORTB = 0B00000111;
  PORTD = _7seg[bcdm[1]];
  delay(8);//tarama ayar

//  PORTB = 0B00000111;//11 iletimde 10 yalıtımda
PORTB = 0B00001011;
  PORTD = _7seg[bcdm[0]];
  delay(8);//tarama ayar
}

ISR(TIMER1_COMPA_vect) {
  salise[2]++;
  bcd_m(salise);

}
 
Hazır bitmiş hap gibi fonksiyon vermiyorum. Problemleri yaşayıp senin düzeltmen daha faydalı.
 
Önce çalışma mantığını BCD ye göre anlat. Anlatım doğru değilse program da haliyle doğru olmayacak
 
Hazır bitmiş hap gibi fonksiyon vermiyorum. Problemleri yaşayıp senin düzeltmen daha faydalı.
Az daha bu arduinom bozuldu diyip diğerini getiriyordum. 10lar basamağına geçemiyor if şartı sağlanmıyormuş birler basamağı şartı sağlandıktan sonra
 
Önce çalışma mantığını BCD ye göre anlat. Anlatım doğru değilse program da haliyle doğru olmayacak
Anladığım kadarıyla.
bcdm[x]
x değeri bizim basamak sayımız.

7 değeri bizim en büyük basamağımız(saat-onlar)
0 değeri bizim en küçük basamağımız(milisaniye-birler)

0-7 arası bölünmüş olarak arttırdığımız için harici bir bölme, yüzde alma işlemi yapmıyoruz benim projenin en başında yaptığım gibi şu kadar arttıysa 1 yap sıfırla.

Anladığımı biliyorum ama tam detaylı dile dökemiyorum en iyisi ben birazcını yazıp göstereyim
 
C++:
static void bcd_m(unsigned char* bcdm)
{

   //bcdm= 0-1(salise) , 2-3(saniye) , 4-5(dakika) , 6-7(saat)
  
  //------MILISANIYE-------------
  ++bcdm[0];//bcd geldiyse 1 arttır

  if (bcdm[0] == 10)//birler basamağı 10 olduysa
  {
    bcdm[1]++;
    bcdm[0] = 0;//birler basamağını sıfırla
    //bcdm[1]++;//onlar basamağını 1 arttır
  }
  if (bcdm[1] == 10)//onlar basamağı 10 olduysa
  {
    bcdm[2]++;
    bcdm[1] = 0;//onlar basamağını sıfırla
  }
    ....
   EKRANA YAZMA KOMUTLARI
       ....
  //------MILISANIYE-------------
 
  if(bcdm[2] == 10){
    bcdm[3]++;
    bcdm[2] = 0;
  }
 
  if(bcdm[3] == 60){
    bcdm[4]++;
    bcdm[3] = 0;
  }
}
 
Kod doğru mu bilmiyorum ama mantığını anlamışsın.
 

Forum istatistikleri

Konular
6,985
Mesajlar
119,316
Üyeler
2,835
Son üye
alpermete

Son kaynaklar

Son profil mesajları

hakan8470 wrote on Dede's profile.
1717172721760.png
Dedecim bu gul mu karanfil mi? Gerci ne farkeder onu da anlamam. Gerci bunun anlamini da bilmem :gulus2:
Lyewor_ wrote on hakan8470's profile.
Takip edilmeye başlanmışım :D ❤️
Merhaba elektronik tutsakları...
Lyewor_ wrote on taydin's profile.
Merhabalar. Elektrik laboratuvarınız varsa bunun hakkında bir konunuz var mı acaba? Sizin laboratuvarınızı merak ettim de :)
Lyewor_ wrote on taydin's profile.
Merhabalar forumda yeniyim! Bir sorum olacaktı lcr meterler hakkında. Hem bobini ölçen hemde bobin direnci ölçen bir lcr meter var mı acaba?
Back
Top