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;
}
her girdiğin forumda bu soruyu sorup bir daha uğramıyor musun?
başka forumda cevap verildi.
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.
Kimse yardım etmeyecek mi?
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.
program dosyasını ve simülasyon dosyasını gönderir misin.
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.
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
}
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;
}
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
}
efe hocam OCR1A'ya 4mhz crystal için vermem gerek değer ne?
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?
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++;
}
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?
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.
kimse yardım etmecek mi arkadaşlar?