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

Bascom AVR: Ustawienia czasu w automacie schodowym na ATtiny2313 nie działają

electro_Nick 24 Mar 2005 15:30 4856 30
Najlepsze odpowiedzi LABEL_AI_GENERATED

Dlaczego ustawianie czasu zworkami nie działa w automacie schodowym na ATtiny2313 i wyłączenie następuje zawsze po tym samym czasie?

Problem wynikał głównie z błędnego odczytu przełączników i niepoprawnej konfiguracji timera: trzeba czytać stan wejść z `PINB`, a nie z `PORTB`, bo `PORTB` pokazuje latch wyjściowy, nie aktualny stan pinów [#1355250] W poprawionej wersji ustawiono też `$crystal = 8867000` w Hz oraz spójny `Prescale = 1024`, bo od tych wartości zależy wyliczenie czasu przerwania i długość odliczania [#1353941][#1354068] Zamiast ręcznie składać BCD, lepiej pobrać wartość z `PINB`, odwrócić bity zworki, a potem użyć `Lookup` do wyboru liczby sekund dla `Licznikczasu` [#1353941] Timer1 powinien być przeładowywany w procedurze przerwania, a licznik czasu zmniejszany w ISR; gdy dojdzie do zera, należy wyłączyć wyjścia i ewentualnie wyłączyć Timer1 [#1353941] Autor wątku potwierdził później, że po tych poprawkach program działał prawidłowo [#1359118]
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA
  • #1 1344712
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    Potrzebuje pomocy z Bascomem! Oto moj plik zrodlowy, program ma (w podstawowej wersji) dzialac jak automat schodowy, a po kompilacji i programowaniu obojetnie jak ustawie zworki(wedle schematu) swiatlo wylacza sie po tym samym czasie(ok7,8s)... Czemu??? Jakby co to SW1 jest do ustawiania czasu(wedle BCD) a SW2 do ustawiania trybu(jak na razie tylko kilka jest zaimplementowanych). Wlacznik zwiera do masy... Oto zrodlo:
    'Program do pracy dyplomowej !Wylacznik schodowy i cos ponadto!
    Dim Czas As Byte , Tryb As Byte , Jedynkaczas As Byte , Dwojkaczas As Byte
    Dim Czworkaczas As Byte , Jedynkatryb As Byte , Dwojkatryb As Byte
    Dim Czworkatryb As Byte , Osemkatryb As Byte , Trybpomoc As Byte , Trybpomocdwa As Byte
    Dim Osemkaczas As Byte , Czaspomoc As Byte , Czaspomocdwa As Byte , Czasik As Byte
    Config Portb = Input : Portb = &B11111111 'wedle schematu
    Config Portd = &B0111100 : Portd = &B1000011 'dipswitche to wejscia...
    Config Timer1 = Timer , Prescale = 1024
    Config Aci = Off
    Enable Interrupts
    Enable Timer1
    On Timer1 Doliczanie
    Do
    If Pinb.7 = 0 Then 'wszystko zczytane z dipswitchy
    Jedynkaczas = 1 'jest zamieniane na kod BCD
    Else 'moze troche nieelegancko
    Jedynkaczas = 0 'ale powinno dzialac...
    End If
    If Pinb.6 = 0 Then
    Dwojkaczas = 2
    Else
    Dwojkaczas = 0
    End If
    If Pinb.5 = 0 Then
    Czworkaczas = 4
    Else
    Czworkaczas = 0
    End If
    If Pinb.4 = 0 Then
    Osemkaczas = 8
    Else
    Osemkaczas = 0
    End If
    Czaspomoc = Jedynkaczas + Dwojkaczas 'zsumuj kod bcd
    Czaspomocdwa = Czworkaczas + Osemkaczas
    Czas = Czaspomoc + Czaspomocdwa 'i zamien na dziesietny(recznie)
    If Pinb.3 = 0 Then 'to samo z dipswitchami
    Jedynkatryb = 1 'od ustawiania trybu...
    Else
    Jedynkatryb = 0
    End If
    If Pinb.2 = 0 Then
    Dwojkatryb = 2
    Else
    Dwojkatryb = 0
    End If
    If Pinb.1 = 0 Then
    Czworkatryb = 4
    Else
    Czworkatryb = 0
    End If
    If Pinb.0 = 0 Then
    Osemkatryb = 8
    Else
    Osemkatryb = 0
    End If
    Trybpomoc = Jedynkatryb + Dwojkatryb 'znowu zamiana na decimal
    Trybpomocdwa = Czworkatryb + Osemkatryb 'z kodu BCD
    Tryb = Trybpomoc + Trybpomocdwa 'koniec wyboru czasu
    Debounce Pind.6 , 0 , Wlaczanie , Sub 'gdy zostanie przycisniety
    Loop
    End
    Wlaczanie:
    Select Case Czas 'wybor czasu wylacznia
    Case 0 'czasy wylaczen
    Czasik = 254 '7 sekund
    Case 1
    Czasik = 253 '14 sekund
    Case 2
    Czasik = 252 '21 sekund
    Case 3
    Czasik = 251 '28 sekund
    Case 4
    Czasik = 248 '50 sekund
    Case 5
    Czasik = 247 '60 sekund
    Case 6
    Czasik = 244 '80 sekund
    Case 7
    Czasik = 241 '100 sekund
    Case 8
    Czasik = 238 '2 minuty
    Case 9
    Czasik = 230 '2,5 minuty
    Case 10
    Czasik = 221 '4 minuty
    Case 11
    Czasik = 204 '6 minut
    Case 12
    Czasik = 186 '8 minut
    Case 13
    Czasik = 127 '15 minut
    Case 14
    Czasik = 84 '20 minut
    Case 15
    Czasik = 1 '30 minut
    Case Else 'w innym przypadku...
    Czasik = 252 '10 sekund
    End Select
    Timer1 = 1
    Select Case Tryb
    Case 0 'tryb zerowy-
    Set Portd.5 'wszystkie zarowki
    Set Portd.4 'sa zapalane na ustalony
    Set Portd.3 'czas...
    Set Portd.2
    Return
    Case 1
    Set Portd.2
    Bitwait Pind.6 , Reset
    Set Portd.3
    Reset Portd.2
    Bitwait Pind.6 , Reset
    Set Portd.4
    Reset Portd.3
    Bitwait Pind.6 , Reset
    Set Portd.5
    Reset Portd.4
    Return
    Case 2
    Set Portd.2
    Set Portd.3
    Bitwait Pind.6 , Reset
    Set Portd.4
    Set Portd.5
    Reset Portd.2
    Reset Portd.3
    Bitwait Pind.6 , Reset
    Gosub Wylacz
    Case 3
    Set Portd.2
    Set Portd.3
    Set Portd.4
    Set Portd.5
    Bitwait Pind.6 , Reset
    Return
    Case Else
    Set Portd.5 'wszystkie zarowki
    Set Portd.4 'sa zapalane na ustalony
    Set Portd.3 'czas...
    Set Portd.2
    Return
    End Select
    Return
    Doliczanie:
    Incr Czasik
    If Czasik >= 120 Then
    Reset Portd.2
    Reset Portd.3
    Reset Portd.4
    Reset Portd.5
    End If
    Return
    Wylacz:
    Reset Portd.2
    Reset Portd.3
    Reset Portd.4
    Reset Portd.5
    Return
    Załączniki:
    • Bascom AVR: Ustawienia czasu w automacie schodowym na ATtiny2313 nie działają Lipaa.jpg (35.65 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • REKLAMA
  • #2 1346216
    Mol
    Poziom 31  
    Posty: 1168
    Pomógł: 152
    Ocena: 103
    Config Portb = Input : Portb = &B11111111 'wedle schematu
    Config Portd = &B0111100 : Portd = &B1000011 'dipswitche to wejscia...


    Zamiast tego sprubój ddrb = &B00000000, ddrd = &B11111111 , nie wiem czemu portb ustawiasz ( Portb = &B11111111) przeciesz to wejścia.No i podłącz od plusa jakieś oporniki pod oba porty.
  • #3 1346262
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Mol napisał:
    [...] nie wiem czemu portb ustawiasz ( Portb = &B11111111) przeciesz to wejścia.No i podłącz od plusa jakieś oporniki pod oba porty.

    1. Po co pod port wyjściowy rezystory podciagające ? Jak już to do GND, aby przy resecie cudów nie było (stan wysokiej impedancji)
    2. Nie słyszał kolega, ze przy takiej konfiguracji (DDRX=0 PORTX=1) portów podciągnięcie już jest po wewnętrznych rezystorach w µkontrolerze ? Polecam http://www.atmel.com/AVR ;), jest tam sporo dokumentacji...
    :arrow: electro_Nick :
    Może jednak by "czasik" w procedurze timera zmniejszać i gdy się wyzeruje podjąć akcję wyłączenia ?
    Pozdr. Light-I
  • #4 1348251
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    @Mol:
    port ustawiam zeby rezystory podciagajace sie wlaczyly...
    @light
    jaka to roznica zeby zmiejszac? Powinno teoretycznie dzialac w obu przypadkach... Ale moge sprobowac....
  • #5 1348267
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    electro_Nick napisał:
    @light
    jaka to roznica zeby zmiejszac? Powinno teoretycznie dzialac w obu przypadkach... Ale moge sprobowac....

    Bo w każdym przypadku układ się wyłączy, jak licznik dojdzie do 120, no nie ?
    Zamiast "nielegancko" zamieniać kod switchy na BCD, nie lepiej przykładowo wczytać całość stanu portu ?:
    BTW : Dla czytelności warto kod programu zaznaczyć myszą i wcisnąć przycisk "Code", zajmuje wtedy on minej miejsca przy czytaniu i łatwiej jest wyodrębnić logiczną całość. Podprocedury można odzielic pustymi liniami.
    Pozdr. Lighti
  • #6 1348547
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    electro_Nick napisał:
    Potrzebuje pomocy z Bascomem! Oto moj plik zrodlowy, program ma (w podstawowej wersji) dzialac jak automat schodowy, a po kompilacji i programowaniu obojetnie jak ustawie zworki(wedle schematu) swiatlo wylacza się po tym samym czasie(ok7,8s)... Czemu???


    UPDATE:
    Powinieneś usunąć "Return-y" w:
    Select Case Tryb
    ..

    Pozdrawiam
    Piotrek

    PS
    I czemu jest tak .... dziwnie napisany :wink:
  • #7 1348671
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Nie widzę oświeżania TCNT1, co nie jest zbyt dużym pominięciem, bo będzie działać, ale czas wywoływania można doprecyzować, bo póki co przerwanie wykonuje się co $$\frac {Xtal}{1024 \cdot 256}$$. Nie widze definicji zegara (Xtal).

    Co do kodu można go niebywale skrócić wstawką asemblerową (pewnie w bascom też jest możliwość optymalizacji, ale ja wolę asm... ;) Spokojnie wywalamy ten "skomplikowany" kod konwersji stanów switchy na czas i tryb oraz wyrzucamy zmienne : Jedynkaczas, Dwojkaczas, Czworkaczas, Jedynkatryb, Dwojkatryb, Czworkatryb, Osemkatryb, Trybpomoc, Trybpomocdwa, Osemkaczas, Czaspomoc, Czaspomocdwa
    ----------------------------------
    Edit : usunięto niedopracowany kod... :)
    ----------------------------------
    Oczywiście wpisywane dane dla "Czasik" są inne, ale to już jak na mnie za duzo do poprawiania. w podobnych programach pisanych pod AVRasm2 robię tak, że kompilator przelicza żądany czas na wpisywane wartości, mając do dyspozycji prędkość zegara (Xtal) i okres wywołań i mogę wtedy sobie hulac z różnymi kwarcami i preskalerem timera, a i tak wszystko bedzie latać jak należy.
    Pozdrawiam Light-I
  • REKLAMA
  • #8 1348937
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    LightHouser napisał:
    Nie widzę oświeżania TCNT1, co nie jest zbyt dużym pominięciem, bo będzie działać, ale czas wywoływania można doprecyzować, bo póki co przerwanie wykonuje się co $$\frac {Xtal}{1024 \cdot 256}$$. Nie widze definicji zegara (Xtal).


    Ja bym powiedział , że $$\frac {Xtal}{1024 \cdot 65536}$$ bo T1 pracuje w trybie 16-bit .

    Pozdrawiam
    Piotrek
  • #9 1349014
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    zumek napisał:

    Ja bym powiedział , że $$\frac {Xtal}{1024 \cdot 65536}$$ bo T1 pracuje w trybie 16-bit .

    Racja, mi najbardziej jednak chodziłoby o to, aby zrobic tak, że przerwanie wystepuje dokładnie co sekundę, wtedy Czasik byłby w sekundach, a jego rozmiar może być zamiast Byte - Word... - zabarłbym się nawet do edycji poprzedniego postu, ale nie mam zmiennej Xtal... ;)
    Pozdr, Light-I
  • #10 1351009
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    Podlaczam uklad do Xtala 8867KHz, ale w bascomie to niepotrzebne no nie?

    Dodano po 35 [minuty]:

    @light:
    cos jest z tym Twoim programem nietak... Teraz zarowka wcale sie nie wylacza... A nawet prescale zmienilem na 8...
  • REKLAMA
  • #11 1351453
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Już pisałem (pod źródłami) co jest nie tak... Co do Xtal to w każdym języku jest to istotne... Jeżeli zmieniasz kwarc to piszesz program od nowa ? A tak jak uzależnisz wartości zmiennych od Xtal i prescale to zmieniasz definicje na początku, a program działa dalej prawidłowo...
    No to poprawiony kod (niesprawdzony ;) ) :
    CONST T1_Prescale = 1024
    CONST T1_Okres = 500 ' ms
    CONST Podzial_ms = 1000 ' milisecond divisor
    CONST OkresoSekunda = Podzial_ms / T1_Okres
    CONST T1Delay = (_XTAL/(OkresoSekunda*T1_Prescale))	
    DIM NastawaCzasu As Byte, NastawaTrybu As Byte, LicznikCzasu As Word
    CONFIG Timer1 = Timer , Prescale = T1_Prescale
    CONFIG ACI = Off
    LOAD Timer1, T1Delay
    CONFIG PORTB = Input : PORTB = &B11111111 'wedle schematu
    CONFIG PORTD = &B0111100 : PORTD = &B1000011 'dipswitche to wejscia...
    ENABLE Timer1
    ENABLE Interrupts
    On Timer1 PomiarCzasu
    Do
    Debounce Pind.6 , 0 , Wlaczanie , Sub 'gdy zostanie przycisniety
    Loop
    End ' Ta instrukcja się nie wykona, jest tylko dla ozdoby ;-)
    '------------------
    Wlaczanie:
    $asm
    in r16, PINB
    com r16
    ldi r18, 8
    OdwracanieBit:
    clc
    ror r16
    rol r17
    dec r18
    brne OdwracanieBit
    mov r16, r17
    swap r17
    andi r16, 0x0F
    andi r17, 0x0F
    sts {NastawaCzasu}, r16
    sts {NastawaTrybu}, r17
    $end asm
    Select Case NastawaCzasu 'wybor czasu wylacznia
    Case 0 'czasy wylaczen
    LicznikCzasu = 7*OkresoSekunda '7 sekund
    Case 1
    LicznikCzasu = 14*OkresoSekunda '14 sekund
    Case 2
    LicznikCzasu = 21*OkresoSekunda '21 sekund
    Case 3
    LicznikCzasu = 28*OkresoSekunda '28 sekund
    Case 4
    LicznikCzasu = 50*OkresoSekunda '50 sekund
    Case 5
    LicznikCzasu = 60*OkresoSekunda '60 sekund
    Case 6
    LicznikCzasu = 80*OkresoSekunda '80 sekund
    Case 7
    LicznikCzasu = 100*OkresoSekunda '100 sekund
    Case 8
    LicznikCzasu = 2*60*OkresoSekunda '2 minuty
    Case 9
    LicznikCzasu = 5*30*OkresoSekunda '2,5 minuty
    Case 10
    LicznikCzasu = 4*60*OkresoSekunda '4 minuty
    Case 11
    LicznikCzasu = 6*60*OkresoSekunda '6 minut
    Case 12
    LicznikCzasu = 8*60*OkresoSekunda '8 minut
    Case 13
    LicznikCzasu = 15*60*OkresoSekunda '15 minut
    Case 14
    LicznikCzasu = 20*60*OkresoSekunda '20 minut
    Case 15
    LicznikCzasu = 30*60*OkresoSekunda '30 minut
    End Select ' Wszystkie przypadki wymienione, wiec innych nie bedzie...
    Select Case NastawaTrybu
    '--------
    Case 1
    Set Portd.2
    Bitwait Pind.6 , Reset
    Set Portd.3
    Reset Portd.2
    Bitwait Pind.6 , Reset
    Set Portd.4
    Reset Portd.3
    Bitwait Pind.6 , Reset
    Set Portd.5
    Reset Portd.4
    '--------
    Case 2
    Set Portd.2
    Set Portd.3
    Bitwait Pind.6 , Reset
    Set Portd.4
    Set Portd.5
    Reset Portd.2
    Reset Portd.3
    Bitwait Pind.6 , Reset
    Reset Portd.2
    Reset Portd.3
    Reset Portd.4
    Reset Portd.5
    '--------
    Case 3
    Set Portd.2
    Set Portd.3
    Set Portd.4
    Set Portd.5
    Bitwait Pind.6 , Reset
    '--------
    Case Else
    $asm
    sbi PORTD, 5 ; wszystkie zarowki
    sbi PORTD, 4 ; sa zapalane na ustalony
    sbi PORTD, 3 ; czas...
    sbi PORTD, 2
    $asm end
    End Select
    Return
    '------------------
    PomiarCzasu:
    LOAD Timer1, T1Delay
    If LicznikCzasu != 0 Then
    Decr LicznikCzasu
    else
    $asm
    cbi PORTD, 5
    cbi PORTD, 4
    cbi PORTD, 3
    cbi PORTD, 2
    $asm end
    End If
    Return
    
    Prawda, że ładne ? ;)
    Uwaga : Ostatnia zmiana 3:23 27-03-2005 (po zmianie strefy czasowej... ;) )
    Pozdr, Light-I
  • #12 1352560
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Pozwolisz Light-I na małą korektę :?:
    ... dzięki :wink:
    
    
    Wlaczanie:
    Select Case NastawaCzasu
    ...
    End Select ' Wszystkie przypadki wymienione, wiec innych nie bedzie...
    ...
    

    zamieńmy na
    
    ...
    Tablica:
    Data 7% , 14% , 21% , 28% , 50% , 60% , 80% , 100%
    Data 120% , 150% , 240% , 360% , 480% , 900% , 1200% , 1800%
    Wlaczanie:
    Licznikczasu = Lookup(nastawaczasu , Tablica)
    Licznikczasu = Licznikczasu * Okresosekunda
    ...
    

    Prawda, że też ładne ? :wink:
    Oszczędzimy trochę flashu i klawiatury :)
    a)W kilku miejscach miast $end asm "pisnąłeś" $asm end".
    b)a=x*y*z w Bascomie nie przejdzie :(

    Pzdr.
    Piotrek

    PS
    Reset Portx.x Bascom "tłumaczy na" cbi PORTx.x(Set/sbi) więc nie ma potrzeby pisać w asm.
  • #13 1352997
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    No cóż, ja tk lubię asembler... ;)
    OkresoSekunda jest stałą, więc kompilator powinien policzyć, co trzeba ? Przynajmniej mój kompilator (Avrasm) nie ma z takimi sprawami problemu... :D. Oczywiście stablicowanie to jest myśl...
    W każdym bądź razie zastrzegam się, że jakiekolwiek rozważania na temat Bascoma przeprowadzam na podstawie Helpa, nic nie kompilując... ;)
    Pozdrawiam, Light-I
  • #14 1353006
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    Niestety, znowu was zmartwie... Program dziala jak uklad czasowy, ale ustawianie czasu nie ma sensu poniewaz i tak chyba Atmel sam losuje kiedy ma wylaczyc...
    Czas jaki otrzymalem przy tym samym ustawieniu zworek to: od 2sekund do 7sekund... O co moze chodzic tym razem???
    _xtal zmienilem na 8867, moze powinienem 8867000(w hertzach?)
  • #15 1353014
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    oczywiście że w Hz... By się przydała jakaś zmienna, która by przekazywała do procedury przerwania, kiedy ma liczyć(= 1), a kiedy nie(=0)
    Pozdr. Light-I
  • #16 1353024
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    ale czy to moglo miec az taki wplyw na to, ze ten uklad niemal losowal kiedy ma wylaczyc???
  • #17 1353155
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Szczerze powiedziawszy nie mam pojęcia, Bascom jest dla mnie zbyt skomplikowany wewnętrznie i trzeba by podejrzeć kod wynikowy w asm, aby coś stwierdzić, np. czy te wstawki asemblerowe nie kłócą się z resztą kodu. Asembler dla mnie ma proste i przejrzyste klocki, z którymi można zrobic prawie wszystko, a można jak najbardziej uzywać w nim zmiennych (danych w pamieci SRAM), we wszystkim pełna kontrola nad mikrokontrolerem. Najbardziej jestem w stanie pomóc, gdyby projekt realizowano w asemblerze AVRasm2 od AVRStudio v.4.11 od Atmela (freeware).
    P.S. Czy linia resetu w rzeczywistości wisi w powietrzu, czy też jest podciągnięta jakimś rezystorkiem (np. 10kΩ) do Vcc ?
    P.S.2 Tabela zumka nie zgadza się z wcześniejszymi założeniami programu (OkresoSekunda wynosi 2)
    P.S. 3 Znowu poprawiłem kod ;) :
    CONST T1_Prescale = 1024
    CONST T1_Okres = 500 ' ms
    CONST Podzial_ms = 1000 ' milisecond divisor
    CONST OkrSec = Podzial_ms / T1_Okres
    CONST T1Delay = (_XTAL/(OkrSec*T1_Prescale))	
    DIM NastawaCzasu As Byte, NastawaTrybu As Byte, LicznikCzasu As Word
    CONFIG Timer1 = Timer, Prescale = T1_Prescale
    CONFIG ACI = Off
    LOAD Timer1, T1Delay
    CONFIG PORTB = Input : PORTB = &B11111111 'wedle schematu
    CONFIG PORTD = &B0111100 : PORTD = &B1000011 'dipswitche to wejscia...
    ENABLE Timer1
    ENABLE Interrupts
    On Timer1 PomiarCzasu
    Do
    Debounce Pind.6, 0, Wlaczanie, Sub 'gdy zostanie przycisniety
    Loop
    End ' Ta instrukcja się nie wykona, jest tylko dla ozdoby ;-)
    '------------------
    Wlaczanie:
    $asm
    in r16, PINB
    com r16
    ldi r18, 8
    OdwracanieBit:
    clc
    ror r16
    rol r17
    dec r18
    brne OdwracanieBit
    mov r16, r17
    swap r17
    andi r16, 0x0F
    andi r17, 0x0F
    sts {NastawaTrybu}, r17
    rjmp UstawLicznikCzasu
    TablicaCzasu:
    .dw 7*OkrSec, 14*OkrSec, 21*OkrSec, 28*OkrSec, 50*OkrSec, 60*OkrSec, 80*OkrSec, 100*OkrSec
    .dw 120*OkrSec, 150*OkrSec, 240*OkrSec, 360*OkrSec, 480*OkrSec, 900*OkrSec, 1200*OkrSec, 1800*OkrSec
    UstawLicznikCzasu:
    ldi ZH, high(1<<TablicaCzasu)
    ldi ZL, low(1<<TablicaCzasu)
    lsl r16 ; Oczywiście tablica jest z elementów dwubajtowych - "word" i index mnożymy * 2 ;-)
    ldi r17, 0
    add ZL, r16
    adc ZH, r17
    lpm
    mov  r16, r0
    ld r0, Z+
    lpm
    mov  r17, r0
    cli
    sts {LicznikCzasu}, r16
    sts {LicznikCzasu+1}, r17
    sei
    $end asm
    Select Case NastawaTrybu
    '--------
    Case 1
    Set Portd.2
    Bitwait Pind.6, Reset
    Set Portd.3
    Reset Portd.2
    Bitwait Pind.6, Reset
    Set Portd.4
    Reset Portd.3
    Bitwait Pind.6, Reset
    Set Portd.5
    Reset Portd.4
    '--------
    Case 2
    Set Portd.2
    Set Portd.3
    Bitwait Pind.6, Reset
    Set Portd.4
    Set Portd.5
    Reset Portd.2
    Reset Portd.3
    Bitwait Pind.6, Reset
    Reset Portd.2
    Reset Portd.3
    Reset Portd.4
    Reset Portd.5
    '--------
    Case 3
    Set Portd.2
    Set Portd.3
    Set Portd.4
    Set Portd.5
    Bitwait Pind.6, Reset
    '--------
    Case Else
    $asm
    sbi PORTD, 5 ; wszystkie zarowki
    sbi PORTD, 4 ; sa zapalane na ustalony
    sbi PORTD, 3 ; czas...
    sbi PORTD, 2
    $end asm
    End Select
    Return
    '------------------
    PomiarCzasu:
    LOAD Timer1, T1Delay
    If LicznikCzasu <> 0 Then
    Decr LicznikCzasu
    else
    $asm
    cbi PORTD, 5
    cbi PORTD, 4
    cbi PORTD, 3
    cbi PORTD, 2
    $end asm
    End If
    Return
    

    Pozdrawiam, Light-I
  • #18 1353245
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    reset wisis w powietrzu, podobno w AVR nie trzeba do niego nic podlaczac...(POR tam jest...). Ten program i tak nadal szaleje, dziala za pierwszym razem tylko...
    Light, moze podjalbys sie napisania tego shitu od poczatku pod asm, tak zeby dzialal, oczywiscie za pieniadze...??? Jestem zdesperowany, za kilka dni potrzebuje to oddac bo to ma byc moja praca dyplomowa...

    Dodano po 1 [minuty]

    Poczekaj moment, wrzuce ten kod do bascoma i skomplikuje, tzn skompiluje...

    Dodano po 3 [minuty]:

    ldi XH, high(TablicaCzasu)
    ldi XL, low(TablicaCzasu)
    lsr r16 ' Oczywiście tablica jest z elementów dwubajtowych - "word" i index mnożymy * 2 ;-)
    ldi r17, 0
    add XL, r1


    w linii od lsr pokazuje blad: (or) missing... czyzby tam brakowalo or?
    poza tym gdzies bylo != zamiast =, to zmienilem...
  • #19 1353431
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    electro_Nick napisał:
    reset wisis w powietrzu, podobno w AVR nie trzeba do niego nic podlaczac...

    Zależy czy to mowa o ATtiny2313, czy AT90S2313...
    electro_Nick napisał:
    w linii od lsr pokazuje blad: (or) missing... czyzby tam brakowalo or?.

    Pomyliłem się, powinno być Tak jak jest w Nocie katalogowej, nie wiem jak Bascom, ale asm nie ma do takiego wyrażenia zastrzeżeń.
    electro_Nick napisał:
    poza tym gdzies bylo != zamiast =, to zmienilem...

    Powinno być wyrażenie, które by oznaczało, że wyrażenie jest różne od 0, chyba
    LicznikCzasu <> 0 Then
    a to "!=" wzięło mi się z asemblera i tam oznacza tak samo "różne od"... ;)
    Pozdr. Light-I
  • #20 1353799
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    chodzi o AT90S2313, jak na schemacie, mozliwe ze przez to ze dawalem tam = uklad nie dzialal tak jak powinien...
  • #21 1353941
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    
    $crystal = 8867000
    $regfile = "2313def.dat"
    Const T1_prescale = 1024
    Const T1_okres = 500
    Const Podzial_ms = 1000
    Const Okresosekunda = Podzial_ms / T1_okres
    Const T1delay = _xtal /(okresosekunda * T1_prescale)
    Const Timer1_wpisz = &HFFFF - T1delay
    Config Aci = Off
    Config Timer1 = Timer , Prescale = 1       'T1_prescale
    Config Portb = Input : Portb = &B11111111
    Config Portd = &B0111100 : Portd = &B1000011
    Dim Nastawaczasu As Byte , Nastawatrybu As Byte , Licznikczasu As Word
    Enable Interrupts
    On Timer1 Pomiarczasu
    
    Licznikczasu = 0       'dla spokojności ducha
    Do
       Debounce Pind.6 , 0 , Wlaczanie , Sub       'gdy zostanie przycisniety
       While Licznikczasu <> 0 : Wend
    Loop
    End       ' Ta instrukcja się nie wykona, jest tylko dla ozdoby ;-)
    '------------------
    Tablica:
    Data 7% , 14% , 21% , 28% , 50% , 60% , 80% , 100%
    Data 120% , 150% , 240% , 360% , 480% , 900% , 1200% , 1800%
    
    Wlaczanie:
    'dla uproszczenia kodu , odwrócone bity "nastwników"
    Nastawaczasu = Portb Xor &HFF
    Nastawatrybu = Nastawaczasu And &H0F
    
    Shift Nastawaczasu , Right , 4
    Licznikczasu = Lookup(nastawaczasu , Tablica)
    Licznikczasu = Licznikczasu * Okresosekunda
    Select Case Nastawatrybu
    '--------
    Case 1
       Set Portd.2
       Bitwait Pind.6 , Reset
       Set Portd.3
       Reset Portd.2
       Bitwait Pind.6 , Reset
       Set Portd.4
       Reset Portd.3
       Bitwait Pind.6 , Reset
       Set Portd.5
       Reset Portd.4
    '--------
    Case 2
       Set Portd.2
       Set Portd.3
       Bitwait Pind.6 , Reset
       Set Portd.4
       Set Portd.5
       Reset Portd.2
       Reset Portd.3
       Bitwait Pind.6 , Reset
       Reset Portd.2
       Reset Portd.3
       Reset Portd.4
       Reset Portd.5
    '--------
    Case 3
       Set Portd.2
       Set Portd.3
       Set Portd.4
       Set Portd.5
       Bitwait Pind.6 , Reset
    '--------
    Case Else
       Set Portd.5       ' Wszystkie Zarowki
       Set Portd.4       ' Sa Zapalane Na Ustalony
       Set Portd.3       ' Czas...
       Set Portd.2
    End Select
    Timer1 = Timer1_wpisz
    Reset Tifr.tov1
    Enable Timer1
    Return
    '------------------
    Pomiarczasu:
    
    Timer1 = Timer1_wpisz
    If Licznikczasu <> 0 Then
       Decr Licznikczasu
    Else
       Disable Timer1
       Reset Portd.5
       Reset Portd.4
       Reset Portd.3
       Reset Portd.2
    End If
    Return
    


    To powinno działać :wink:
    Nie rozumiem "fajerwerków" dla trybów 1-3 i UWAGA - funkcja Debounce wykorzystuje Timer1.

    Piotrek
  • REKLAMA
  • #22 1353971
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    Na razie moge tyle powiedziec, ze komipluje bez bledu...
  • #23 1353988
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Aj... zapomniałem przestawić Prescale na 1024 i w kodzie jest na 1 , bo testowałem w AVRStudio :(

    Piotrek
  • #25 1355169
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    W tym programie jest wszystko OK, ale w ukladzie to dziala tak ze obojetnie jaki czas ustawie to wylacza sie po 7.74s Co moze byc tego przyczyna?
  • #27 1355300
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    Nie wiem czy dobrze kombinuje ale pinb to chyba pojedynczy pin a nie caly port... Musze to sprawdzic w ukladzie...
  • #28 1355329
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Nie.
    Pinb to wszystkie bity i/o o adresie 0x16 , a portb to 0x18.
    I nie ma różnicy czy Potrb,Pinb,Ddrb zawsze możemy odczytać cały rejestr lub pojedynczy bit .

    Piotrek
  • #29 1355373
    electro_Nick
    Poziom 33  
    Posty: 1721
    Pomógł: 218
    Ocena: 203
    Uklad (niestety) dziala tak jak przedtem, wedle mojego symulatora z bascoma nie sa zmieniane zmienne nastawatrybu i nastawa czasu...
  • #30 1355441
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Drogi kolego electro_Nick.
    Zapuściłem symulator z Bascoma i ... działa, AVRStudio i ... działa.
    a)ustaw pułapkę na "Nastawaczasu = Pinb Xor &HFF"
    b)po zatrzymaniu programu na w/w lini wpisz do PINB FF(nie PORTB)
    c)wykonaj kilka kroków i zatrzymaj sie na "Case 1"
    d)zmienna "licznikczasu" bedzie wynosić 14
    e)zresetuj symulator
    f)uruchom ponownie
    g)po zatrzymaniu na pułapce i nie zmieniając PINB
    h)wykonaj kilka kroków i zatrzymaj sie na "Case 1"
    i)zmienna "licznikczasu" bedzie wynosić 3600

    I mówisz , że nie działa :?:

    Piotrek

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy problemu z programem w Bascom AVR dla automatu schodowego opartego na mikrokontrolerze ATtiny2313 (w rzeczywistości AT90S2313), gdzie ustawienia czasu wyłączania światła nie działają poprawnie – niezależnie od ustawień zworki, światło wyłącza się po stałym czasie około 7,7 sekundy. Użytkownik implementuje różne tryby pracy i sterowanie czasem za pomocą przełączników BCD podłączonych do portów mikrokontrolera. Wskazano błędy w konfiguracji portów i timerów, m.in. nieprawidłowe ustawienie rejestrów DDR i PORT, brak odpowiedniego odczytu stanu pinów (należy czytać PINB zamiast PORTB), oraz nieodpowiednie wartości stałych związanych z częstotliwością kwarcu (_XTAL) i preskalera timera. Zwrócono uwagę na konieczność poprawnego definiowania częstotliwości kwarcu w Hz (np. 8867000), właściwej konfiguracji preskalera (np. 1024), oraz na poprawne obliczanie wartości opóźnień i liczników czasu w oparciu o przerwania timera. Zaproponowano uproszczenie kodu przez stosowanie tablic do mapowania ustawień BCD na wartości czasowe oraz eliminację zbędnych zmiennych. Wskazano, że reset mikrokontrolera powinien być podciągnięty rezystorem do Vcc, a nie wisieć w powietrzu. Ostatecznie autor udostępnił poprawiony, działający kod z zaimplementowanymi czterema trybami pracy, który rozwiązuje problem i może służyć jako przykład do pracy dyplomowej. Dyskusja zawiera także sugestie dotyczące optymalizacji kodu i wykorzystania asemblera dla lepszej kontroli nad mikrokontrolerem.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA