Bu yazımda bir buton ile bir led'in Atmega 328p mikrodenetleyicisi ile nasıl kontrol edileceğini anlatacağım. bu uygulamayı yaptığımız zaman
1-
Avr Atmega mikrodenetleyicisi ile girişlerin nasıl okunacağını
2-
Avr Atmega mikrodenetleyicisi portlarının pull_up özelliğinin nasıl
kulanılacağın
3- Avr Atmega portlarına bağlanan digital bir sensoru nasıl
okuyacağımızı öğrenmiş olacağız.
Kısaca girişteki dijital bir verinin nasıl okunacağı ve
yorumlanacağını öğreneceğiz.
Devre şeması

Devre şemasından da görüleceği gibi butonumuz PD0 (PORTD0 ) pinine pull-up bağlanmış , led'imiz de PB0 (PORTB0) pinine bağlanmıştır. Yapmamız gereken butona basdığımız zaman led2imizin yanıp sönmesidir.
PD0'a buton bağlandığı için PD0 pini giriş olarak tanımlanmalı : DDRD &=~(1<<PIND0);
PB0'a led bağlandığı için PB0 pini çıkış olarak tanımlanmalı : DDRB |=(1<<PINB0);
Butona bastığımız anlamak için if () - else deyimini kullanacağız.
kabaca programımız şöyle olmalı
Eğer buton sıfır ise led yak
değil ise led söndür
Atmel studio'da herhangi bir portun tek bir bitini kontrol etmek için iki tane macro kullanırız.
bit'in bir olup olmadığı nı kontrol için
#define bit_is_set(sfr,bit) \ (_SFR_BYTE(sfr) & _BV(bit))
bit'in sıfır olup olmadığını kontrol için
#define bit_is_clear(sfr,bit) \
(!(_SFR_BYTE(sfr) & _BV(bit)))
Bu makrolar " #include <avr/io.h>" program satırı ile tanımlanır. Tekrardan "#define" ile tanımlamaya gerek yok
if(bit_is_clear(PIND,0))
{
PORTB|=(1<<PINB0);
}
else
{
PORTB&=~(1<<PINB0);
}
Programın tamamı
#include <avr/io.h>
#define F_CPU 1000000ul
#include "util/delay.h"
int main(void)
{
DDRB |=(1<<PINB0); // pinb0 çıkış olarak yönlendiriliyor
DDRD &=~(1<<PIND0); // pind0 giriş olarak yönlendiriliyor
while (1)
{
if(bit_is_clear(PIND,0)) // butona basılıp basılmadığı kontrol ediliyor
{
PORTB|=(1<<PINB0);
_delay_ms(200);
}
else
{
PORTB&=~(1<<PINB0);
}
}
}
if(bit_is_clear(PIND,0)) atmel studio için kullanışlı , ancak bu programı ilerde başka bir derleyicide yazmak isterseniz bu macro kullanılmaya bilir. Bunun yerine daha kullanışlı bir kod yazmalıyız.
onun yerine if((PIND & 0X01)==0X00) yazsak ne yapmış oluruz. inceleyelim .burada
PIND diyerek D portunun tamamı okunuyor. ve PIND kaydeicisine kayıt ediliyor.
PIND & 0X01 = PIND kaydedicisinin içeriği 0x01 sayısı AND (bit düzeyinde) işlemine tabi tutuluyor.
Eğer butona basılmış ise d0= 0 olur. d0=0 olursa yukarıdaki bit düzeyinde AND (&) işleminin sonucu sıfır olur.
Böylece
if((PIND & 0X01)==0X00) if deyimi içindeki şart sağlanmış olur.
bu ifadeyi if(!(PIND & 0X01)) şeklinde de yazabiliriz.
en son haliyle programımız.
#define F_CPU 1000000ul
#include "util/delay.h"
int main(void)
{
DDRB |=(1<<PINB0); // pinb0 çıkış olarak yönlendiriliyor
DDRD &=~(1<<PIND0); // pind0 giriş olarak yönlendiriliyor
while (1)
{
if(!(PIND & 0X01)) // butona basıldıysa
{
PORTB|=(1<<PINB0);
_delay_ms(200);
}
else // butona basılmadıysa
{
PORTB&=~(1<<PINB0);
}
}
}
Bu programı Proteusta deneyebilisrsiniz. Ayrıca Breadboard üzerine devrenizi kurup denemeniz daha faydalı olacaktır.
program ve devre üzerinde şu değişiklikleri yaparak tekrar deneyiniz.
1- _delay_ms(200); satırını silip deneyin. aradaki farkı gözlemleyin.
2- Butonun bağlı olduğu pini boşta bırakın , herhangi bir bağlantı olmasın, led'i gözlemleyin ve durumu yorumlayın.
3- Butonu ve led'i farklı pinlere bağlayın, programınızı düzenleyin ve deneyin.
program ve devre üzerinde şu değişiklikleri yaparak tekrar deneyiniz.
1- _delay_ms(200); satırını silip deneyin. aradaki farkı gözlemleyin.
2- Butonun bağlı olduğu pini boşta bırakın , herhangi bir bağlantı olmasın, led'i gözlemleyin ve durumu yorumlayın.
3- Butonu ve led'i farklı pinlere bağlayın, programınızı düzenleyin ve deneyin.
Elinize sağlık
YanıtlaSilTeşekkür ederim .
YanıtlaSilBu yorum yazar tarafından silindi.
YanıtlaSilHocam bu avr derslerinin videosunu çekseniz daha faydalı olur.Bu arada çok güzel bir yazı.
YanıtlaSilVideo çekmek aklımda ancak zaman bulamıyorum. İnşallah birgün video da olacak.
Sil