Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Ubuntu 8.10 dziwny problem z timerazmi pod ATMEGA16

maly_elektronik 28 Sty 2009 09:42 1017 3
  • #1 28 Sty 2009 09:42
    maly_elektronik
    Poziom 23  

    Witam
    Od niedawna przerzuciłem się na środowisko linux (Ubuntu 8.10). Jażo jest jest to system unix to do pisania programów w C dla avr'ków pisze je w gedit. Testując gcc pod linuxem natrafiłem na dziwny problem. Mianowicie timer0 wogóle nie odpala pomimo dobrej konfiguracji.
    Oto najprostszy kod obsługi przerwania od timera0

    Code:

    #include <avr/io.h>
    #include <stdio.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>

    INT0_vect(TIMER0_OVF_vect)
    {
    if(bit_is_clear(PINC,0))
    PORTD=0x00;
    else
    PORTD=0xFF;
    }


    int main(void)
    {

    DDRC=0x00;
    PORTC=0xFF;
    DDRD=0xFF;

    TCCR0 = 0x03;

    TCNT0 = 0x00;
    TIMSK = 0x01;
    sei();
    }



    Poniżej makefile którego używam do kompilacji programu
    Code:

    PRG            = main

    OBJ            = main.o

    MCU_TARGET     = atmega16

    OPTIMIZE       = -O2

    DEFS           =

    LIBS           =

    # You should not have to change anything below here.

    CC             = avr-gcc

    # Override is only needed by avr-lib build system.

    override CFLAGS        = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) -I/usr/avr/include -D__AVR_ATMega16__

    override LDFLAGS       = -Wl,-Map,$(PRG).map

    OBJCOPY        = avr-objcopy

    OBJDUMP        = avr-objdump

    all: $(PRG).elf lst text eeprom

    $(PRG).elf: $(OBJ)

       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)

    clean:

       rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak

       rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)

    lst:  $(PRG).lst

    %.lst: %.elf

       $(OBJDUMP) -h -S $< > $@

    # Rules for building the .text rom images

    text: hex bin srec

    hex:  $(PRG).hex

    bin:  $(PRG).bin

    srec: $(PRG).srec

    %.hex: %.elf

       $(OBJCOPY) -j .text -j .data -O ihex $< $@

    %.srec: %.elf

       $(OBJCOPY) -j .text -j .data -O srec $< $@

    %.bin: %.elf

       $(OBJCOPY) -j .text -j .data -O binary $< $@

    # Rules for building the .eeprom rom images

    eeprom: ehex ebin esrec

    ehex:  $(PRG)_eeprom.hex

    ebin:  $(PRG)_eeprom.bin

    esrec: $(PRG)_eeprom.srec

    %_eeprom.hex: %.elf

       $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@

    %_eeprom.srec: %.elf

       $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@

    %_eeprom.bin: %.elf

       $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@

    # Every thing below here is used by avr-libc's build system and can be ignored

    # by the casual user.

    FIG2DEV                 = fig2dev

    EXTRA_CLEAN_FILES       = *.hex *.bin *.srec

    dox: eps png pdf

    eps: $(PRG).eps

    png: $(PRG).png

    pdf: $(PRG).pdf

    %.eps: %.fig

       $(FIG2DEV) -L eps $< $@

    %.pdf: %.fig

       $(FIG2DEV) -L pdf $< $@

    %.png: %.fig

       $(FIG2DEV) -L png $< $@


    PS To nie wina mikrokontrolera gdyż próbowałem na paru niezależnych

    0 3
  • #2 28 Sty 2009 10:08
    GienekS
    Poziom 32  

    Ten program na pewno nie będzie działał poprawnie bo się będzie w kółko resetował. Na końcu brak pętli w której go zatrzymasz.

    0
  • Pomocny post
    #3 28 Sty 2009 10:30
    krzemowy
    Poziom 19  

    Zakładam że kompilujesz w takim GCC jak ja. Spróbuj tego:

    Code:

    #include <avr/io.h>
    //#include <stdio.h>  niepotrzebne, bez tego też działa
    #include <avr/interrupt.h>
    //#include <avr/signal.h>  tej biblioteki się nie stosuje - patrz gcc-libc

    ISR(TIMER0_OVF_vect)   //po co tam miałeś INT0_vect?
    {
        PORTD ^= 0xFF;  //będziemy mieli przebieg na wyjściu, łatwe do wykrycia woltomierzem - pomiar da 2.5V
        /*
        if(bit_is_clear(PINC,0))  //jest gdzieś taki define?
            PORTD=0x00;
        else
            PORTD=0xFF;
        */
    }


    int main(void)
    {
        DDRC=0x00;
        PORTC=0xFF;
        DDRD=0xFF;
        TCCR0 = _BV(CS00) | _BV(CS01); //TCCR0 = 0x03;  zakładam że miałeś na myśli preskaler 64 i define _BV istnieje
        TCNT0 = 0x00;    //to jest w zasadzie niepotrzebne, przerwanie i tak by zadziałało
        TIMSK = _BV(TOIE0); //TIMSK = 0x01;
        sei();
        while(1);
    }

    0
  • #4 28 Sty 2009 10:31
    maly_elektronik
    Poziom 23  

    Wielkie dzięki krzemowy. Nie zauważyłem tego że dałem INT0 a nie ISR :(
    PS. Tak jest taka definicja bit_is_clear(PINx,NRpinu) jak i bit_is_set jeszcze jest pętla loop_until_bit_is_set/clear(...) -> powoduje sprawdzanie w pętli czy bit jest ustawiony/nie ustawiony

    0