Atmel atmega8 karşılaştığım sorun.Büyük hocalarımdan yardım bekliyorum.

Başlatan raconcu, 13 Ağustos 2013, 16:06:12

raconcu

atmega8 serisini c dili ile yazmayı öğreniyorum.Bir program yapmaya karar verdim.Programda PortB.0 18dk boyunca lojik 1 olacak daha sonra 8 sn boyunca lojik 0 olacaktır ve bu döngü sonsuz şekilde devam edecektir. Yazdığım programda proteusta similasyon yaptığımda (crystal frekansı ayarlı) 18 dk'lık enerjilenmesi gereken portB.0 19 dakika 26 saniye enerjilenmektedir.Hocalarımdan yardım bekliyorum acaba nerde hata yaptım?şimdiden çok teşekkürler.Programı altta yazdım.Kullandığım derleyici avr studio 4 ve winavr'dir.

#include <avr/io.h>

#define F_CPU 4000000UL

#include <util/delay.h>

unsigned int i;

void main()

{

DDRB = 0xFF;
PORTB = 0x00;

while(1)

{

PORTB = 0x01;

for(i=0; i<4320; i++)
_delay_ms(250);

PORTB = 0x00;

for(i=0;i<32;i++)
_delay_ms(250);

}

return 0;

}


bocek

her girdiğin forumda bu soruyu sorup bir daha uğramıyor musun?
başka forumda cevap verildi.
1 ya da 0. işte 'bit'ün mesele..

raconcu

başka forumda aradığımı bulamadım hocam öğrenci adamım ben öğrencem tabikide...kendime yeni bişeyler katmak istiyorum kızma sende bana hak ver.


SERRO EFE

Bu şekilde delay fonksiyonları ile uğraşmak yerine timer kurup daha hassas zamanlayıcı elde ederseniz daha iyi sonuçlar alırsınız.
timer örnekleri ile ilgili link https://sites.google.com/site/qeewiki/books/avr-guide/timer-on-the-atmega8
Yada sapma hesap edilip ona göre oranlayıp for-next çevrim sayısı yeniden hesaplanmalı.
for-next sayısını 4001 yaptığında yaklaşık olarak işini görür.

run

özgürlük için teknoloji

raconcu

Alıntı yapılan: SERRO EFE - 14 Ağustos 2013, 12:08:04
Bu şekilde delay fonksiyonları ile uğraşmak yerine timer kurup daha hassas zamanlayıcı elde ederseniz daha iyi sonuçlar alırsınız.
timer örnekleri ile ilgili link https://sites.google.com/site/qeewiki/books/avr-guide/timer-on-the-atmega8
Yada sapma hesap edilip ona göre oranlayıp for-next çevrim sayısı yeniden hesaplanmalı.
for-next sayısını 4001 yaptığında yaklaşık olarak işini görür.

SERRO EFE hocam öncelikle yardımın için çok teşükkür ederim.Atmega8'in yapısını incelediğimde timer/counter özelliğinin Port D (PD0..PD7)'de olduğunu gördüm o satırı programıma eklermisin denemem için programım yukarıda duruyor senin kadar profesyonel değilim.Programa satır olarak eklersen çok sevinirim şimdiden çok teşekkürler.

SERRO EFE

Vermiş olduğum linkteki programın biri  1sn kesme oluşturuyor alta ekledim. Kesmeye her gelişinde sayacı 1 arttır while içinde istediğin sayıya gelmişmi karşılaştır ona göre pini 1-0 yap. Uğraş biraz. Prescalar 16mhz için ayarlı sen 4mhz çalışıyon prescaları ona göre düzenlemen lazım yada timer 4 kat hızlı çalışacak.
this code sets up timer1 for a 1s  @ 16Mhz Clock (mode 4)
#include <avr/io.h>
#include <avr/interrupt.h>

unsigned int i; 
int main(void)
{
    OCR1A = 15624;

    TCCR1B |= (1 << WGM12);
    // Mode 4, CTC on OCR1A

    TIMSK |= (1 << OCIE1A);
    //Set interrupt on compare match

    TCCR1B |= (1 << CS12) | (1 << CS10);
    // set prescaler to 1024 and start the timer


    sei();
    // enable interrupts


    while (1);
    {
        // we have a working Timer
    }
}

ISR (TIMER1_COMPA_vect)
{
i++;
    // action to be done every 1 sec
}

raconcu

Efe hocam dediklerinden hiç bişey anlamıyorum ben daha başlangıç seviyesindeyim dediklerini yapamıyorum üzgünüm.kesmeler zamanlayıcılar daha ileri seviyeler için ben başlangıçtayım daha.

mesaj birleştirme:: 14 Ağustos 2013, 15:21:03

Efe hocam şöyle bişeyler yapmaya çalıştım yanlışım veya eksiğim varsa düzeltirsin.Bir de datasheette portD'de timer/intterrups olduğu görülüyor o yüzden D portunu kullandım.OCR1A değerinide 4001 yaptım.

#include <avr/io.h>

#define F_CPU 4000000UL

#include <util/delay.h>

#include <avr/interrupt.h>

unsigned int i;

int main(void)

{


DDRD = 0xFF;
PORTD = 0x00;


OCR1A = 4001;

TCCR1B |= (1 << WGM12);
// Mode 4, CTC on OCR1A

TIMSK |= (1 << OCIE1A);
//Set interrupt on compare match

TCCR1B |= (1 << CS12) | (1 << CS10);
// set prescaler to 1024 and start the timer


sei();
// enable interrupts


while (1);
{
PORTD = 0x01;

for(i=0; i<4320; i++)
_delay_ms(250);

PORTD = 0x00;

for(i=0;i<32;i++)
_delay_ms(250);

}

}

ISR (TIMER1_COMPA_vect)
{
i++;
    // action to be done every 1 sec
}
}

return 0;

}

SERRO EFE

Timer kesmesinin portla herhangi bir alakası yok bu uygulamada. Bu programda timer i mcu içersinde kendi kendine sayan bir sayaç olarak düşün.Sayac istediğin sayıya geldiğinde sana haber verecek şekilde ayarlıyorsun sonra sayac  ben ayarladığın zaman kadar bekledim süre geçti ne yapacaksan zamanı geldi diyor.
Programı derleyip dene portbyi toggle yapıyor.
this code sets up timer1 for a 1s  @ 16Mhz Clock (mode 4)
#include <avr/io.h>
#include <avr/interrupt.h>

unsigned int i; 
int main(void)
{
    OCR1A = 15624;

    TCCR1B |= (1 << WGM12);
    // Mode 4, CTC on OCR1A

    TIMSK |= (1 << OCIE1A);
    //Set interrupt on compare match

    TCCR1B |= (1 << CS12) | (1 << CS10);
    // set prescaler to 1024 and start the timer
   DDRB = 0xFF;
   PORTB = 0x00;

    sei();
    // enable interrupts


    while (1);
    {
        // we have a working Timer
    }
}

ISR (TIMER1_COMPA_vect)
{
PORTB ^= 0x80; 

    // action to be done every 1 sec
}

raconcu


raconcu

derledim şu şekilde

#include <avr/io.h>

#define F_CPU 4000000UL

#include <util/delay.h>

#include <avr/interrupt.h>

unsigned int i;

int main(void)

{


DDRB = 0xFF;
PORTB = 0x00;


OCR1A = 4001;

TCCR1B |= (1 << WGM12);
// Mode 4, CTC on OCR1A

TIMSK |= (1 << OCIE1A);
//karşılaştırma üzerinde kesme

TCCR1B |= (1 << CS12) | (1 << CS10);
// set prescaler to 1024 and start the timer


sei();
// enable interrupts


while (1);
{
PORTB = 0x01;

for(i=0; i<4320; i++)
_delay_ms(250);

PORTB = 0x00;

for(i=0;i<32;i++)
_delay_ms(250);

}

}

ISR (TIMER1_COMPA_vect)
{
i++;
    // action to be done every 1 sec


return 0;

}


mesaj birleştirme:: 14 Ağustos 2013, 15:55:57

Efe hocam kesmeleri ve hassas zamanlayıcıları beceremiyorum öğrenmem için programdaki hatalı ve eksik yerleri tamamlarmısın?

SERRO EFE

Sanırım istediğin program bi dene bakalım
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned int i; 
int main(void)
{
    OCR1A = 15624;

    TCCR1B |= (1 << WGM12);


    TIMSK |= (1 << OCIE1A);


    TCCR1B |= (1 << CS12) | (0 << CS10);

   DDRB = 0xFF;
   PORTB = 0x00;

    sei();



    while (1)
	{
     
//	 if (PINB0 == 0){
	if(!PINB & (1 << 0)){
	if (i>=5){  // KAPALI KALMA SÜRESİ 5 YERİNE İSTEDİĞİN ZAMANI SANİYE CİNSİNDEN GİR
	i =0;
	PORTB = 0X01;
	}
	}


	if(PINB & (1 << 0)){
	if (i>=10){ // AÇIK KALMA SÜRESİ 10 YERİNE İSTEDİĞİN ZAMANI SANİYE CİNSİNDEN GİR
	i =0;
	PORTB = 0;
	}
	}
	}


}

ISR (TIMER1_COMPA_vect)
{
i++;

}

raconcu

Serro efe hocam programlara her zaman osilatör frekansının girilmesi gerekmiyor mu? sen girmemişsin, hesaplamalar 4 mhz'lik crystal'e göre mi?

raconcu

Hocam derleyici de senin programını derledim.(avr studio 4 ve winavr)Bide crystal frekansı 4 mhz göre mi hesaplı?Hesaplı değil sanırım 4mhz'lik crystal'ê göre değerler ne olacak?Devre hazır 4mhz crystalli

#include <avr/io.h>

#include <avr/interrupt.h>

unsigned int i;

int main(void)

{


    OCR1A = 15624;

    TCCR1B |= (1 << WGM12);


    TIMSK |= (1 << OCIE1A);


    TCCR1B |= (1 << CS12) | (0 << CS10);

   DDRB = 0xFF;
   PORTB = 0x00;

    sei();



    while (1)
    {
     
//    if (PINB0 == 0){
    if(!PINB & (1 << 0)){
    if (i>=480){  // KAPALI KALMA SÜRESİ 5 YERİNE İSTEDİĞİN ZAMANI SANİYE CİNSİNDEN GİR( 8 saniye kapalı kalacak)
    i =0;
    PORTB = 0X01;
    }
    }


    if(PINB & (1 << 0)){
    if (i>=1080){ // AÇIK KALMA SÜRESİ 10 YERİNE İSTEDİĞİN ZAMANI SANİYE CİNSİNDEN GİR(18 dk açık kalacak)
    i =0;
    PORTB = 0;
    }
    }
    }


}

ISR (TIMER1_COMPA_vect)
{
i++;

}


mesaj birleştirme:: 14 Ağustos 2013, 21:49:56

Programı isiste simulasyon yaptım 17 dakika enerjisiz kalıyor sonra enerjileniyor ve hep enerjilenmiş kalıyor programda hata var hocam.

Benim yazmak istediğim(4mhz crystalle) 18 dk enerjilenecek 8 sn'ye enerjisiz kalacak ve bu sonsuz şekilde devam edecek.

Kontrol edermisin.