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

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

nelik1987 02 Paź 2008 17:32 3687 20
  • #1 5592105
    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.
    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
  • Pomocny post
    #2 5592152
    skynet_2
    Poziom 26  
    dołącz
    #include <util/delay.h>

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

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

    opóźnia ale jest wykowywane bardzo szybko i nawet tego nie zauważysz[około 1ms]
  • #4 5592390
    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?

    
    ###############################################################################
    # 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/*)
    
    
  • #6 5592461
    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
  • #7 5592650
    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
  • #8 5592697
    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

    #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);
    
      }
    }
    
  • #9 5592755
    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
  • #11 5592999
    Konto nie istnieje
    Konto nie istnieje  
  • #12 5593056
    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
  • #13 5599948
    Pijopic
    Poziom 17  
    A po kiego grzyba kilka razy to powtarzac co mozna zrobic raz...
    
    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); 
    }
    
  • #16 5600389
    piotr_go
    Konstruktor DIY elektronika
    @skynet_2
    Co ty gadasz, używałem ją w sofcie na attiny13 i spokojnie wchodzi, jeszcze sporo miejsca zostaje.
  • #18 5600565
    piotr_go
    Konstruktor DIY elektronika
    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ł)
  • #19 5601824
    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...
  • #20 5603388
    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
  • #21 5603917
    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.
REKLAMA