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.

[ATtiny26][jezyk C] Zatrzymywanie programu = przerwanie?

nelik1987 02 Paź 2008 17:32 3477 20
  • #1 02 Paź 2008 17:32
    nelik1987

    Poziom 31  

    Witam od paru dni bawię się w programowanie uC, doszedłem już do etapu ustawiania stanów na poszczególnych bitach, odczytania wartości bitów i nadszedł czas by program w którymś momencie zatrzymał się na chwilę na przykład po to by zamrugać kilkukrotnie diodą LED (dalej chciał bym sterować silnikiem krokowym ale dla uproszczenia stosuję na razie diody led).

    I teraz mam problem bo na przykład w bascomie była bardzo fajna i wygodna funkcja "waitms" (czekaj x milisekund) no a w C czyli jezyku jakiego uzywam nic takiego nie znalazłem, wiem ze trzeba użyć przerwań ale niestety czytałem o tym w książce i na wieli stronach www i nic z tego nie rozumiem.

    jeszcze jedno pytanie dlaczego amatorskie użycie pętli np.

    Code:
    for(i=0;i<1000;i++)
    
    {
    }


    robiącej "NIC" nie opóxnia przełączania diod, bo napisałem program tak, że 4 diody miały zapalać się kolejno z jakimś opóźnieniem, jezeli to opanuje bedę mógł sterowć w prosty sposób silnikiem krokowym

    0 20
  • Pomocny post
    #2 02 Paź 2008 17:45
    skynet_2
    Poziom 26  

    dołącz

    Code:
    #include <util/delay.h>

    i masz
    Code:
    _delay_ms();//milisekundy
    
    _delay_us();//mikrosekundy

    pętla
    Code:
    for(i=0;i<1000;i++) { }

    opóźnia ale jest wykowywane bardzo szybko i nawet tego nie zauważysz[około 1ms]

    0
  • #4 02 Paź 2008 18:56
    nelik1987

    Poziom 31  

    no właśnie wszystko działa fajnie tylko wydaje mi się ze mam źle ustawione F_CPU i ustawiony czas nie jest realny

    pokażę mój plik makefile bo tam się chyba to ustawia prawda?

    Code:

    ###############################################################################
    # Makefile for the project trzeci_projekt
    ###############################################################################

    ## General Flags
    PROJECT = trzeci_projekt
    MCU = attiny26
    TARGET = trzeci_projekt.elf
    CC = avr-gcc.exe

    ## Options common to compile, link and assembly rules
    COMMON = -mmcu=$(MCU)

    ## Compile options common for all C compilation units.
    CFLAGS = $(COMMON)
    CFLAGS += -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
    CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d

    ## Assembly specific flags
    ASMFLAGS = $(COMMON)
    ASMFLAGS += $(CFLAGS)
    ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2

    ## Linker flags
    LDFLAGS = $(COMMON)
    LDFLAGS +=  -Wl,-Map=trzeci_projekt.map


    ## Intel Hex file production flags
    HEX_FLASH_FLAGS = -R .eeprom

    HEX_EEPROM_FLAGS = -j .eeprom
    HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
    HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings


    ## Objects that must be built in order to link
    OBJECTS = trzeci_projekt.o

    ## Objects explicitly added by the user
    LINKONLYOBJECTS =

    ## Build
    all: $(TARGET) trzeci_projekt.hex trzeci_projekt.eep trzeci_projekt.lss size

    ## Compile
    trzeci_projekt.o: ../trzeci_projekt.c
       $(CC) $(INCLUDES) $(CFLAGS) -c  $<

    ##Link
    $(TARGET): $(OBJECTS)
        $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)

    %.hex: $(TARGET)
       avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@

    %.eep: $(TARGET)
       -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0

    %.lss: $(TARGET)
       avr-objdump -h -S $< > $@

    size: ${TARGET}
       @echo
       @avr-size -C --mcu=${MCU} ${TARGET}

    ## Clean target
    .PHONY: clean
    clean:
       -rm -rf $(OBJECTS) trzeci_projekt.elf dep/* trzeci_projekt.hex trzeci_projekt.eep trzeci_projekt.lss trzeci_projekt.map


    ## Other dependencies
    -include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)

    0
  • #5 02 Paź 2008 19:04
    skynet_2
    Poziom 26  

    do linii

    Code:
    CFLAGS +=

    dodaj
    Code:
    -DF_CPU=1000000UL

    jeżeli taktujesz 1Mhz.

    Pozdrawiam

    0
  • #6 02 Paź 2008 19:19
    nelik1987

    Poziom 31  

    a attiny z wewnętrznym oscylatorem działa na 1MHz? mi się wydawało ze wewnętrzny oscylator jest ustawiony domyślenie na 4MHz

    znalazłem w ustawieniach programu gdzie można wpisać częstotliwość pracy kostki :)

    korzystam z AVRStudio4

    0
  • #7 02 Paź 2008 20:12
    Dr.Vee
    VIP Zasłużony dla elektroda

    Przy domyślnych ustawieniach fuse bitów attiny26 jest taktowany wewnętrznym zegarem 1MHz.

    Do generowania przebiegów z wysokimi częstotliwościami (silnik krokowy?) możesz wykorzystać wbudowane timery i sprzętową generację impulsów na pinach OC1A i OC1B.

    Pozdrawiam,
    Dr.Vee

    0
  • #8 02 Paź 2008 20:23
    nelik1987

    Poziom 31  

    czyli chodzi Ci o piny PB0-PB3 w tej chwili mam to podłączone do pinów PA0-PA3 a jaka jest różnica miedzy tymi pinami?

    bo ogólnie doszedłem do tego co chciałem silnik się kreci

    pokaże program ale proszę się nie śmiać bo to jeden z pierwszych moich programów i na pewno nie jest doskonały

    program miał obracać silnikiem o 360 stopni i czekać chwile i ponawiać operacje no i chyba do tego doszedłem

    Code:
    #include <avr/io.h>                        // dostęp do rejestrów
    
    #include <util/delay.h>

    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))


    int main( void )                        // program główny
    {

    unsigned int i = 60, a=12;                  // czas w milisekundach

      sbi(DDRA,0);                      // użyj linii PA0 jako wyjście
      sbi(DDRA,1);                    // użyj linii PA1 jako wyjście
      sbi(DDRA,2);                      // użyj linii PA2 jako wyjście
      sbi(DDRA,3);                    // użyj linii PA3 jako wyjście   
                       


      while(1)                               // pętla nieskończona
      {

      for(a=0;a<12;a++)
      {
        sbi(PORTA,0);                        // zapal diodę LED podłączoną do linii PA0
       
    _delay_ms(i);                      // czekaj 500 milisekund

       
       cbi(PORTA,0);                        // zgaś  diodę LED podłączoną do linii PA0
    //===================================================================================   
       sbi(PORTA,1);                        // zapal diodę LED podłączoną do linii PA1
       
    _delay_ms(i);                      // czekaj 500 milisekund
       
       cbi(PORTA,1);                        // zgaś  diodę LED podłączoną do linii PA1
    //====================================================================================
       sbi(PORTA,2);                        // zapal diodę LED podłączoną do linii PA2

    _delay_ms(i);                      // czekaj 500 milisekund
       
       cbi(PORTA,2);                        // zgaś  diodę LED podłączoną do linii PA2
    //====================================================================================
       sbi(PORTA,3);                        // zapal diodę LED podłączoną do linii PA3

    _delay_ms(i);                      // czekaj 500 milisekund
       
       cbi(PORTA,3);                        // zgaś  diodę LED podłączoną do linii PA3
    }

    _delay_ms(1300);

      }
    }

    0
  • #9 02 Paź 2008 20:37
    Dr.Vee
    VIP Zasłużony dla elektroda

    Z dokumentacji funkcji _delay_ms() wynika, że maksymalne opóźnienie to 262.14ms / F_CPU w MHz - jak chcesz dłuższe opóźnienia, to musisz sam zrobić zewnętrzną pętlę.

    Z dodatkowymi funkcjami pinów mikrokontolera jest tak, że są przypisane do konkretnych nóżek i nie można tego zmienić. Dlatego warto się zastanawiać co gdzie podłączać na etapie projektowania. Ale jak Twój program działa, to chyba wszystko gra i nie potrzebujesz sprzętowych timerów :)

    Pozdrawiam,
    Dr.Vee

    0
  • #10 02 Paź 2008 21:33
    nelik1987

    Poziom 31  

    a to ciekawe bo ja wstawiłem _delay_ms(2500); i działa doskonale :P czyli czeka 2,5 sekundy

    0
  • #11 02 Paź 2008 21:35
    Anonymous
    Użytkownik usunął konto  
  • #12 02 Paź 2008 21:46
    Dr.Vee
    VIP Zasłużony dla elektroda

    Oczywiście. Coś mi się na oczy rzuciło i dopiero teraz to doczytałem :)

    Pozdrawiam,
    Dr.Vee

    0
  • #13 05 Paź 2008 00:19
    Pijopic
    Poziom 17  

    A po kiego grzyba kilka razy to powtarzac co mozna zrobic raz...

    Code:

    for(b=0; b<=3; b++)
    {
    PORTA|=_BV(b);               // zapal diodę LED podłączoną do linii PA(b)
    _delay_ms(i);                   // czekaj 500 milisekund
    PORTA&=~_BV(b);
    }

    0
  • #14 05 Paź 2008 08:34
    skynet_2
    Poziom 26  

    z tego co pamiętem funkcja

    Code:
    _delay_ms(i);

    zajmuje sporo miejsca, gdzieś 3,5 KiB, pomieważ kompilator nie może tego zoptymalizować.

    0
  • #15 05 Paź 2008 09:10
    nelik1987

    Poziom 31  

    to jaki inny sposób wykorzystać?

    0
  • #16 05 Paź 2008 10:24
    piotr_go
    Poziom 27  
  • #17 05 Paź 2008 10:42
    skynet_2
    Poziom 26  

    ale używałeś ze zmienna bo np.

    Code:
    _delay_ms(50);

    zajmuje ok 8B
    natomiast
    _delay_ms(i);
    Code:
    zajmuje ok 3,5KiB

    0
  • #18 05 Paź 2008 11:29
    piotr_go
    Poziom 27  

    Ze zmienną nie, zawsze podawałem wartość.
    Do zmiennej wartości używałem zwykle timera bo potrzebowałem większej dokładności.
    Zawsze można samemu napisać odpowiednią funkcję jeżeli oryginalna za dużo zajmuje.
    Chociaż to trochę dziwne żeby zajmowało 3.5kB. Przecież to tylko dodatkowa pętla w _delay_ms(1). (przynajmniej ja bym tak zrobił)

    0
  • #19 05 Paź 2008 17:25
    Pijopic
    Poziom 17  

    To ile zajmuje zalezy od typu zmiennej, mozna tak napisac kod, ze zajmuje tyle samo z stala liczbowa jak i przypisana zmienna...

    0
  • #20 05 Paź 2008 23:54
    Dr.Vee
    VIP Zasłużony dla elektroda

    Pijopic napisał:
    To ile zajmuje zalezy od typu zmiennej, mozna tak napisac kod, ze zajmuje tyle samo z stala liczbowa jak i przypisana zmienna...


    Oczywiście, ale tylko w przypadku gdy wartość zmiennej może być obliczona w trakcie kompilacji. W takim przypadku "zmienna" staje się stałą :)

    Pozdrawiam,
    Dr.Vee

    0
  • #21 06 Paź 2008 11:12
    Pijopic
    Poziom 17  

    Akurat tu jest taki przypadek bo "i" jest stala w kodzie autora lecz zadeklarował ja tak, ze kodu bedzie duzo :) , ale to nie ma znaczenia ani w tym przypadku ani w przypadku rzeczywistej zmiennej ktorej wartosci kompilator nie zna, ma znaczenie tylko sposob w jaki zadeklaruje sie zmienna.

    0
  Szukaj w 5mln produktów