WinAVR ile 7segment Sayıcı (8li)

Başlatan ahmet2004, 01 Aralık 2007, 19:09:55

ahmet2004


//*************************************************************************
//****** 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.	
		}
 }
}

ahmet2004