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

[Atmega16][Assembler] Symulacja OK, program dziala inaczej

Student_Bartosh 24 Sty 2011 01:55 2519 14
  • #1 9048870
    Student_Bartosh
    Poziom 9  
    Witam wszystkich.
    Jestem początkującym programistą mikrokontrolerów. W miarę postępu edukacyjnego z AVR staram się wyznaczać sobie coraz to trudniejsze zadania. W końcu wymyśliłem sobie coś, z czym nie potrafię sobie poradzić.

    Korzystam z makiety mod_avr_2 (pdf dostępny w zamieszczonym linku)
    Moduł uruchomieniowy Atmega 2

    Program napisany w asemblerze w AVR studio 4.18
    Do wgrania napisanego programu korzystam z programu MegaLoad.net.
    Ustawiam ścieżkę pliku hex do flasha i eeprom (zgodnie z instrukcją makiety), ustawiam odpowiedni port UBS i prędkość 57600bps. Program się wczytuje.

    A teraz, co ma robić program. Naciskając odpowiedni przycisk zostaje zaświecona odpowiednia sekwencja podłączonych diod.
    Przyciski są podłączone pod portA, na wyjście uC podłączone 8 diod.

    Kod źródłowy:
    
    .include"m16def.inc"
    .cseg
    .org 0
    .def acc=r16
    
    ldi acc,HIGH(RAMEND) ; Definicja stosu
    out SPH,acc
    ldi acc,LOW(RAMEND)
    out SPL,acc
    
    ldi acc,0b00000000	;wszystkie bity jako wejscie
    out DDRA,acc 
    ldi acc,0b11111111	;wszystkie wejscia w stanie wysokim
    out PORTA,acc
    ldi acc,0b11111111	;wszystkie bity jako wyjscia
    out DDRB, acc
    ;ldi acc,0b11111111	;wszystkie diody wylaczone
    ;out PORTB,acc
    
    Odczyt:
    
    	in acc,PINA		;odczyt stanu przyciskow
    	andi acc,0b10000000	
        brne Kombinacja1
    
    	in acc,PINA		;odczyt stanu przyciskow
    	andi acc,0b01000000	
        brne Kombinacja2
    
    	in acc,PINA		;odczyt stanu przyciskow
    	andi acc,0b00100000	
        brne Kombinacja3
    
    	in acc,PINA		;odczyt stanu przyciskow
    	andi acc,0b00010000	
        brne Kombinacja4
    		
    	ldi acc,0b00000000
    	out PortB,acc
    
    	rjmp Odczyt	
    
    
    Kombinacja1:
    
    	ldi acc,0b00001111
    	out PortB,acc	
    	rjmp Odczyt
    
    Kombinacja2:
    
    	ldi acc,0b10011001
    	out PortB,acc
    	rjmp Odczyt
    
    Kombinacja3:
    
    	ldi acc,0b11001100
    	out PortB,acc
    	rjmp Odczyt
    
    Kombinacja4:
    
    	ldi acc,0b01010101
    	out PortB,acc
    	rjmp Odczyt
    
    .exit
    


    Symulacja działa tak, jak sobie to wymyśliłem. Naciskam odpowiedni przycisk podłączony do portu A , a na port B zostaje wysłana odpowiednia sekwencja zapalająca diody przypisana odpowiedniemu przyciskowi. Po puszczeniu przycisku diody gasną.

    Po wczytaniu programu do uC świecą (i nie wiem dlaczego) następujące diody: 01100110 (kombinacja2) i odczytana zostaje kombinacja3, czyli po wciśnięciu przycisku 2 (bit 6 portu A). Reszta nie działa :(

    Moje podejrzenia:
    1. Mój uC ma oznaczenie "Atmel Atmega32 16PU 1019D". W instrukcji napisane, że to Atmega16. Czy możliwe, że korzystam ze złych bibliotek? Do tej pory wszystko co napisałem działało.
    2.Błąd w kodzie programu:
    a)źle zdefiniowane porty A i B,
    b)błąd w strukturze programu,
    c) czegoś brakuje?

    Przepraszam, że taki długi post, ale chciałem przekazać jak najwięcej info. Strasznie się zaciąłem na ten program. Chcę to zrobić i wyznaczać sobie nowe zadania :p
  • #3 9048894
    rrytel
    Poziom 14  
    .include"m16def.inc" 

    zamień na
    .include"m32def.inc" 

    A odczyt stanu klawiszy spróbuj zrobić w ten sposób:
    Odczyt:
    in acc, pina
    
    sbrc acc, 7
      rjmp kombinacja1
    sbrc acc, 6
      rjmp kombinacja2
    sbrc acc, 5
      rjmp kombinacja3
    sbrc acc, 4
      rjmp kombinacja4
    rjmp Odczyt
    

    w kodzie powyżej jeżeli przycisniecie zwiera do gnd to zamiast sbrc dajesz sbrs
    tak przy okazji:
    wartość w acc nie była zmieniana pomiędzy tymi instrukcjami
    ldi acc,0b11111111   ;wszystkie wejscia w stanie wysokim
    out PORTA,acc
    ldi acc,0b11111111   ;wszystkie bity jako wyjscia
    out DDRB, acc 

    więc drugie ldi acc... można pominąć
  • #4 9049010
    Student_Bartosh
    Poziom 9  
    zumek napisał:
    Wytłumacz, dlaczego użyłeś BRNE, a nie BREQ
     brne Kombinacja1
    

    Przycisk po wciśnięciu łączy pin z GND, czyż nie :?:


    BREQ-skok względny, jeśli równe, sprawdza flagę Z.
    BRNE-skok względny, jeśli nie równe, sprawdza flagę Z.

    Po wykonaniu instrukcji:
    in acc,PINA		;odczyt stanu przyciskow
    andi acc,0b10000000	
    breq Kombinacja1

    flaga Z jest ustawiona, przycisk nie jest wciśnięty i niestety skacze. Ma wykonywać skok po wciśnięciu przycisku. Więc musiałem zastosować instrukcję:
    
    in acc,PINA		;odczyt stanu przyciskow
    andi acc,0b10000000	
    brne Kombinacja1

    flaga Z nie jest ustawiona.

    Dodano po 7 [minuty]:

    rrytel napisał:
    .include"m16def.inc" 

    zamień na
    .include"m32def.inc" 


    Niestety, nie pomogło. Działa tak samo jak za poprzednim razem.

    rrytel napisał:
    A odczyt stanu klawiszy spróbuj zrobić w ten sposób:

    Odczyt:
    in acc, pina
    
    sbrc acc, 7
      rjmp kombinacja1
    sbrc acc, 6
      rjmp kombinacja2
    sbrc acc, 5
      rjmp kombinacja3
    sbrc acc, 4
      rjmp kombinacja4
    rjmp Odczyt
    

    w kodzie powyżej jeżeli przycisniecie zwiera do gnd to zamiast sbrc dajesz sbrs


    Tak, to poprawiłem. Faktycznie lepiej to wygląda teraz.

    rrytel napisał:

    tak przy okazji:
    wartość w acc nie była zmieniana pomiędzy tymi instrukcjami
    ldi acc,0b11111111   ;wszystkie wejscia w stanie wysokim
    out PORTA,acc
    ldi acc,0b11111111   ;wszystkie bity jako wyjscia
    out DDRB, acc 

    więc drugie ldi acc... można pominąć


    Faktycznie, nie zwróciłem na to uwagi. Poprawiłem.
    Dzięki za wszelkie poprawki. Ale dalej działa tak jak działało. Po załadowaniu diody świecą jak po wgraniu kombinacji2, działa tylko przycisk przy bicie 6 portu A.
  • #5 9049041
    elektrofil
    Poziom 17  
    proszę bardzo:
    
    .include"m32def.inc"
    .cseg
    .org 0
    .def acc=r16
    
    ldi acc,HIGH(RAMEND) ; Definicja stosu
    out SPH,acc
    ldi acc,LOW(RAMEND)
    out SPL,acc
    
    ldi acc,0b00000000   
    out DDRA,acc		 ;wszystkie bity jako wejscie
    ldi acc,0b11111111   
    out PORTA,acc		 ;wszystkie wejscia w stanie wysokim
    out DDRB, acc		 ;wszystkie bity jako wyjscia
    ;ldi acc,0b11111111   ;wszystkie diody wylaczone
    ;out PORTB,acc
    
    Odczyt:
    in acc, pina
    
    sbrs acc, 7
      rjmp kombinacja1
    sbrs acc, 6
      rjmp kombinacja2
    sbrs acc, 5
      rjmp kombinacja3
    sbrs acc, 4
      rjmp kombinacja4
    rjmp Odczyt   
    
    
    Kombinacja1:
    
       ldi acc,0b00001111
       out PortB,acc   
       rjmp Odczyt
    
    Kombinacja2:
    
       ldi acc,0b10011001
       out PortB,acc
       rjmp Odczyt
    
    Kombinacja3:
    
       ldi acc,0b11001100
       out PortB,acc
       rjmp Odczyt
    
    Kombinacja4:
    
       ldi acc,0b01010101
       out PortB,acc
       rjmp Odczyt
    
    .exit


    działająca procedura, sprawdzone na atmega 32.
  • #6 9049343
    LordBlick
    VIP Zasłużony dla elektroda
    Osobiście proponuję wersję kodu łatwiejszą do połapania się, w pełni proceduralną ;) i łatwiej modyfikowalną przy zmianie konfiguracji schematu (np. przy zmianie portu na przyciski nie wprowadzamy zmian pieczołowicie w każdym miejscu z dużym ryzykiem, że coś pominiemy, tylko zmieniamy w jednym i gra), z pełniejszym wykorzystaniem tego, co oferuje asembler AVRasm2:
    .include"m32def.inc"
    .def Acc=r16
    #define KEY_PORT PORTA
    #define KEY1 PORTA7
    #define KEY2 PORTA6
    #define KEY3 PORTA5
    #define KEY4 PORTA4
    #define LED_PORT PORTB
    .cseg
    .org 0
    	rjmp RESET
    InitKey:
    	sbi KEY_PORT, KEY1	 	; wszystkie bity jako wejscie z Pullup
    	cbi KEY_PORT-1, KEY1	; Adres DDRx jest o 1 mniejszy od PORTx
    	sbi KEY_PORT, KEY2
    	cbi KEY_PORT-1, KEY2
    	sbi KEY_PORT, KEY3
    	cbi KEY_PORT-1, KEY3
    	sbi KEY_PORT, KEY4
    	cbi KEY_PORT-1, KEY4
    	ret
    ; - -
    InitLED:
    	ldi Acc, 0b11111111
    	out LED_PORT-1, Acc	; DDR - wszystkie bity jako wyjscia
    	out LED_PORT, Acc	;wszystkie diody wylaczone
    	ret
    ; - -
    Kombinacja1:
    	ldi Acc, 0b00001111
    	out LED_PORT, Acc
    	ret
    Kombinacja2:
    	ldi Acc, 0b10011001
    	out LED_PORT, Acc
    	ret
    Kombinacja3:
    	ldi Acc, 0b11001100
    	out LED_PORT, Acc
    	ret
    Kombinacja4:
    	ldi Acc, 0b01010101
    	out LED_PORT, Acc
    	ret
    RESET:
    	ldi Acc, HIGH(RAMEND) ; Definicja stosu
    	out SPH, Acc
    	ldi Acc, LOW(RAMEND)
    	out SPL, Acc
    	rcall InitKey
    	rcall InitLED
    MainLoop:
    	sbis KEY_PORT-2, KEY1	; Adres PINx jest o 2 mniejszy od PORTx
    	rcall Kombinacja1
    	sbis KEY_PORT-2, KEY2
    	rcall Kombinacja2
    	sbis KEY_PORT-2, KEY3
    	rcall Kombinacja3
    	sbis KEY_PORT-2, KEY4
    	rcall Kombinacja4
    	rjmp MainLoop
    .exit
  • #7 9053260
    Student_Bartosh
    Poziom 9  
    Witam. Dziękuję za tyle odpowiedzi w tak krótkim czasie. Przepraszam, że nie odpisywałem. Natłok obowiązków :/

    elektrofil napisał:
    proszę bardzo:
    
    .include"m32def.inc"
    .cseg
    .org 0
    .def acc=r16
    
    ldi acc,HIGH(RAMEND) ; Definicja stosu
    out SPH,acc
    ldi acc,LOW(RAMEND)
    out SPL,acc
    
    ldi acc,0b00000000   
    out DDRA,acc		 ;wszystkie bity jako wejscie
    ldi acc,0b11111111   
    out PORTA,acc		 ;wszystkie wejscia w stanie wysokim
    out DDRB, acc		 ;wszystkie bity jako wyjscia
    ;ldi acc,0b11111111   ;wszystkie diody wylaczone
    ;out PORTB,acc
    
    Odczyt:
    in acc, pina
    
    sbrs acc, 7
      rjmp kombinacja1
    sbrs acc, 6
      rjmp kombinacja2
    sbrs acc, 5
      rjmp kombinacja3
    sbrs acc, 4
      rjmp kombinacja4
    rjmp Odczyt   
    
    
    Kombinacja1:
    
       ldi acc,0b00001111
       out PortB,acc   
       rjmp Odczyt
    
    Kombinacja2:
    
       ldi acc,0b10011001
       out PortB,acc
       rjmp Odczyt
    
    Kombinacja3:
    
       ldi acc,0b11001100
       out PortB,acc
       rjmp Odczyt
    
    Kombinacja4:
    
       ldi acc,0b01010101
       out PortB,acc
       rjmp Odczyt
    
    .exit


    działająca procedura, sprawdzone na atmega 32.



    Jak Tobie działa, to ja mam coś rąbnięte. Zakładałem, że ten program dopiero po wciśnięciu przycisku będzie sterował diodami. Po wgraniu na diodach mam taki stan: 10001110. I działa tylko przycisk na pinie 6.

    W ogóle to ta dioda na bicie najstarszym (7-bit) zazwyczaj mi świeci. Czasem jasno, czasem normalnie. Może coś jest z makietą? Dzieje się tak nawet przy najprostszym programie, jakim jest czytanie stanu pinu i wyprowadzenie go na diody.
  • #8 9053591
    elektrofil
    Poziom 17  
    działają obydwa kody, sprawdzone podczas pisania tego posta. filmiku nie wrzucę, ponieważ ani Avila, ani Cookie nie radzi sobie z nagraniem świecących LED'ów.
    więc masz albo uwalony procek, albo zwarcia na płytce.
    dorzucam plik hex który daje efekt "biegnącego światła" w jednej chwili jest zaświecona tylko jedna dioda LED. przy zegarze 16MHz czas przerwy wynosi 300msek. diody na portb. wspólny plus (czyli tak jak masz na swojej pcb)
  • #9 9053624
    Student_Bartosh
    Poziom 9  
    Dobra, dzisiaj zaopatrzę się w nowy procek i zobaczę czy dalej tak jest.
  • #10 9065127
    Student_Bartosh
    Poziom 9  
    Dla zainteresowanych śledzących temat.

    Kupiłem nowy uC na moją makietę, jest to tak jak poprzednio Atmel Atmega32 16PU. Po wyjęciu starego uC i wsadzeniu nowego na (do?) makietę(ty?) program się nie wgrywa, nic się nie dzieje. Do wgrywania programu korzystam z MegaLoad.

    Jak się dowiedziałem, muszę zaopatrzyć się w programator i zrobić coś z bootloaderem (?). Podobno wtedy będzie dobrze.

    Próbowałem zrobić tego bootloadera na starej atmege, pierwotnie zainstalowanej w makiecie. Robiłem to przez MegaLoads i nawet się coś wgrało :D ale spowodowało to, że portB uC jest uwalony, nie działają cztery wyprowadzenia.

    Kupię programator ISP (czy jakoś tak) i przedstawię, jak się potoczyła sprawa.
  • #11 9066526
    elektrofil
    Poziom 17  
    jeżeli masz programator na ft232 zainteresuj się podłączeniem w ten sposób:

    Link

    nic nie musisz kupować :)

    jutro rano podrzucę prawidłowe wartości do ustawienia w "fusach"]Link[/url]
  • #12 9066681
    Student_Bartosh
    Poziom 9  
    Przyznam, że bardzo sprytnie ktoś to wymyślił :D

    Mam na makiecie FT232RL i cztery piny oznaczone: TxD, RxD, PD1 i PD0.

    [Atmega16][Assembler] Symulacja OK, program dziala inaczej
    Obrazek przedstawia fragment mojej makiety z układem FT232RL

    Wiec raczej z tej metody nie będę mógł skorzystać.
  • #13 9067812
    elektrofil
    Poziom 17  
    Trochę to mało, bez podlutowania pod nogi ft232rl 4-rech kabelków się nie obejdzie.
    TxD idzie od ft232rl, niestety przez zworkę na TxD procesora (PD1) to samo z Rxd.
    i obiecane fusy:
    [Atmega16][Assembler] Symulacja OK, program dziala inaczej
  • #14 9085645
    Student_Bartosh
    Poziom 9  
    W końcu się ogarnąłem i poszedłem tam, gdzie kupiłem makietę. Na miejscu koleś wgrał mi bootloadera na tą drugą Atmegę, a pierwszą Atmęgę (ta przez którą jest ten temat) wziął do serwisu :D Miał dziwną minę, kiedy próbował coś tam wgrać. Jutro mam się po nią zgłosić. Udało się trochę zaoszczędzić na programatorze.

    Jeśli chodzi o programy, to po wgraniu oba działają. Jest tak jak miało działać w założeniu.

    Dalej nie wiem dlaczego uC który miałem na makiecie nie działał i musiałem zakupić nowy.

    Mam jeszcze pytanie do elektrofil'a. Program, który zamieściłeś. Jak realizujesz opóźnienia? Chciałbym zrobić tak, żeby po wciśnięciu odpowiedniego przycisku diody mrugały w zaprogramowanej sekwencji.
REKLAMA