Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => Atmel => Konuyu başlatan: ahmet2004 - 01 Aralık 2007, 19:09:55

Başlık: WinAVR ile 7segment Sayıcı (8li)
Gönderen: ahmet2004 - 01 Aralık 2007, 19:09:55
(http://img47.imageshack.us/img47/1516/devrekwf6.jpg)

//*************************************************************************
//****** Hazırlayan ahmet2004 ************ Atmel winAVR *******************
//*************************************************************************
//*************************************************************************
//******** Xtal = 8 Mhz internal ******************************************
//*************************************************************************
//*************************************************************************
//*************************************** 30 Kasım 2007 16:58 *************
//*************************************************************************

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define DISPLAY1 1
#define DISPLAY2 2
#define DISPLAY3 4
#define DISPLAY4 8
#define DISPLAY5 16
#define DISPLAY6 32
#define DISPLAY7 64
#define DISPLAY8 128

#define DISPLAYPORT PORTB
#define DATAPORT PORTD
#define DISPLAY_DELAY 2

static void segment7(uint16_t say);
volatile uint32_t deger=0;

// Timer1 kesme fonksiyonu
ISR(TIMER1_OVF_vect){
cli();
segment7(deger); // deger değerini displaye gönderir
TCNT1H=0xFF; // Timer1'i yeniden 6.4ms'de bir kesme oluşturacak
TCNT1L=0xDB; // şekilde doldur.
sei();
}


static void delay_ms(uint16_t ms){
   for(uint16_t x=0;x<ms;x++){
   _delay_ms(1);
   }
}

static void mcu_init(void){

DDRB =0xFF; // B portunu çıkış yap
PORTB =0xFF; // B portunun tüm pinleri 1 olsun
DDRD =0x1F; // D portunun üst 4 pini giriş alt 4 pini cikis yap
PORTD =0xF0; // D portu 11110000 olur

TCCR1A =0x00;
TCCR1B =0x05; // Çalışma frekansı(8) / 1024 = 7812.5 Hz (128uS)
TCNT1H =0xFF;
TCNT1L =0xDB; // FF9B ondalık olarak 65499'e eşittir.Bu değer
ICR1H =0x00; // 16 bitlik en büyük değer olan 65535'i geçtiğinde
ICR1L =0x00; // sıfırlar ve kesme oluşturulur.Buda 36 adımdır(65535-65499)=36
OCR1AH =0x00; // 36 * 128uS = 4,6 ms olur.
OCR1AL =0x00;
OCR1BH =0x00;
OCR1BL =0x00;

TIMSK =0x04; // Timer1 icin interrupt etkinleştirilir.
}

static void segment7(uint16_t say){
uint8_t birler,onlar,yuzler,binler,onbinler,yuzbinler,milyonlar,milyarlar;

milyarlar = say/10000000;
say -= milyarlar*10000000;
milyonlar = say/1000000;
say -= milyonlar*1000000;
yuzbinler = say/100000;
say -= yuzbinler*100000;
onbinler = say/10000;
say -= onbinler*10000;
binler = say/1000;
say -= binler*1000;
yuzler = say/100;
say -= yuzler*100;
onlar = say/10;
say -= onlar*10;
birler = say;

DISPLAYPORT = ~DISPLAY1; //birinci display aktif
DATAPORT = birler; //birler basamagini PORTD'ye gonder
delay_ms(DISPLAY_DELAY); //Gecikme

DISPLAYPORT = ~DISPLAY2;
DATAPORT = onlar;
delay_ms(DISPLAY_DELAY);

DISPLAYPORT = ~DISPLAY3;
DATAPORT = yuzler;
delay_ms(DISPLAY_DELAY);

DISPLAYPORT = ~DISPLAY4;
DATAPORT = binler;
delay_ms(DISPLAY_DELAY);

DISPLAYPORT = ~DISPLAY5;
DATAPORT = onbinler;
delay_ms(DISPLAY_DELAY);

DISPLAYPORT = ~DISPLAY6;
DATAPORT = yuzbinler;
delay_ms(DISPLAY_DELAY);

DISPLAYPORT = ~DISPLAY7;
DATAPORT = milyonlar;
delay_ms(DISPLAY_DELAY);

DISPLAYPORT = ~DISPLAY8;
DATAPORT = milyarlar;
delay_ms(DISPLAY_DELAY);
}

//*******************************************************************************
//*******************************************************************************
//*************************    Program Başlangıcı     ***************************
//*******************************************************************************
//********************************************************************** @2007 **
//*******************************************************************************
int main(void){
mcu_init();
sei();

while(1) {
if(deger > 99999999) deger = 0; // değer 99999999 dan büyükse  sıfırla

if (bit_is_clear(PIND, 7)) // Eğer butona basıldıysa
{
delay_ms(50);
loop_until_bit_is_set(PIND, 7); // Butonda el çekilmesini bekleme
deger++; // sayaç değerini 1 artır.
}

if (bit_is_clear(PIND, 6)) // Eğer butona basıldıysa
{
delay_ms(50);
loop_until_bit_is_set(PIND, 6); // Butonda el çekilmesini bekleme
deger--; // sayaç değerini 1 azalt.
}
}
}

Başlık: WinAVR ile 7segment Sayıcı (8li)
Gönderen: ahmet2004 - 01 Aralık 2007, 19:17:51
Proteus 7.2 animasyon dosyası:
Animasyon... (http://rapidshare.com/files/73588070/8liSayac.DSN.html)


Resim:
(http://img162.imageshack.us/img162/7227/sayac4ll8.gif)