1. Aşağı Yukarı Sayıcı

Bu örnek iki buton ile 0 - 99 sayıcı örneğidir. Aşağıda aynı işi yapan farklı kod örnekleri vardır.

İlk örnek kod taşınabilirliği ve anlaşılabilirliği açısından zayıf bir örnektir. Kodlar optimize yazılmamış ve kod yoğunluğu gayet düşük bir koddur.

İkinci örnek aynı kodun taşınabilirliği, okunabilirliği ve optimize edilmiş halini içerir. Pin giriş ve çıkışların Arduino kütüphaneleri kullanılmıştır.

Üçüncü örnek herhangi bir kütüphane kullanmadan bir mikrodenetleyici nasıl C ile kodlanır örneğidir. Bu örnek ile ikinci örneği karşılaştırıp Arduino fonksiyonları yerine direk mikrodenetleyici registerları ile nasıl yapıldığını anlamaya çalışmanızı tavsiye ederim.

Not

Üçüncü örnek de Arduino IDE’sinde yapılacağı için setup(), loop() fonksiyonları bu örnekte de bulunmaktadır.

1.1. Örnek - 1

Bu örnek ilk programlamaya başladığım zamanlarda yazdığım kodlara çok benzer :) Listede bu kodun eksik noktaları belirtilmiştir.

  1. Tekrarlanan işler döngülere alınmamış Kopyala-yapıştır ile çoğaltılmış
  2. Tanımlama hiç kullanılmamış, en ufak pin değişikliğinde tüm kodun elden geçmesi gerekir
  3. Aynı işi yapan iki ayrı fonksiyon kullanılmış
  4. Lokal bir değişken ile çözülebilecek sayac değişkeni global olarak tanımlanmış
  5. Kod yoğunluğu ve derleyici optimizasyonu uygunluğu düşük bir kod
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
static unsigned int sayac;

void setup() 
{
   unsigned int pin;

   pinMode(2, INPUT_PULLUP);
   pinMode(3, INPUT_PULLUP);
   pinMode(13, OUTPUT);
   pinMode(8, OUTPUT);
   pinMode(9, OUTPUT);
   pinMode(10, OUTPUT);
   pinMode(11, OUTPUT);
   
   pinMode(14, OUTPUT);
   pinMode(15, OUTPUT);
   pinMode(16, OUTPUT);
   pinMode(17, OUTPUT);

   sayac = 0;
}

void loop() 
{
   if (LOW == digitalRead(3))
   {
      digitalWrite(13, HIGH);
      while (LOW == digitalRead(3))
      {
         /* Buton basılı iken bekle */
      }
      digitalWrite(13, LOW);
      if (0 != sayac)
      {
         sayac--;
      }
         else
      {
         sayac = 0;      
      }
   }
   if (LOW == digitalRead(2))
   {
      digitalWrite(13, HIGH);
      while (LOW == digitalRead(2))
      {
         /* Buton basılı iken bekle */
      }
      digitalWrite(13, LOW);
      if (sayac < 99)
      {
         sayac++;
      }
      else
      {
         sayac=99;      
      }
   }
   
   Onlar_Yazdir();
   Birler_Yazdir();  
}

void Onlar_Yazdir(void)
{
   unsigned int onlar;
   
   onlar = sayac / 10;

   if (onlar & 1)
   {
      digitalWrite(14, HIGH);
   }
   else
   {
      digitalWrite(14, LOW);
   }
   if (onlar & 2)
   {
      digitalWrite(15, HIGH);
   }
   else
   {
      digitalWrite(15, LOW);
   }
   if (onlar & 4)
   {
      digitalWrite(16, HIGH);
   }
   else
   {
      digitalWrite(16, LOW);
   }
   if (onlar & 8)
   {
      digitalWrite(17, HIGH);
   }
   else
   {
      digitalWrite(17, LOW);
   }
}  

void Birler_Yazdir(void)
{
   unsigned int birler;
   
   birler = sayac % 10;

   if (birler & 1)
   {
      digitalWrite(8, HIGH);
   }
   else
   {
      digitalWrite(8, LOW);
   }
   if (birler & 2)
   {
      digitalWrite(9, HIGH);
   }
   else
   {
      digitalWrite(9, LOW);
   }
   if (birler & 4)
   {
      digitalWrite(10, HIGH);
   }
   else
   {
      digitalWrite(10, LOW);
   }
   if (birler & 8)
   {
      digitalWrite(11, HIGH);
   }
   else
   {
      digitalWrite(11, LOW);
   }
}

1.2. Örnek - 2

Bu örnekte C dilinde ön-işlemci tanımlamaları, döngüler, bit işlemleri, ? : operatörü, fonksiyonlaştırma örneklerini göstermeye çalıştım. LED Display bağlantıları değişirse sadece ilk baştaki tanımları değiştirmeniz yeterlidir. Hatta maksimum değer, sayı tabanı vb. değerleri değiştirdiğinizde sonuç çok kolay bir şekilde üretilecektir. Üçüncü bir display ekleyip 8’li sayı tabanında bir sayıcı yapmayı deneyebilirsiniz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#define BIRLER_BASAMAGI_BASLANGIC    (8U)
#define ONLAR_BASAMAGI_BASLANGIC    (14U)
#define DISPLAY_PIN_SAYISI           (4U)
#define YUKARI_DUGME                 (2U)
#define ASAGI_DUGME                  (3U)
#define LED_PIN                     (13U)
#define SAYAC_MAKSIMUM              (99U)
#define SAYI_TABANI                 (10U)

void setup() 
{
   unsigned int i;
   
   pinMode(YUKARI_DUGME, INPUT_PULLUP);
   pinMode(ASAGI_DUGME, INPUT_PULLUP);
   pinMode(LED_PIN, OUTPUT);
   for (i = 0; i < DISPLAY_PIN_SAYISI; i++)
   {
      pinMode((BIRLER_BASAMAGI_BASLANGIC + i), OUTPUT);
      pinMode((ONLAR_BASAMAGI_BASLANGIC + i), OUTPUT);
   }
}

void loop() 
{
   static unsigned int sayac = 0;
   
   if (LOW == digitalRead(ASAGI_DUGME))
   {
      digitalWrite(LED_PIN, HIGH);
      while (LOW == digitalRead(ASAGI_DUGME))
      {
         /* Buton basılı iken bekle */
      }
      digitalWrite(LED_PIN, LOW);
      sayac--;
      if (SAYAC_MAKSIMUM < sayac)
      {
         sayac = 0;      
      }
   }
   if (LOW == digitalRead(YUKARI_DUGME))
   {
      digitalWrite(LED_PIN, HIGH);
      while (LOW == digitalRead(YUKARI_DUGME))
      {
         /* Buton basılı iken bekle */
      }
      digitalWrite(LED_PIN, LOW);
      sayac++;
      if (sayac >= SAYAC_MAKSIMUM)
      {
         sayac = SAYAC_MAKSIMUM;      
      }
   }
   Yazdir(BIRLER_BASAMAGI_BASLANGIC, (sayac % SAYI_TABANI));
   Yazdir(ONLAR_BASAMAGI_BASLANGIC,  (sayac / SAYI_TABANI));  
}

void Yazdir (unsigned int ondalik, unsigned int sayi)
{
   unsigned int i;
   for (i = 0; i < DISPLAY_PIN_SAYISI; i++)
   {
      digitalWrite(ondalik++, (sayi & (1U << i)) ? HIGH : LOW);
   }
}

1.3. Örnek - 3

Bu örnekte ise mikrodenetleyiciye ait bir sürücü kütüphanemiz yok. Tüm giriş ve çıkış işlemleri mikrodenetleyici Port donanımı üzerinden yapılacak. Sadece AVR derleyici ve üretici tanım başlık dosyaları kullanılmıştır. PORTB adresini elle tanımlamak yerine üretici başlık dosyasındaki tanımı kullanır.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#define BIRLER_BASAMAGI_MASKE          (0x0F)
#define ONLAR_BASAMAGI_MASKE           (0x0F)
#define BIRLER_BASAMAGI_YON_REGISTER   DDRB
#define ONLAR_BASAMAGI_YON_REGISTER    DDRC
#define BIRLER_BASAMAGI_PORT_REGISTER  PORTB
#define ONLAR_BASAMAGI_PORT_REGISTER   PORTC
#define DUGMELER_YON_REGISTER          DDRD
#define DUGMELER_PORT_REGISTER         PORTD
#define DUGMELER_PIN_REGISTER          PIND
#define YUKARI_DUGME                   (1 << 2U)
#define ASAGI_DUGME                    (1 << 3U)
#define LED_PORT_REGISTER              PORTB
#define LED_PIN                        (1 << 5U)
#define SAYAC_MAKSIMUM                 (99U)
#define SAYI_TABANI                    (10U)

void setup() 
{
   BIRLER_BASAMAGI_YON_REGISTER = (BIRLER_BASAMAGI_MASKE | LED_PIN);
   ONLAR_BASAMAGI_YON_REGISTER  = ONLAR_BASAMAGI_MASKE;
   DUGMELER_YON_REGISTER        = ~(YUKARI_DUGME | ASAGI_DUGME);
   DUGMELER_PORT_REGISTER       = (YUKARI_DUGME | ASAGI_DUGME);
}

void loop() 
{
   static unsigned int sayac = 0;
      
   if (ASAGI_DUGME != (ASAGI_DUGME & DUGMELER_PIN_REGISTER))
   {
      LED_PORT_REGISTER |= LED_PIN;
      while (ASAGI_DUGME != (ASAGI_DUGME & DUGMELER_PIN_REGISTER))
      {
         /* Buton basılı iken bekle */
      }
      LED_PORT_REGISTER &= ~LED_PIN;
      sayac--;
      if (SAYAC_MAKSIMUM < sayac)
      {
         sayac = 0;      
      }
   }
   if (YUKARI_DUGME != (YUKARI_DUGME & DUGMELER_PIN_REGISTER))
   {
      LED_PORT_REGISTER |= LED_PIN;
      while (YUKARI_DUGME != (YUKARI_DUGME & DUGMELER_PIN_REGISTER))
      {
         /* Buton basılı iken bekle */
      }
      LED_PORT_REGISTER &= ~LED_PIN;
      sayac++;
      if (sayac >= SAYAC_MAKSIMUM)
      {
         sayac = SAYAC_MAKSIMUM;      
      }
   }
   Yazdir(&BIRLER_BASAMAGI_PORT_REGISTER, (sayac % SAYI_TABANI), BIRLER_BASAMAGI_MASKE);
   Yazdir(&ONLAR_BASAMAGI_PORT_REGISTER, (sayac / SAYI_TABANI), ONLAR_BASAMAGI_MASKE);
}

void Yazdir(volatile uint8_t *const port, const uint8_t deger, const uint8_t maske)
{
   uint8_t port_gecici_deger;

   port_gecici_deger  = *port & ~maske;
   port_gecici_deger |= deger & maske;
   *port = port_gecici_deger;
}