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

Atmega16 Asembler - Dlaczego diody na PORTA nie migają?

Perler 15 Gru 2005 11:21 1244 2
REKLAMA
  • #1 2085239
    Perler
    Poziom 10  
    Posty: 47
    Ocena: 1
    Witam, mam oto taki program napisany w asemblerze pod Atmega16:

    
    .INCLUDE "m16def.inc"
    
    	ldi R16, 0xFF
    	out DDRA, R16
    	.EQU SYS_FREQ = 16
    
    Petla:
    
    	ldi R16, 0b11111111
    	out PORTA, R16
    
    	rjmp Delay
    	rjmp Delay
    	rjmp Delay
    	rjmp Delay
    	rjmp Delay
    	rjmp Delay
    	rjmp Delay
    	rjmp Delay
    
    
    	ldi R16, 0b00000000
    	out PORTA, R16
    
    
    	rjmp Petla
    
    Delay:
    	ldi R16, 1
    	ldi R16, 1
    
    	push R18
    	push R19
    	push R20
    	push R21
    
    	mov R20, R16
    	mov R21, R17
    	ldi R18, SYS_FREQ
    


    Moim zamiarem bylo napisanie prostego programu ktory by migal diodami . Jedna dioda jest podlaczona do portu A1 a druga do A2.
    Kiedy wlaczam procka dioda A1 caly czas sie pali a dioda A2 tylko raz mignie i nastepnie caly czas sie swieci.

    Dlazcego tak sie dzieje? Dlaczego diody nie migaja?
  • REKLAMA
  • #2 2085276
    hunterhouse
    Poziom 26  
    Posty: 893
    Pomógł: 84
    Ocena: 3
    .INCLUDE "m16def.inc"

    ldi R16, 0xFF
    out DDRA, R16
    .EQU SYS_FREQ = 16

    Petla:

    ldi R16, 0b11111111
    out PORTA, R16

    rjmp Delay 'to jest skok we wskazane miejsce a nie do procedury.
    powinno być
    rcall Delay


    ldi R16, 0b00000000
    out PORTA, R16

    tu też brakuje opużnienia

    rjmp Petla

    Delay:
    ldi R16, 1
    ldi R16, 1

    push R18
    push R19
    push R20
    push R21

    mov R20, R16
    mov R21, R17
    ldi R18, SYS_FREQ

    tu chba czegoś brakuje????
    na końcu musi być
    ret

    a wogóle to brakje jakiejś pętli co by opużniała


    oprucz tego to musisz na początku ustawić rejestr stosu i zostawić miejsce na wektory przerwań
  • #3 2087282
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    Perler: w twoim kodzie jest dużo niedociągnięć.. funkcje Delay powinieneś wywołać przez 'rcall', tu zaś przychodzi brak stosu i brak 'ret' na końcu. w samym Delay widze odkładanie 4 rejestrów (gdzie?) ale niewidze ich zdejmowania ani pętli do opóźnienia.. po wystawieniu wartości 0x00 na porta odrazu dokonujesz skoku do początku pętli i odrazu zmieniasz stan porta na 0xFF.. wątpie żebyś zobaczył jak przez te 4 cykle dioda sie świeci/nieświeci. Brakuje jawnego zadeklarowania tablicy wektorów przerwań co nie jest dobrym objawem...

    spróbuj skompilować poniższy kod i go wgrać:
    
    .include "m16def.inc"
    .org 0
    ; tablica wektorów
    rjmp reset
    
    .org INT_VECTORS_SIZE
    
    .equ stack_size = 32         ; rozmiar stosu w bajtach
    .equ crystal = 100000        ; zmien to na ilosc Hz zegara mikrokontrolera
    
    .def rA = r16      ; mój nawyk...
    .def rB = r17
    .def rC = r18
    .def rD = r19
    
    .macro dnop
      rjmp PC+1        ; zoptymalizowany podwójny nop...
    .endm
    
    .macro mIDelay     ; makro opóżniające
      .if @0 < 760
        .if (@0)>2
          ldi rA,(@0)/3
          dec rA
          brne PC-1
        .endif
        .if (@0)%3 == 1
          nop
        .endif
        .if (@0)%3 == 2
          dnop
        .endif
      .else
        push rA
        push rB
        push rC
        push rD
        ldi rA,byte1((@0-20)/6)
        ldi rB,byte2((@0-20)/6)
        ldi rC,byte3((@0-20)/6)
        ldi rD,byte4((@0-20)/6)
        _midelay_loop:
          subi rA,1
          sbci rB,0
          sbci rC,0
          sbci rD,0
        brne _midelay_loop
        nop
        .if (@0-20)%6 > 1
          dnop
        .endif
        .if (@0-20)%6 > 3
          dnop
        .endif
        .if (@0-20)%6 > 5
          dnop
        .endif
        .if (@0-20)%2 > 0
          nop
        .endif
        pop rD
        pop rC
        pop rB
        pop rA
      .endif
    .endm
    
    .macro outi        ; dla zwiększenia czytelności
      ldi rA,@1
      out @0,rA
    .endm
    
    reset:
      outi spl,low(stack+stack_size-1)
      outi sph,high(stack+stack_size-1)
      outi ddra,$FF
    loop:
      outi porta,$FF
      mIDelay (crystal/2)-2
      outi porta,$00
      mIDelay (crystal/2)-4
    rjmp loop
    
    .dseg
    stack: .byte stack_size      ; stos
    .cseg
    
    
REKLAMA