Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[atmega32] program działa na symulatorze, na uC już nie

mi14chal 04 Jul 2011 17:57 2332 21
Altium Designer Computer Controls
  • #1
    mi14chal
    Level 28  
    Problem jest taki że na symulatorze kod działa tak jak powinien, a na uC nie działa "menu" programu(funkcja Program) tylko od razu przechodzi do wykonywania pierwszej funkcji(funkcja Count). W ogóle atmega jakby nie reagowała na żadne przyciski. Zamieszczam kod programu:

    Code: armasm
    Log in, to see the code


    Macie jakieś pomysły jak to naprawić?
  • Altium Designer Computer Controls
  • Helpful post
    #2
    excray
    Level 40  
    A nie powinno być SBIS?

    Program:
    	sbis PINB,0 ; check the button0 is being pressed
    	call Count
    	sbis PINB,1 ; check the button1 is being pressed
    	call Up
    	sbis PINB,2 ; check the button2 is being pressed
    	call Down
    	call Program

    Jak mniemam wduszając przycisk zwierasz wejście do masy. A SBIC działa jak: "pomiń poniższy rozkaz i skocz do następnego jeśli bit wyzerowany". W przypadku SBIS program będzie pomijać skoki dopóki na wejściu będzie 1 czyli nie wciśnięto przycisku. A w AVR Studio jeśli nie zwróciłeś uwagi stan wirtualnych bitów PINB po uruchomieniu to 00000000 i dlatego działa.
  • Altium Designer Computer Controls
  • #4
    excray
    Level 40  
    Rozszerzam i zaopatruję w graficzne wyjaśnienie.
    [atmega32] program działa na symulatorze, na uC już nie
    Jeśli w AVR Studio uruchomisz debugging to stan dowolnego wejścia PINx jest standardowo na starcie 0x00 czyli binarnie 0b00000000 czyli na "chłopski rozum" na wszystkich wejściach jest 0 logiczne.[/img]
  • #5
    mi14chal
    Level 28  
    Wgrałem na uC i wydaję się być ok dzięki za wyjaśnienie. Ale pojawił się też problem. Niektóre diodki się w ogóle nie świecą, czasem się zdarza że te co świecą zaczynają słabiej świecić co to może być za problem?
  • #6
    dondu
    Moderator on vacation ...
    AVR Studio nie ma nic do tego.
    To "przypadłość" tego konkretnego mikrokontrolera opisana w datasheet.

    I tylko tyle chciałem sprostować.

    Dodano po 1 [minuty]:

    mi14chal wrote:
    Wgrałem na uC i wydaję się być ok dzięki za wyjaśnienie. Ale pojawił się też problem. Niektóre diodki się w ogóle nie świecą, czasem się zdarza że te co świecą zaczynają słabiej świecić co to może być za problem?

    Prosiłem o schemat - nic nie odpowiedziałeś.
    W takim razie może to Ci pomoże: http://mikrokontrolery.blogspot.com/2011/04/pieklo-poczatkujacych.html
  • #7
    mi14chal
    Level 28  
    Schematu nie posiadam, ale opiszę co jest podłączone... 3 przyciski do portów PB0-PB2 oczywiście dalej połączone do masy, a z portów PA rezystorki 390R potem diodka i do masy.
  • #8
    excray
    Level 40  
    "sbis PINB, PINB0 || PINB1 || PINB2"
    Pierwszy raz widzę coś takiego w assemblerze w takim połączeniu. Niech się kolega Dondu wypowie ale jak dla mnie to ewidentny błąd.
  • #9
    dondu
    Moderator on vacation ...
    To go zrób np. darmowym programem EAGLE.
    Albo chociaż na kartce.
    Przyciski i LEDy to nie wszystko.

    Dodano po 1 [minuty]:

    excray wrote:
    Niech się kolega Dondu wypowie ale jak dla mnie to ewidentny błąd.

    Niestety od wieków nie programuję w asemblerze i nie chciałbym podpowiedzieć źle.
  • #10
    excray
    Level 40  
    Poza tym odnoszę wrażenie że pogubiłeś RET czyli powrót w swoich podprogramach. Pamiętaj, że wywołanie CALL zazwyczaj kończy się RET w podprogramie. Z kolei w kilku innych miejscach zamiast CALL chyba powinieneś mieć RJMP. U Ciebie w tym programie na 99% następuje przepełnienie stosu.
  • #11
    zumek
    Level 39  
    Ja natomiast zauważyłem, że autor nie zdaje sobie sprawy z istnienia stosu oraz jego wskaźnika, a kończenie pętli głównej rozkazem call , ...
    Code: armasm
    Log in, to see the code

    ... to po prostu makabra.

    PS
    Kolega autor, to chyba nie za bardzo rozumie działanie instrukcji, których używa.
  • #12
    mi14chal
    Level 28  
    Ok dodaje schemat zrobiłem w KiCad.
    Quote:
    Poza tym odnoszę wrażenie że pogubiłeś RET czyli powrót w swoich podprogramach. Pamiętaj, że wywołanie CALL zazwyczaj kończy się RET w podprogramie. Z kolei w kilku innych miejscach zamiast CALL chyba powinieneś mieć RJMP. U Ciebie w tym programie na 99% następuje przepełnienie stosu.


    To jakby miała wyglądać poprawna wersja kodu?
  • #16
    excray
    Level 40  
    mi14chal wrote:
    To jakby miała wyglądać poprawna wersja kodu?

    A co ten kod miałby robić? Opisz swój program - jego działanie.
  • #17
    mi14chal
    Level 28  
    No tylko w których miejscach dawać ten ret, rjmp bo za bardzo nie wiem.

    excray wrote:
    mi14chal wrote:
    To jakby miała wyglądać poprawna wersja kodu?

    A co ten kod miałby robić? Opisz swój program - jego działanie.


    No są 3 przyciski jeden podpięty do PB0 ma zapalać diodki w kodzie binarnym jak się zapalą wszystkie diodki mają gasnąć i program ma wrócić do menu. Przycisk podpięty do PB1 ma zwiększać wartość, a przycisk PB2 ma zmniejszać wartość. Oczywiście nie może przekraczać minimalnej jak i maksymalnej wartości. Zresztą kod ma komentarze więc chyba nie ma większego problemu?
  • #18
    mi14chal
    Level 28  
    Mam problem z tym call i ret mam taki kod:
    Code: armasm
    Log in, to see the code


    oczywiście call z funkcji Main przechodzi do funkcji test, ale ret nie wraca do funkcji Main tylko wraca na początek kodu do linii:
    ldi R16, 0x00
    Co jest źle?
  • Helpful post
    #19
    zumek
    Level 39  
    mi14chal wrote:
    ... Co jest źle?

    zumek wrote:
    Ja natomiast zauważyłem, że autor nie zdaje sobie sprawy z istnienia stosu ...

    Trzeci raz, nie będę powtarzał :evil:
  • #20
    mi14chal
    Level 28  
    zumek wrote:
    mi14chal wrote:
    ... Co jest źle?

    zumek wrote:
    Ja natomiast zauważyłem, że autor nie zdaje sobie sprawy z istnienia stosu ...

    Trzeci raz, nie będę powtarzał :evil:


    Hmm zrobiłem coś takiego:
    Code: armasm
    Log in, to see the code

    Wydaje się działać. Tylko mam pytanie taka inicjacja stosu nie będzie mieć złego wpływu na działanie programu?
  • Helpful post
    #21
    excray
    Level 40  
    mi14chal wrote:
    Mam problem z tym call i ret mam taki kod:
    Code: armasm
    Log in, to see the code


    oczywiście call z funkcji Main przechodzi do funkcji test, ale ret nie wraca do funkcji Main tylko wraca na początek kodu do linii:
    ldi R16, 0x00
    Co jest źle?

    W przypadku procesorów AVR zawsze na sam początek musisz ustawić stos w odpowiednim miejscu w pamięci programu. Praktycznie każdy program więc zaczyna się (dla atmega32) od rozkazów ustawiających stos. Za manualem str 45:
    
    Address Labels Code Comments
    $000 jmp RESET ; Reset Handler
    $002 jmp EXT_INT0 ; IRQ0 Handler
    $004 jmp EXT_INT1 ; IRQ1 Handler
    $006 jmp EXT_INT2 ; IRQ2 Handler
    $008 jmp TIM2_COMP ; Timer2 Compare Handler
    $00A jmp TIM2_OVF ; Timer2 Overflow Handler
    $00C jmp TIM1_CAPT ; Timer1 Capture Handler
    $00E jmp TIM1_COMPA ; Timer1 CompareA Handler
    $010 jmp TIM1_COMPB ; Timer1 CompareB Handler
    $012 jmp TIM1_OVF ; Timer1 Overflow Handler
    $014 jmp TIM0_COMP ; Timer0 Compare Handler
    $016 jmp TIM0_OVF ; Timer0 Overflow Handler
    $018 jmp SPI_STC ; SPI Transfer Complete Handler
    $01A jmp USART_RXC ; USART RX Complete Handler
    $01C jmp USART_UDRE ; UDR Empty Handler
    $01E jmp USART_TXC ; USART TX Complete Handler
    $020 jmp ADC ; ADC Conversion Complete Handler
    $022 jmp EE_RDY ; EEPROM Ready Handler
    $024 jmp ANA_COMP ; Analog Comparator Handler
    $026 jmp TWI ; Two-wire Serial Interface Handler
    $028 jmp SPM_RDY ; Store Program Memory Ready Handler
    ;
    $02A RESET: ldi r16,high(RAMEND) ; Main program start
    $02B out SPH,r16 ; Set Stack Pointer to top of RAM
    $02C ldi r16,low(RAMEND)
    $02D out SPL,r16
    $02E sei ; Enable interrupts
    $02F <instr>  xxx
    ... ... ...

    Jak widzisz na początek są skoki obsługi przerwań a od adresu $02A zaczyna się program który w pierwszych rozkazach porządkuje adres stosu. W prostych programach wystarczy:
    
    .org 00h
      rjmp Main
    
    .org 02Ah
    Main:
      ldi r16,high(RAMEND)
      out SPH,r16
      ldi r16,low(RAMEND)
      out SPL,r16
    ;dalsze linie programu, na przykład:
      call TEST
      ldi r16,0x00
    
    TEST:
      ret

    Dodaj to u siebie na sam początek a Twój prosty program z cytowanego postu będzie działać poprawnie. Poczytaj sobie o stosie. Zapoznaj się z manualem.
  • #22
    mi14chal
    Level 28  
    Dzięki za wyjaśnienie.