logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Problem z instrukcjami cbi i sbi [atmega16][ avr-gcc]

elektor18 28 Lut 2010 13:55 3104 5
REKLAMA
  • #1 7763204
    elektor18
    Poziom 18  
    Witam
    Mam problem z kompilacją programu już na samym podstawowym etapie jego pisania:
    #define F_CPU 1000000L
    #include <avr/io.h>
    #include <util/delay.h>

    /******************************************************
    Definicje stałych
    *******************************************************/
    #define F_CPU 1000000 /* 1MHz zegar procesora */
    /**************************************************************
    Koniec definicji stałych
    **************************************************************/
    //definiujemy stany portu sterujacego dioda LED
    #define LED_ON sbi(DDRB,PB1)
    #define LED_OFF cbi(DDRB,PB1)

    Potem w programie głównym mam wywołanie LED_ON i OFF i tyle dla testów a wynik kompilacji taki:


    > "make.exe" all

    -------- begin --------
    avr-gcc (WinAVR 20100110) 4.3.3
    Copyright (C) 2008 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


    Compiling C: LED.c
    avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./LED.lst -std=gnu99 -MMD -MP -MF .dep/LED.o.d LED.c -o LED.o
    LED.c:1:1: warning: "F_CPU" redefined
    <command-line>: warning: this is the location of the previous definition
    LED.c:11:1: warning: "F_CPU" redefined
    LED.c:1:1: warning: this is the location of the previous definition
    LED.c: In function 'main':
    LED.c:25: warning: implicit declaration of function 'sbi'
    LED.c:27: warning: implicit declaration of function 'cbi'

    Linking: LED.elf
    avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=LED.o -std=gnu99 -MMD -MP -MF .dep/LED.elf.d LED.o --output LED.elf -Wl,-Map=LED.map,--cref -lm
    LED.o: In function `main':
    C:\kurs_avrgcc\01/LED.c:25: undefined reference to `sbi'
    C:\kurs_avrgcc\01/LED.c:27: undefined reference to `cbi'
    make.exe: *** [LED.elf] Error 1

    > Process Exit Code: 2
    > Time Taken: 00:01


    Dlaczego nie mogę używać sbi oraz cbi?
  • REKLAMA
  • Pomocny post
    #2 7763306
    janbernat
    Poziom 38  
    Porting programs that use the deprecated sbi/cbi macros

    Access to the AVR single bit set and clear instructions are provided via the standard C bit manipulation commands. The sbi and cbi macros are no longer directly supported. sbi (sfr,bit) can be replaced by sfr |= _BV(bit) .

    i.e.: sbi(PORTB, PB1); is now PORTB |= _BV(PB1);

    This actually is more flexible than having sbi directly, as the optimizer will use a hardware sbi if appropriate, or a read/or/write operation if not appropriate. You do not need to keep track of which registers sbi/cbi will operate on.

    Likewise, cbi (sfr,bit) is now sfr &= ~(_BV(bit));
  • REKLAMA
  • Pomocny post
    #3 7763314
    baxter007
    Poziom 11  
    na początku najprawdopodobniej definiujesz F_CPU trzy razy niepotrzebnie
    LED.c:1:1: warning: "F_CPU" redefined

    jak juz chcesz dla pewności definiować nie tylko w makefile to skorzystaj z
    
    #ifndef F_CPU
    #define F_CPU 16000000UL
    #endif
    


    co do sbi cbi w nowszych wersjach winavr odstąpiono do tego, i odpowiednio :

    #define LED_ON DDRB|=_BV(1)
    #define LED_OFF DDRB&=~_BV(1)
  • REKLAMA
  • #4 7764049
    elektor18
    Poziom 18  
    A no i z takim zapisem też się spotkałem ale nie wiedziałem że to tak jest rozwiązane. Oczywiście obaj koledzy dostają "pomógł" ale jeszcze jeśli możecie to opiszcie co dokładnie oznacza to polecenie DDRx|=_BV(1) i DDRx&=~_BV(1) .Dzięki wielkie za odpowiedzi:)
  • REKLAMA
  • #5 7764354
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Zamiast tego durnego i nieprzenośnego nigdzie indziej zapisu używaj "standardowego":

    zmienna |= (1 << bit); // set
    zmienna &= ~(1 << bit); // clear

    albo

    zmienna |= (1 << bit1) | (1 << bit2) | (1 << bit3); // set
    zmienna &= ~((1 << bit1) | (1 << bit2) | (1 << bit3)); // clear

    http://pl.wikibooks.org/wiki/C/Operatory#Operacje_bitowe

    4\/3!!
  • #6 7764579
    elektor18
    Poziom 18  
    OK raz jeszcze wielkie dzięki za wyjaśnienie.Pozdrawiam :)
REKLAMA