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

[AVR][asembler][Sterowanie diodą LED]

maciej_333 19 Paź 2009 18:33 3325 5
REKLAMA
  • #1 7148687
    maciej_333
    Poziom 38  
    Jestem początkujący jeśli chodzi o mikrokontrolery AVR. Znam dobrze natomiast '51. Chcę napisać program naprzemiennie gaszący i zapalający diodę LED. Dioda jest podpięta katodą do linii portu, anoda przez rezystor do +5V. W związku z tym dioda jest sterowana zerem. Poniżej przedstawiam mój kod. Częstotliwość zegara wynosi 16MHz.
    .nolist
    
    .include "m8def.inc"
    
    .list
    
    
    
    .cseg
    
    .org 0
    
    rjmp begin
    	delay1:
    		ldi R16, 0
    		del1:
    			inc R16
    		brne del1
    	ret
    
    	delay2:
    		ldi R17, 0
    		del2:
    			rcall delay1
    			inc R17
    		brne del2
    	ret
    
    	delay3:
    		ldi R18, 0
    		del3:
    			rcall delay2
    			inc R18
    		brne del3
    	ret
    
    begin:
    
    ldi R17, high(RAMEND) ;inicjalizacja stosu
    ldi R16, low(RAMEND)
    out SPH, R17
    out SPL, R16
    
    ldi R20,0xFF
    out DDRB,R20
    out PORTB,R20 ;dioda zgaszona i port ustawiony jako wyjście
    
    petla_glowna:
    	rcall delay3
    	in R20, PORTB
    	com R20
    	out PORTB, R20
    rjmp petla_glowna
    


    Mam pytanie jak duże w tym programie jest opóźnienie wnoszone przez podprogram delay2 ? Czy wystarczające do zauważenia migotania diody ?
  • REKLAMA
  • Pomocny post
    #2 7148875
    Krauser
    Poziom 26  
    Jeśli dobrze pamiętam to tak to się liczyło
    
       delay1:
          ldi R16, 0 ;1 cykl
          del1:
             inc R16 ;1cykl
          brne del1 ;2 cykle (1 gdy nie ma skoku)
       ret ;4 cykle
    ;razem (1+1+2)*256-1+4=1027 cykli
    
       delay2:
          ldi R17, 0 ;1 cykl
          del2:
             rcall delay1 ;3+1027 cykli
             inc R17 ;1 cykl
          brne del2 ;2 cykle (1 gdy nie ma skoku)
       ret ;4 cykle
    ;razem (1+1030+1+2)*256-1+4=264707 cykli

    czyli 264707 cykli / (16 000 000 cykli/sek) = 16,5 ms

    Jeśli pracujesz na AVR Studio to łatwo to sprawdzić w symulacji. Po dojściu do linii przed wywołaniem opóźnienia wyzerować podwójnym kliknięciem licznik cykli i sprawdzić po wykonaniu podprogramu.
  • REKLAMA
  • #3 7149033
    maciej_333
    Poziom 38  
    Czyli licząc opóźnienie wnoszone przez delay3 powinno wyjść tak:
    	delay3:
    		ldi R18, 0 ;1 cykl
    		del3:
    			rcall delay2 ;3+264707 cykli  - jak rozumiem 3 to ilość cykli rcall ?
    			inc R18 ;1 cykl
    		brne del3 ;2 cykle (1 gdy nie ma skoku)
    	ret ;4 cykle
                 ;razem (1+264710+1+2)*256-1+4=67766787 cykli


    67766787*(16MHz)^-1=4,24s Czy tak ?
  • REKLAMA
  • #4 7152748
    Krauser
    Poziom 26  
    Było by dobrze, ale źle postawiłem nawias, bo ldi nie wykonuje się w pętli, ale tylko raz. Po poprawce:
    
       delay1:
          ldi R16, 0 ;1 cykl
          del1:
             inc R16 ;1cykl
          brne del1 ;2 cykle (1 gdy nie ma skoku)
       ret ;4 cykle
    ;razem 1+(1+2)*256-1+4=772 cykli
    
       delay2:
          ldi R17, 0 ;1 cykl
          del2:
             rcall delay1 ;3+772 cykli
             inc R17 ;1 cykl
          brne del2 ;2 cykle (1 gdy nie ma skoku)
       ret ;4 cykle
    ;razem 1+(775+1+2)*256-1+4=199172 cykli
    
       delay3:
          ldi R18, 0 ;1 cykl
          del3:
             rcall delay2 ;3+199172 cykli  
             inc R18 ;1 cykl
          brne del3 ;2 cykle (1 gdy nie ma skoku)
       ret ;4 cykle
    ;razem 1+(199175+1+2)*256-1+4=50989572 cykli

    co przy kwarcu 16MHz da 3,19 sekundy
  • REKLAMA
REKLAMA