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.
- Tekrarlanan işler döngülere alınmamış Kopyala-yapıştır ile çoğaltılmış
- Tanımlama hiç kullanılmamış, en ufak pin değişikliğinde tüm kodun elden geçmesi gerekir
- Aynı işi yapan iki ayrı fonksiyon kullanılmış
- Lokal bir değişken ile çözülebilecek
sayacdeğişkeni global olarak tanımlanmış- 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;
}
|