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

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

mi14chal 04 Lip 2011 17:57 2461 21
  • #1 9681585
    mi14chal
    Poziom 28  
    Posty: 1021
    Pomógł: 112
    Ocena: 23
    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:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Macie jakieś pomysły jak to naprawić?
  • Pomocny post
    #2 9681642
    excray
    Poziom 41  
    Posty: 5500
    Pomógł: 739
    Ocena: 656
    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.
  • #3 9681727
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    Przydałby się jeszcze schemat.

    excray napisał:
    A w AVR Studio jeśli nie zwróciłeś uwagi stan wirtualnych bitów PINB po uruchomieniu to 00000000 i dlatego działa.

    Czy mógłbyś rozszerzyć tę myśl?
  • #4 9681751
    excray
    Poziom 41  
    Posty: 5500
    Pomógł: 739
    Ocena: 656
    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 9681762
    mi14chal
    Poziom 28  
    Posty: 1021
    Pomógł: 112
    Ocena: 23
    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 9681771
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    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 napisał:
    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 9681806
    mi14chal
    Poziom 28  
    Posty: 1021
    Pomógł: 112
    Ocena: 23
    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 9681811
    excray
    Poziom 41  
    Posty: 5500
    Pomógł: 739
    Ocena: 656
    "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 9681816
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    To go zrób np. darmowym programem EAGLE.
    Albo chociaż na kartce.
    Przyciski i LEDy to nie wszystko.

    Dodano po 1 [minuty]:

    excray napisał:
    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 9681853
    excray
    Poziom 41  
    Posty: 5500
    Pomógł: 739
    Ocena: 656
    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 9681866
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    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 , ...
    Kod: text
    Zaloguj się, aby zobaczyć kod

    ... to po prostu makabra.

    PS
    Kolega autor, to chyba nie za bardzo rozumie działanie instrukcji, których używa.
  • #12 9681971
    mi14chal
    Poziom 28  
    Posty: 1021
    Pomógł: 112
    Ocena: 23
    Ok dodaje schemat zrobiłem w KiCad.
    Cytat:
    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?
    Załączniki:
    • ledki.zip (9.58 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #16 9682031
    excray
    Poziom 41  
    Posty: 5500
    Pomógł: 739
    Ocena: 656
    mi14chal napisał:
    To jakby miała wyglądać poprawna wersja kodu?

    A co ten kod miałby robić? Opisz swój program - jego działanie.
  • #17 9682036
    mi14chal
    Poziom 28  
    Posty: 1021
    Pomógł: 112
    Ocena: 23
    No tylko w których miejscach dawać ten ret, rjmp bo za bardzo nie wiem.

    excray napisał:
    mi14chal napisał:
    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 9685110
    mi14chal
    Poziom 28  
    Posty: 1021
    Pomógł: 112
    Ocena: 23
    Mam problem z tym call i ret mam taki kod:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    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?
  • Pomocny post
    #19 9685700
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    mi14chal napisał:
    ... Co jest źle?

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

    Trzeci raz, nie będę powtarzał :evil:
  • #20 9685931
    mi14chal
    Poziom 28  
    Posty: 1021
    Pomógł: 112
    Ocena: 23
    zumek napisał:
    mi14chal napisał:
    ... Co jest źle?

    zumek napisał:
    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:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    Wydaje się działać. Tylko mam pytanie taka inicjacja stosu nie będzie mieć złego wpływu na działanie programu?
  • Pomocny post
    #21 9685989
    excray
    Poziom 41  
    Posty: 5500
    Pomógł: 739
    Ocena: 656
    mi14chal napisał:
    Mam problem z tym call i ret mam taki kod:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    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 9686028
    mi14chal
    Poziom 28  
    Posty: 1021
    Pomógł: 112
    Ocena: 23
    Dzięki za wyjaśnienie.

Podsumowanie tematu

✨ Problem z programem na mikrokontrolerze ATmega32 polegał na tym, że kod działał poprawnie w symulatorze, ale na rzeczywistym urządzeniu nie reagował na przyciski, przechodząc od razu do funkcji Count. Użytkownicy zasugerowali, że zamiast instrukcji SBIC powinno się używać SBIS, ponieważ przyciski są podłączone do masy. Dodatkowo, zwrócono uwagę na konieczność poprawnego zarządzania stosami oraz użycia instrukcji RET w podprogramach. Użytkownik dodał schemat połączeń, a także opisał działanie programu, który miał obsługiwać trzy przyciski do zmiany wartości i zapalania diod LED. W końcu, po wprowadzeniu poprawek, użytkownik potwierdził, że program działa poprawnie, ale pojawiły się nowe problemy z diodami LED.
Wygenerowane przez model językowy.
REKLAMA