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

[ASM][ATTINY2313] Prośba o sprawdzenie programu

wojtek8-7 16 Lut 2010 23:14 2525 22
REKLAMA
  • #1 7706083
    wojtek8-7
    Poziom 13  
    Bardzo proszę o sprawdzenie tego programu i napisanie co jest źle, dlaczego ten program nie działa tak jak powinien.

    Mikrokontroler to Attiny 2313, diody podłączone do portu B zapalane 0, klawisze na porcie D zwierające do masy.

    Zadaniem programu było zapalenie lub gaszenie diody w zależności od stanu poprzedniego, realizowane na przerwaniu

    
    .INCLUDE "TN2313DEF.INC"
    	.CSEG
    	.ORG 0x00
    	RJMP RESET
    	.ORG 0X01
    	RET
    	.ORG 0X02
    	RJMP INTERRUPT1
    
    
    RESET:
    	LDI R16,0XFF
    	OUT DDRB,R16
    	OUT PORTB,R16
    
    	LDI R16,0
    	OUT DDRD,R16
    	LDI R16,0XFF
    	OUT PORTD,R16
    
    	LDI R16,0X0F
    	OUT MCUCR,R16
    
    	LDI R16,0XFF
    	OUT GIMSK,R16
    	SEI
    
    POCZ:
    	NOP
    	RJMP POCZ
    
    
    INTERRUPT1:
    	RJMP STOP
    	IN R17,PORTB
    	ANDI R17,0B00000001
    	LDI R18,0X01
    	CPSE R18,R17
    	LDI R17,0B11111111
    	LDI R17,0B11111110
    	ANDI R17,0B10000001
    	OUT PORTB,R17
    	RETI
    
    
    STOP:
    	LDI R19,0XFF
    SK:	LDI R20,0XFF
    S:	DEC R20
    	BRNE S
    	DEC R19
    	BRNE SK
    	RET
    
  • REKLAMA
  • Pomocny post
    #2 7706539
    michalko12
    Specjalista - Mikrokontrolery
    Po pierwsze błąd jest w tytule wątku!

    Po drugie, jeśli ty pisałeś ten kod a nie jest to jakieś zadanie szkolne to pomyśl trochę
    nad tym:



    	CPSE R18,R17
    	LDI R17,0B11111111
    	LDI R17,0B11111110


    Całą tą procedurę przerwania można zrobić prościej.
  • #3 7706920
    wojtek8-7
    Poziom 13  
    Witam!

    Nie jest to zadanie szkolne.

    No fakt jest tam błąd, z tego kodu wynika, że zawsze będzie włączona jedna dioda, niestety jak wrzucam to do procesora to nie świeci się żadna dioda... Procesor, płytka i połączone diody są dobrze bo działają na nich inne programy. W takim razie co jest źle?
  • REKLAMA
  • Pomocny post
    #4 7707004
    kemot55
    Poziom 31  
    Ogólnie nie cierpię AVR'ów ! no ale...
    W przerwaniu jest błąd.
    Cytat:

    
    INTERRUPT1:
       RJMP STOP 
    


    Używasz polecenia RJMP (skok w pierwszej linii przerwania do etykiety a nie do procedury STOP) a na końcu RET (czyli powrót z procedury ->w Twoim przypadku program leci "w kosmos"). Lepiej wpisz tam RCALL, albo wpisz cały kod w przerwaniu. Ale po co opóźnienia w przerwaniu to już zupełnie nie wiem.
  • Pomocny post
    #5 7707029
    zumek
    Poziom 39  
    wojtek8-7 napisał:
    ...dlaczego ten program nie działa tak jak powinien.

    a)Zapomniałeś zainicjować wskaźnik stosu(SP)
    b)Doczytaj kiedy stosować RET, a kiedy RETI.
    
       .ORG 0X01
       RET
    

    c)RJMP to nie to samo co RCALL.
    
    INTERRUPT1:
       RJMP STOP
    ;...
       RETI
    
    
    STOP:
       LDI R19,0XFF
    SK:   LDI R20,0XFF
    S:   DEC R20
       BRNE S
       DEC R19
       BRNE SK
       RET
    
  • #6 7707228
    wojtek8-7
    Poziom 13  
    Po waszych uwagach program teraz wygląda tak:

    
    .INCLUDE "TN2313DEF.INC"
    	.CSEG
    	.ORG 0x00
    	RJMP RESET
    	.ORG 0X01
    	RETI
    	.ORG 0X02
    	RJMP INTERRUPT1
    
    
    RESET:
    	LDI R16,127
    	OUT SPL,R16
    	LDI R16,0XFF
    	OUT DDRB,R16
    	OUT PORTB,R16
    
    	LDI R16,0
    	OUT DDRD,R16
    	LDI R16,0XFF
    	OUT PORTD,R16
    
    	LDI R16,0X0F
    	OUT MCUCR,R16
    
    	LDI R16,0XFF
    	OUT GIMSK,R16
    	SEI
    
    POCZ:
    	NOP
    	SEI
    	RJMP POCZ
    
    
    INTERRUPT1:
    	RCALL STOP
    	IN R17,PORTB
    	ANDI R17,0B00000001
    	LDI R18,0X01
    	CP R18,R17
    	BRNE SKOK
    	LDI R17,0B11111110
    	RJMP WYJSCIE
    SKOK:
    	LDI R17,0B11111111
    WYJSCIE:
    	OUT PORTB,R17
    	RETI
    
    
    STOP:
    	LDI R19,0XFF
    SK:	LDI R20,0XFF
    S:	DEC R20
    	BRNE S
    	DEC R19
    	BRNE SK
    	RET
    


    Teraz już wszystko działa. Ja się dopiero uczę programować i każda uwaga będzie mile widziana, proszę śmiało pisać co zrobiłem źle i co można zrobić lepiej.
  • REKLAMA
  • #7 7707786
    michalko12
    Specjalista - Mikrokontrolery
    wojtek8-7 napisał:
    ... i co można zrobić lepiej.


    INTERRUPT1:
       RCALL STOP
       IN R17,PORTB
       LDI R18,0X01
       EOR R17,R18
       OUT PORTB,R17
       RETI    
  • #8 7716489
    wojtek8-7
    Poziom 13  
    Żeby nie zakładać nowego tematu napiszę tutaj. Może ktoś napisać jak się korzysta z tablic w AVR? Jak zainicjować tablice, jak z niej odczytać i zapisać dane, wszystko w asemblerze. Będę bardzo wdzięczny ponieważ długo się już z tym męczę i dużo szukałem, na razie bezskutecznie.
  • #9 7716515
    michalko12
    Specjalista - Mikrokontrolery
    wojtek8-7 napisał:
    Będę bardzo wdzięczny ponieważ długo się już z tym męczę i dużo szukałem, na razie bezskutecznie.


    Pokaż co zmęczyłeś, to może ktoś cię naprowadzi.
  • #10 7716591
    wojtek8-7
    Poziom 13  
    Znalazłem coś takiego:

    .DSEG
    .ORG $60
    INDEX: .BYTE 1
    TABLICA: .BYTE 40

    .CSEG
    LDS R16, INDEX
    LDI XL, LOW(TABLICA)
    LDI XH, HIGH(TABLICA)
    ADD XL, R16
    LDI R16, 0
    ADC XH, R16
    LD R16, X

    ale nie bardzo to rozumnie. Dużo jest opisów jak to zrobić w C niestety mało w asemblerze. Próbuję się dowiedzieć jak się inicjuje tablice itp.
  • #11 7719253
    grysek
    Poziom 19  
    To co pokazałeś to jest właśnie doczyt z Tablicy elementu określonego zmienną INDEX. Musisz pojąć jedną rzecz w asm nie ma dosłownie czegoś takiego jak tablica, jest tylko zarezerwowany obszar pamieci a Twoim przypadku etykieta Tablica jest to właśnie adres początku tego obszaru, tak więc jeśli dodasz do tego zawartość INDEX wtedy otrzymasz adres komórki z której chcesz odczytać.

    Ten adres właśnie jest w rejestrze adresowym X. I wtedy tylko używamy Instrukcji LD czyli ładujemy tą wartość do rejestru R16.

    Nie bardzo tylko rozumiem o co chodzi Ci z tym inicjowaniem tablicy?
  • #12 7727887
    wojtek8-7
    Poziom 13  
    Napisałem taki prosty programik, żeby dane były wystawiane po kolei na port B. Niestety program nie działa, mógłby ktoś pokazać mi co zrobiłem źle?

    
    .include "tn2313def.inc"
    
    LDI R16,127 
    OUT SPL,R16
    
    LDI R16,0XFF
    OUT DDRB,R16
    OUT DDRB,R16
    
    LDI R16,0X10
    OUT PORTD,R16
    
    .DSEG 
    .ORG $60 
    INDEX: .BYTE 1 
    .CSEG 
    
    
    LDS R16, INDEX 
    
    POCZ:
    
    
    LDI XL, LOW(TABLICA) 
    LDI XH, HIGH(TABLICA) 
    ADD XL, R16 
    LDI R16, 0 
    ADC XH, R16 
    LD R16, X
    
    OUT PORTB,R16
    RCALL CZEKAJ
    INC XL
    RJMP POCZ
    
    CZEKAJ:
    	LDI R17,0X55
    K:	LDI R18,0Xff
    S:	DEC R18
    	BRNE S
    	DEC R17
    	BRNE K
    	RET
    
    
    TABLICA: .db 0x28,0x7D,0x32,0X34,0x65,0XA4,0XA0,0X3D,0X20,0X24
    
  • #13 7728201
    grysek
    Poziom 19  
    Kilka podstawowych reczy:
    Dane zapisałeś do pamieci programu w więc za pomocą LD tego nie wczytasz. Musisz odczytywac je za pomocą instrukcji LPM, a co za tym idzie do adresowania musisz użyć rejestru adresowego Z - bo tego wymaga ta instrukcja.
    Poza tym w pętli cały czas ładujesz do rejestru ten sam adres wiec nie ma szans aby odczytywać kolejne bajty, lecz odczytywany byłby ten pierwszy.

    powinno raczej to wyglądać tak:

    main:
    LDI ZL, LOW(TABLICA*2) ; bo w pamięci adresowane są słowa 
    LDI ZH, HIGH(TABLICA*2) 
    LDI r17, 10 
    POCZ:                          
    LPM r16, Z+            ;instrukcja umożliwia jednocześnie inkrementację adresu
    OUT PORTB,R16 
    RCALL CZEKAJ 
    DEC  r17
    BRNE POCZ
    rjmp main


    W dodatku podprogram czekaj trwa za krótko, kolejne wrtości na PORTB będą pojawiały się około 46 razy na sekundę przy zegarze 1Mhz
  • REKLAMA
  • #14 7728540
    wojtek8-7
    Poziom 13  
    Wszystko ładnie działa, nie rozumnie tylko jednej rzeczy. Dlaczego ładujesz do rejestru Z TABLICA*2?
  • Pomocny post
    #15 7728620
    grysek
    Poziom 19  
    Bo dane w pamieci programu adresowane są po 2 bajty i żeby dostać adres pojedynczego bajtu trzeba adres pomnożyć przez 2 :P

    Tylko przy odczycie z pamięci programu musisz tak zrobić

    PS. Piszą o tym coś w datasheecie na stronie 155, jak jesteś ciekaw więcej szczegółów :P
  • #16 7732780
    wojtek8-7
    Poziom 13  
    Dzięki za pomoc, jak będę miał jeszcze jakiś problem to się tu odezwę.
  • #17 7750971
    wojtek8-7
    Poziom 13  
    Witam ponownie.

    Poznałem już tablice, wyświetlacz siedmiosegmentowy teraz przyszedł czas na termometr, czyli układ DS18B20 i magistrale 1-Wire.

    Próbuję nawiązać komunikację z układem, niestety na razie bezskutecznie. Na podstawie informacji z tej strony: http://www.1-wire.rms.biz.pl/ napisałem taki program:
    
    .include "tn2313def.inc"
    
    START:
    
    	LDI R16,127
    	OUT SPL,R16
    
    	LDI R16,0XFF
    	OUT DDRB,R16
    	LDI R16,0XFE
    	OUT DDRD,R16
    	LDI R16,0XFF
    	OUT PORTB,R16
    	OUT PORTD,R16
    	SBI PIND,0
    	RCALL CZEKAJ_570US
    	RCALL CZEKAJ_570US
    	CBI PIND,0
    	RCALL CZEKAJ_570US
    	LDI R16,0XFE
    	OUT PORTB,R16
    	SBI PIND,0
    CZEKAJ:
    	SBIS PIND,0
    	RJMP DALEJ
    	RJMP CZEKAJ
    
    DALEJ:
    	LDI R16,0B11111100
    	OUT PORTB,R16
    CZEKAJ2:
    	SBIC PIND,0
    	RJMP DALEJ2
    	RJMP CZEKAJ2
    
    DALEJ2:
    	LDI R16,0B11111000
    	OUT PORTB,R16
    POCZ:
    	RJMP CZEKAJ_570US
    	RJMP POCZ
    
    
    
    CZEKAJ_570US:
    	LDI R17,1;10
    K:	LDI R16,1;0XBE
    S:	DEC R16
    	BRNE S
    	DEC R17
    	BRNE K
    	RET
    
    


    DS znajduje się na porcie D0.
    Wystawiam na D0 stan niski na czas ok 570us i czekam na odpowiedz układu i nic... Na porcie B zapalam kolejno diody w celu sprawdzenia na którym etapie program przestał działać. Niestety zapaliła się tylko 1 dioda. Proszę o pomoc, napisanie co robię źle lub gdzie mogę się dowiedzieć więcej na temat 1-wire.



    Znalazłem błąd! :)
    Pin D0 do którego podłączony jest DS był źle skonfigurowany. Teraz cały port D skonfigurowany jest jako wyjście i jest ok.
  • #18 7757896
    wojtek8-7
    Poziom 13  
    Witam!

    Napisałem program na obsługę DS18B20 jednak jak zwykle on nie działa.

    Pod pin D0 podłączony jest DS, temperaturę chcę pokazać na porcie B, program ciągle pokazuje 85 st C..... Procesor (Attiny2313) taktowany jest 10MHz, pętle opóźnień sprawdzałem w symulatorze i trwają odpowiednią ilość czasu. Mógłby ktoś spojrzeć na program i sprawdzić co robię źle? Oczywiście linia danych jest podciągnięta do 5V przez rezystor 4,7K

    
    .include "tn2313def.inc"
    
    	LDI R16,127
    	OUT SPL,R16
    
    	LDI R16,0XFF
    	OUT DDRD,R16
    	LDI R16,0XFF
    	OUT DDRB,R16
    	OUT PORTD,R16
    	OUT PORTB,R16
    
    MAIN:
    	SBI PIND,0
    	RCALL STOP750
    	RCALL INIC
    	LDI R20,0XCC
    	RCALL WYSLIJ	;WYSŁANIE KOMENDY SKIP ROM
    	LDI R20,0X44
    	RCALL WYSLIJ	;ROZPOCZNIJ POMIAR TEMP. CONVERT T
    	RCALL STOP750
    	LDI R20,0XCC
    	RCALL WYSLIJ
    	LDI R20,0XBE
    	RCALL WYSLIJ
    	RCALL ODBIERZ
    	MOV R30,R20
    	RCALL ODBIERZ
    	MOV R31,R20
    	
    	LSR R30
    	LSR R30
    	LSR R30 
    	LSR R30
    
    	ANDI R31,0X07
    	LSL R31
    	LSL R31
    	LSL R31
    	LSL R31
    
    	OR R30,R31
    
    	OUT PORTB,R30
    	SBI PIND,0
    	RCALL STOP500
    	RCALL STOP500
    	RCALL STOP500
    	 
    	RJMP MAIN
    
    STOP750:
    	LDI R23,10
    SW:	LDI R24,250
    SA:	DEC R24
    	BRNE SA
    	DEC R23
    	BRNE SW
    	RET
    
    
    WYSLIJ:
    	MOV R16,R20
    	LDI R17,8
    NEXT:
    	SBRC R16,0
    	RJMP JEDEN
    	RJMP ZERO
    JEDEN:
    	CBI PIND,0
    	RCALL STOP1
    	SBI PIND,0
    	RCALL STOP45
    	RJMP DALEJ
    
    ZERO:
    	CBI PIND,0
    	RCALL STOP60
    	SBI PIND,0
    	RCALL STOP1
    	RJMP DALEJ
    
    DALEJ:
    	RCALL STOP1
    	LSR R16
    	DEC R17
    	BRNE NEXT
    	RET
    
    
    
    
    INIC:
    	CBI PIND,0
    	RCALL STOP500
    	SBI PIND,0
    CZEKAJ: 
       	SBIS PIND,0 
       	RJMP DAL 
       	RJMP CZEKAJ 
    
    DAL: 
       	LDI R16,0B11111100 
       	OUT PORTB,R16 
    CZEKAJ2:
    	RCALL STOP60 
    	SBI PIND,0
       	SBIC PIND,0 
       	RJMP DALEJ2 
       	RJMP CZEKAJ2 
    
    DALEJ2: 
       	LDI R16,0XF7
       	OUT PORTB,R16 
     
       	RET
    
    
    STOP1:
    	LDI R21,4
    SS:	DEC R21
    	BRNE SS
    	RET
    
    STOP500:
    	LDI R21,10
    K:	LDI R18,170
    S:	DEC R18
    	BRNE S
    	DEC R21
    	BRNE K
    	RET
    
    
    STOP45:
    	LDI R18,170
    SSS:
    	DEC R18
    	BRNE SSS
    	RET
    
    STOP60:
    	LDI R18,250
    KK:	DEC R18
    	BRNE KK
    	RET
    
    ODBIERZ:
    	LDI R17,1
    	LDI R18,0
    XX:	RCALL CZYTAJ
    	CPI R19,0
    	BREQ SKOK
    	OR R18,R17
    SKOK:
    	RCALL STOP9
    	LSL R17
    	CPI R17,0
    	BRNE XX
    	MOV R20,R18
    	RET
    
    
    
    
    CZYTAJ:
    	LDI R19,0
    	CBI PIND,0
    	RCALL STOP1
    	RCALL STOP1
    	SBI PIND,0
    	RCALL STOP15
    	LDI R19,1
    	SBIS PIND,0
    	LDI R19,0
    	RET
    
    STOP15:
    	LDI R21,50
    KKK:	
    	DEC R21
    	BRNE KKK
    	RET
    
    STOP9:
    	LDI R21,30
    SK:	DEC R21
    	BRNE SK
    	RET
    


    Wydłużyłem pętle 750us (STOP750) na grubo ponad 750 ms i dalej nie działa
  • Pomocny post
    #19 7760082
    grysek
    Poziom 19  
    Prawdopodobnie problem tkwi w odstępach czasowych :P Mój działający kod wysłąłem Ci na PW. Mam nadzieje że to Ci pomoże :D
  • #20 7760872
    zumek
    Poziom 39  
    wojtek8-7 napisał:
    Witam!

    Napisałem program na obsługę DS18B20 jednak jak zwykle on nie działa.

    No to chyba pora zweryfikować swoją wiedzę o asemblerze AVR.
    Co to za ... "kwiatki" :?:
    
       SBI PIND,0   ; toggle PORTD,0
    ;...
       CBI PIND,0   ;???
    
  • #21 7760978
    wojtek8-7
    Poziom 13  
    zumek napisał:

    Co to za ... "kwiatki" :?:
    
       SBI PIND,0   ; toggle PORTD,0
    ;...
       CBI PIND,0   ;???
    


    
    .include "tn2313def.inc"
    
    	LDI R16,127
    	OUT SPL,R16
    
    	LDI R16,0XFF
    	OUT DDRB,R16
    	OUT	PORTB,R16
    
    
    START:
    	RCALL POCZ
    	SBI PINB,0
    	RCALL POCZ
    	CBI PINB,0
    	RCALL POCZ
    	RJMP START
    
    
    
    pocz:
    	ldi r16,50
    O:	LDI R17,100
    K:	LDI R18,250
    S:	DEC R18
    	BRNE S
    	DEC R17
    	BRNE K
    	DEC R16
    	BRNE O
    	NOP
    	NOP
    	RET
    
    
    


    Napisałem właśnie taki o to program i program działa zgodnie z założeniem, miganie diody na porcie B.0. Program zarówno działa z PINB jak i PORTB......


    A termometr dalej nie działa, ciągle jest temp 85st

    :arrow:GRYSEK dzięki za pomoc :)
  • #22 7762237
    zumek
    Poziom 39  
    wojtek8-7 napisał:

    Napisałem właśnie taki o to program i program działa zgodnie z założeniem, miganie diody na porcie B.0. Program zarówno działa z PINB jak i PORTB......

    A termometr dalej nie działa, ciągle jest temp 85st

    A więc sam widzisz, że obecnie Twoja wiedza o AVR-ku, wystarcza jedynie na miganie LED-ką - wybacz sarkazm :D
    Wróćmy do
    Atmel w dokumentacji ATTiny2313 napisał:

    Three I/O memory address locations are allocated for each port, one each for the Data
    Register – PORTx, Data Direction Register – DDRx, and the Port Input Pins – PINx. The
    Port Input Pins I/O location is read only, while the Data Register and the Data Direction
    Register are read/write. However, writing a logic one to a bit in the PINx Register, will
    result in a toggle in the corresponding bit in the Data Register...


    Poza tym, w Twoim kodzie "kwiatków" jest więcej, ot choćby ustawienie pinu podłączonego do magistrali 1wire jako wyjście w stanie wysokim i próba odczytu stanu tej linii - myślisz że DS18b20 potrafi taką linię "ściągnąć" do GND :?:
    itp.
  • #23 7762388
    wojtek8-7
    Poziom 13  
    Niestety angielskiego nie znam w takim stopniu aby zrozumieć data sheeta i programowania uczę się doświadczalnie na podstawie skąpych kursów internetowych. Oczywiści istnieją książki tematyczne, ale na razie wstrzymam się z ich kupnem.... Jak znalazłeś jakiś błąd to pokaż mi go, po to napisałem na forum. Nie jestem doświadczonym programistą, dopiero się uczę i mam prawo robić błędy. Chociaż próbuje się czegoś nauczyć i staram się samemu coś zrobić a nie czekam na gotowe.

    Wracając do PIND to przeczytałem o tym w tym temacie: https://www.elektroda.pl/rtvforum/topic949656.html Czyli jak w końcu pisać Pind czy Portd ?
REKLAMA