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 Timer1 ATmega8 - Dioda miga zbyt szybko po załadowaniu wartości 1000

luknogal 11 Wrz 2004 13:10 3123 21
REKLAMA
  • #1 846419
    luknogal
    Poziom 12  
    Posty: 88
    Ocena: 3
    mam już od dłuższego czasu problem
    mianowicie generator częstotliwości
    dzisiaj bardzo się zdziwiłem
    gdy nie ładuje do timera wartosci początkowej
    wszystko jest ok, dioda sobie miga
    co ok 2 sek i jest spoko

    gdy natomiast załaduje do timera1 16Bit
    np 1000 co w zauważalny sposób nie powinno
    zmienić częstotliwości migania diody
    ona zaczyna migać jak oszalała

    z tego co zauważyłem pierwszy cykl mojego
    licznika jest ok
    dopiero po pierwszym d.2=1 zaczyna działać
    jak oszalały

    pomocy

    używam bascom,atmega8, oscylator 8MHz połączony przez
    C 16pF FS ustawione jako 1111:1111 external Xtal

    program (tylko sie nie śmiejcie :) )


    $regfile = "m8def.DAT"
    $crystal = 8000000
    Dim Licznik As Integer
    Dim I As Integer
    Dim C As Integer
    Dim P As Integer
    Config Pind.2 = Output
    Config Timer1 = Timer , Prescale = 64
    Enable Interrupts
    Enable Timer1
    On Timer1 Co1us
    Portd.2 = 1
    Portd.5 = 1
    Portd.6 = 1
    Portd.7 = 1
    Portb.0 = 1
    Cls
    Cursor Off Noblink
    I = 3
    P = 2

    Do

    If Pind.5 = 0 Then
    Incr P
    Cls
    End If

    If Pind.6 = 0 Then
    Decr P
    Cls
    End If

    If Pind.7 = 0 Then
    Incr I
    Cls
    End If

    If Pinb.0 = 0 Then
    Decr I
    Cls
    End If

    C = P + I

    Home
    Lcd "P=" ; P ; "us"
    Lowerline
    Lcd "I=" ; I ; "us " ; Licznik

    If Licznik = P Then
    Portd.2 = 0
    End If

    If Licznik >= C Then
    Portd.2 = 1
    Licznik = 0
    End If

    Loop
    End

    Co1us:
    Load Timer1 , 1000 :cry:
    Incr Licznik
    Return
  • REKLAMA
  • #2 846604
    luknogal
    Poziom 12  
    Posty: 88
    Ocena: 3
    sprawdzałem wszystko
    chyba poprostu robie jakiś głupi błąd
    czegoś nie przewidziałem
    np przy tak zmodyfikowanym programie
    diodka miga sobie 2 razy potem chwila przerwy
    potem 5 razy znowu chwila przerwy
    i tak w kółko

    normalnie jak dla mnie jakoś dziko

    takich problemów nie ma jak do timera
    wprowadze mniejszcze wartości
    dłuższe czasy, wtedy jest ok

    pomóżcie bo normalnie chyba się
    zastrzele



    $regfile = "m8def.DAT"
    $crystal = 8000000
    Dim Licznik As Word
    Dim I As Word
    Dim C As Word
    Dim P As Word
    Dim Pu As Integer
    Dim Iu As Integer
    Config Pind.2 = Output
    Config Timer1 = Timer , Prescale = 8
    Enable Interrupts
    Enable Timer1
    Start Timer1
    On Timer1 Co1us
    Portd.2 = 1
    Portd.5 = 1
    Portd.6 = 1
    Portd.7 = 1
    Portb.0 = 1
    Cls
    Cursor Off Noblink
    I = 54
    P = 54

    Do

    If Pind.5 = 0 Then
    Incr P
    Cls
    End If

    If Pind.6 = 0 Then
    Decr P
    Cls
    End If

    If Pind.7 = 0 Then
    Incr I
    Cls
    End If

    If Pinb.0 = 0 Then
    Decr I
    Cls
    End If

    C = P + I
    'Pu = P * 32
    'Iu = I * 32
    Home
    Lcd "P=" ; P ; "us"
    Lowerline
    Lcd "I=" ; I ; "us " ; Licznik

    If Licznik = P Then
    Portd.2 = 0
    End If

    If Licznik >= C Then
    Portd.2 = 1
    Licznik = 0
    End If

    Loop
    End

    Co1us:
    Timer1 = 60000
    Incr Licznik : Return
  • REKLAMA
  • #3 846741
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    luknogal napisał:
    sprawdzałem wszystko
    ...
    Portd.2 = 1
    Portd.5 = 1
    Portd.6 = 1
    Portd.7 = 1
    Portb.0 = 1
    ...


    Witam.

    Na dobry początek podpowiem Ci że masz źle skonfigurowane piny do ,których (jak mi się wydaje) masz podłączone przyciski.
    Dla ułatwienia dodam że na tych pinach procek zawsze odczytuje "0" (w Twoim przypadku oczywiście)i dlatego Twój program tak dziwnie działa :?:

    Pozdrawiam.
    Piotrek Sz.
  • REKLAMA
  • #4 846801
    luknogal
    Poziom 12  
    Posty: 88
    Ocena: 3
    z tym się nie zgodzę
    ustawiam je na 1
    a drugim końcem są podłączone do masy
    jeśli go naciskam wtedy pin zwiera się do 0
    o procek widzi to jako zero dopiero wtedy

    dodawanie i odejmowanie wartości
    P I tymi przyciskami działa prawidłowo
    (no czasem potrafi dodać np 5 odrazu, ale to nie problem)

    więc na początek myślę że nie w tym tkwi problem
    no chyba że się mylę
  • #5 846876
    Dexter77
    Poziom 28  
    Posty: 889
    Pomógł: 134
    Ocena: 19
    AVR po resecie ustawia kierunek portow na wejscia wiec tylko ustawienie jedynek na porcie podciagnie je do plusa zasilania i bedzie mozna odczytywac, tu akurat nie ma bledu. Natomiast takie wyrazenie jest zle:
    Config Pind.2 = Output
    Pind to rejestr wejsciowy i nie mozna do niego wpisywac mozna tylko odczytywac. Domyslam sieze powinno tam byc
    Config Portd.2 = Output
    Pozdro
    Dexter
  • #6 846950
    midas78
    Poziom 19  
    Posty: 360
    Pomógł: 12
    Ocena: 12
    W Bascomie nóżki konfiguruje się przez
    Config Portx = input/output - dla całego portu
    Config Pinx.y = input/output - dla jednej linii
    Sugerowałbym zatrzymać licznik przed załadowaniem do niego wartości. W nocie można znalźć info, że mogą pojawić się przypadkowe wartości w rejestrach przy zapisie na pracującym liczniku.
  • #7 846977
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Dexter77 napisał:
    AVR po resecie ustawia kierunek portow na wejscia wiec tylko ustawienie jedynek na porcie podciagnie je do plusa zasilania i bedzie mozna odczytywac, tu akurat nie ma bledu. Natomiast takie wyrazenie jest zle:
    Config Pind.2 = Output
    Pind to rejestr wejsciowy i nie mozna do niego wpisywac mozna tylko odczytywac. Domyslam sieze powinno tam byc
    Config Portd.2 = Output
    Pozdro
    Dexter


    Hmmm...
    Akurat tak się nie da.Baskom zaprotestuje :)
    Proponuję taki teścik.

    Dim I As Byte
    Declare Sub Ala()

    Config Pind.7 = Input 'potem zmienić na Output
    Portd.7 = 1
    I = 0
    Cls

    Do
    If Pind.7 = 0 Then Gosub Ala
    LCD I
    Loop

    Sub Ala()
    Incr I
    End Sub

    Wdawać by się mogło że zmienna "I " powinna=0 jeśli nie podamy na pin "0", tak nie będzie niestety.Proszę sprawdzić.Natomiast jak ustawimy pind.7 na Output to będzie dobrze.Dlaczego tak jest hmmm...... :wink:

    Pzdr

    Piotrek Sz.
  • #8 847081
    luknogal
    Poziom 12  
    Posty: 88
    Ocena: 3
    to zatrzymanie timera przed załadowaniem wartości
    jakby pomogło (przynajmniej nie zachowuje się dziwnie)
    teraz miga w równych odstępach

    ale nadal nie działa tak jak potrzeba
    przy ustawieniach jak poniżej P,I = 20
    mignięcie diody jak i przerwa trwają po
    ok 1 sekunde
    (na razie testuje na diodzie bo oscyloskopu
    niestety nie posiadam )

    a chyba tak być nie powinno, z grubsza
    co wyliczyłem to powinno to być po 2ms

    sam już mie wiem co może być tego przyczyną
    może kwarc zły??
    mam 8MHz połączony prze 2xC 16pF FS 1111:1111 external XTAL

    może coś z tym

    mam jescze 16MHz moge podłaczyć, tylko nie wiem czy będzie
    chodził w opisie procka pisało że do 8Mhz chodzą nieoprogramwane
    a 16 MHz musi być oprogramowany
    nie wiem o co chodzi więc zastosowałem 8

    co jeszcze może być nie tak
    bo kurde potrzebny mi ten generator
    od dłuższego czasu próbuje zrobić i lipa

    musze osiągnąć czasy impulsów i przerwy ok 5us
    najmniejsze
    $regfile = "m8def.DAT"
    $crystal = 8000000
    Dim Licznik As Word
    Dim I As Word
    Dim C As Word
    Dim P As Word
    Dim Pu As Integer
    Dim Iu As Integer
    Config Pind.2 = Output
    Config Timer1 = Timer , Prescale = 8
    Enable Interrupts
    Enable Timer1
    Start Timer1
    On Timer1 Co1us
    Portd.2 = 1
    Portd.5 = 1
    Portd.6 = 1
    Portd.7 = 1
    Portb.0 = 1
    Cls
    Cursor Off Noblink
    I = 20
    P = 20

    Do

    If Pind.5 = 0 Then
    Incr P
    Cls
    End If

    If Pind.6 = 0 Then
    Decr P
    Cls
    End If

    If Pind.7 = 0 Then
    Incr I
    Cls
    End If

    If Pinb.0 = 0 Then
    Decr I
    Cls
    End If

    C = P + I
    Home
    Lcd "P=" ; P ; "us"
    Lowerline
    Lcd "I=" ; I ; "us " ; Licznik

    If Licznik = P Then
    Portd.2 = 0
    End If

    If Licznik >= C Then
    Portd.2 = 1
    Licznik = 0
    End If

    Loop
    End

    Co1us:
    Stop Timer1
    Load Timer1 , 65436
    Start Timer1
    Incr Licznik : Return
  • #9 847140
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    luknogal napisał:
    to zatrzymanie timera przed załadowaniem wartości
    jakby pomogło (przynajmniej nie zachowuje się dziwnie)
    teraz miga w równych odstępach
    ...

    Home
    Lcd "P=" ; P ; "us"
    Lowerline
    Lcd "I=" ; I ; "us " ; Licznik

    If Licznik = P Then
    Portd.2 = 0
    End If

    If Licznik >= C Then
    Portd.2 = 1
    Licznik = 0
    End If
    ...


    Dobra odczepiam się od portów :)
    I już mówię dlaczego jest jak jest :idea:
    Błąd tkwi w tym że zmieniasz stany pinow w pętli głównej :?
    A czy wiesz ile czasu zajmuje prockowi wyświetlacz LCD :?:
    MNÓSTWO :!:

    Pzdr.

    Piotrek Sz.
  • REKLAMA
  • #10 847147
    midas78
    Poziom 19  
    Posty: 360
    Pomógł: 12
    Ocena: 12
    OPIS FUNKCJI LOAD

    Action
    Load specified TIMER with a reload value.

    .
    .
    .

    It will do the calculation. (256-value)
    So LOAD TIMER0, 10 will load the TIMER0 with a value of 246 so that it will overflow after 10 ticks.

    TIMER1 is a 16 bit counter so it will be loaded with the value of 65536-value.

    Czyli u ciebie ładuje 65536 - 65436 = 100

    Przepełnienie właśnie po 65436 czyli po ~65ms
    65ms * (c+i) = ~2,6s Czyli przerwa i błysk po ok 1,3 sek

    Przy prawidłowym zaladowaniu będziesz miał przerwanie co 100us co po pomnożeniu przez C i I da 2ms / 2ms

    Podpisuję się również "obiema ręcami" pod tym co napisał Piotrek.
  • #11 847358
    luknogal
    Poziom 12  
    Posty: 88
    Ocena: 3
    no chyba sprawa się wyjaśniła
    ja myślałem odwrotnie
    ładuje to timera na początek 65436
    więc przepełni się po 100

    a z tego co napisaliście jest zupełnie odwrotnie
    a co do tego LCD to jeszcze zobacze czy to ma duży wpływ
    i może będę wyświetlał tylko po zmianie wartości

    dzięki
  • #12 847408
    luknogal
    Poziom 12  
    Posty: 88
    Ocena: 3
    sorry że tak męcze ale naprawde potrzebuje ten
    generator

    z tym load timer to racja zrobiłem według wskazówek
    zmianę stanów pind.2 przeniosłem do przerwania
    żeby działało pewniej

    ale...

    nadal coś jest do chrzanu
    program zmodyfikowany poniżej według wskazówek
    powinien dawać impulsy 0.5ms/0.5ms
    (do timera ładuje 8 czyli przepełni się po 8*0.125us
    czyli co ok 1us)
    P I ustawione po 500 więc mowinnooo wyć tak jak
    pisałem, natomiast działa tak że dioda pali się
    jakieś 4s następnie 4s jest zgaszona tak około

    i co teraz...

    $regfile = "m8def.DAT"
    $crystal = 8000000
    Dim Licznik As Word
    Dim I As Word
    Dim C As Word
    Dim P As Word
    Dim Pu As Integer
    Dim Iu As Integer
    Config Pind.2 = Output
    Config Timer1 = Timer , Prescale = 1
    Enable Interrupts
    Enable Timer1
    Start Timer1
    On Timer1 Co1us
    Portd.2 = 1
    Portd.5 = 1
    Portd.6 = 1
    Portd.7 = 1
    Portb.0 = 1
    Cls
    Cursor Off Noblink
    I = 500
    P = 500

    Do

    If Pind.5 = 0 Then
    Incr P
    Cls
    End If

    If Pind.6 = 0 Then
    Decr P
    Cls
    End If

    If Pind.7 = 0 Then
    Incr I
    Cls
    End If

    If Pinb.0 = 0 Then
    Decr I
    Cls
    End If

    C = P + I
    Home
    Lcd "P=" ; P ; "us"
    Lowerline
    Lcd "I=" ; I ; "us " ; Licznik

    Loop
    End

    Co1us:
    Stop Timer1
    Load Timer1 , 8
    Start Timer1
    Incr Licznik
    If Licznik = P Then
    Portd.2 = 0
    End If
    If Licznik >= C Then
    Portd.2 = 1
    Licznik = 0
    End If
    Return
  • #13 847411
    midas78
    Poziom 19  
    Posty: 360
    Pomógł: 12
    Ocena: 12
    Fnkcja LOAD robi przeliczenia za ciebie. Jeżeli użyjesz Timerx = y to będziesz musiał sam poodejmować.
    Najlepiej przenieś zmianę stanu portu do przerwania, a w pętli głównej daj tylko wyświetlanie i obsługę przycisków.
  • #14 847710
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Po instrukcji "Load Timer1 , 8" rejestry Timera1 zawierają wartość 248(0x00F8H) jak Ci w takim razie wyszło że przerwanie wywołasz co 8 :?:
    Trzeba zajrzeć do Help-a , a tam jest wyjaśniony ten "ewenement" :)
    Zeby do T1 załadować taką małą(<256) wartość należy:
    Dim wartosc as word
    wartosc=8
    load timer1, wartosc
    lub rejestry bezpośrednio do TCNT1L,TCNT1H :idea:

    Sorry ale mi się oczka kleją.

    Pzdr.

    Piotrek Sz.
  • #15 847764
    luknogal
    Poziom 12  
    Posty: 88
    Ocena: 3
    a tego to nie zauważyłem, że przy małych wartościach
    tak trzeba postępować
    dzięki spróbuje
    helpa czytam na bieżąco i jakoś tego nie zauważyłem
  • #16 847799
    luknogal
    Poziom 12  
    Posty: 88
    Ocena: 3
    już prawie ale...
    jeszcze coś jest nie tak, zrobiłem jak doradzaliście
    przypisałem 8 do zmiennej i za-load-owałem do timera
    (reszta programu taka sama jak poprzednio)

    na pierwszy rzut oka wszystko jest ok, diodka świeci
    zmieniając swoją jasność w zależności od P I
    Myśle sobie nareszczie mam generator (tylko teraz przyciski
    chałowo działają, chyba za dużo przerwań, ale to nie szkodzi)

    no ale dla ostatecznej pewności wyszperałem winscope
    patrze sobie ładny w miare przebieg, choć trochę poszarpany
    ale ok i...
    zmierzyłem czasy impulsów i przerw jak się okazało np przy
    p60 I20 czas impulsu wynosi ok 0.6ms czas przerwy jest ok 3
    razy dłuższy więc...

    albo znowu źle licze, albo czegoś nie doczytałem...
    bo nadal te czasy są nie tak

    teraz nie wiem czy to wina winscope czy generatora
    (dzwiękówka powinna chyba dać rade sb16 chyba 20kHz
    powinien spokojnie wyciągnąć)
    przy P100 I100 czas impulsu jak i przerwy trwają po
    ponad 2ms każdy)

    i teraz to już naprawdę nie wiem, bo wcześniej były głupie
    błedy, a teraz nadal lipa
    co dalej z tym począć ??? bo ja za mało się znam żeby coś wymyśleć
    acha przebiegi z winscope
    Załączniki:
    • Bascom Timer1 ATmega8 - Dioda miga zbyt szybko po załadowaniu wartości 1000 P100I100.jpg (69.25 KB) Musisz być zalogowany, aby pobrać ten załącznik.
    • Bascom Timer1 ATmega8 - Dioda miga zbyt szybko po załadowaniu wartości 1000 P60I20.jpg (75.84 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #17 847812
    midas78
    Poziom 19  
    Posty: 360
    Pomógł: 12
    Ocena: 12
    Fragment:

    Incr Licznik
    If Licznik = P Then
    Portd.2 = 0
    End If
    If Licznik >= C Then
    Portd.2 = 1
    Licznik = 0
    End If

    wykonuje się w najlepszym przypadku (bez wchodzenia do IFów) 6us. Z wejściem do drugiego IFa 7us. Krótko mówiąc procesor nie ma nawet czasu na wyjście z przerwania a już powinien obsłużyć następne.
    Czyli na tym kwarcu nie widać szans na tak szybką zmianę stanu portu.
    W Bascomie można pisać wstawki w assemblerze. Możesz napisać swoją wstawkę, która na pewno wykona się szybciej.
    Spróbuj dać większy kwarc, i/lub zredukować ilość wejść do przerwania do minimum (co minimalny wymagany czas).

    Jeżeli ustawiłbyś wywołanie przerwań co 5us miałbyś czas na wykonanie 40 instrukcji (w tym załadowanie licznika).
    Może wstanie ten procek na 10MHz, zawsze to 10 instrukcji więcej.

    DODATEK:
    Odpuść sobie LOAD i sam policz co masz załadować do licznika. Tracisz przez to 1,75us.
  • #18 848014
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Witam.
    Powiem krótko,tak wygląda Twoje przerwanie.

    ;o tym nawet nie wiesz,bo to generuje Bascom.
    PUSH    R0        
    PUSH    R1        
    PUSH    R2        
    PUSH    R3        
    PUSH    R4        
    PUSH    R5        
    PUSH    R7        
    PUSH    R8        
    PUSH    R9        
    PUSH    R10       
    PUSH    R11       
    PUSH    R16       
    PUSH    R17       
    PUSH    R18       
    PUSH    R19       
    PUSH    R20       
    PUSH    R21       
    PUSH    R22       
    PUSH    R23       
    PUSH    R24       
    PUSH    R25       
    PUSH    R26       
    PUSH    R27       
    PUSH    R28       
    PUSH    R29       
    PUSH    R30       
    PUSH    R31 
    
    ;od tąd Twój program       
    IN      R24,0x3F  
    PUSH    R24       
    IN      R24,0x2E  
    ANDI    R24,0xF8  
    OUT     0x2E,R24  
    LDI     R26,0x62  
    LDI     R27,0x00  
    LD      R16,X+    
    LD      R17,X     
    COM     R16       
    COM     R17       
    SUBI    R16,0xFF  
    SBCI    R17,0xFF  
    OUT     0x2C,R16  
    OUT     0x2D,R17  
    LDI     R24,0x01  
    OUT     0x2E,R24  
    LDI     R26,0x60  
    LDI     R27,0x00  
    RCALL   +0x003E   
    LDI     R26,0x68  
    LDI     R27,0x00  
    LD      R20,X+    
    LD      R21,X     
    LDI     R26,0x60  
    LDI     R27,0x00  
    LD      R16,X+    
    LD      R17,X     
    CP      R16,R20   
    CPC     R17,R21   
    BREQ    +0x01     
    RJMP    +0x0001   
    CBI     0x12,2    
    LDI     R26,0x66  
    LDI     R27,0x00  
    LD      R20,X+    
    LD      R21,X     
    LDI     R26,0x60  
    LDI     R27,0x00  
    LD      R16,X+    
    LD      R17,X     
    CP      R16,R20   
    CPC     R17,R21   
    BRCC    +0x01     
    RJMP    +0x0007   
    SBI     0x12,2    
    LDI     R24,0x00  
    LDI     R25,0x00  
    LDI     R26,0x60  
    LDI     R27,0x00  
    ST      X+,R24    
    ST      X,R25     
    POP     R24       
    OUT     0x3F,R24  
    
    ;a tu znowu Bascom
    POP     R31       
    POP     R30       
    POP     R29       
    POP     R28       
    POP     R27       
    POP     R26       
    POP     R25       
    POP     R24       
    POP     R23       
    POP     R22       
    POP     R21       
    POP     R20       
    POP     R19       
    POP     R18       
    POP     R17       
    POP     R16       
    POP     R11       
    POP     R10       
    POP     R9        
    POP     R8        
    POP     R7        
    POP     R5        
    POP     R4        
    POP     R3        
    POP     R2        
    POP     R1        
    POP     R0        
    RETI              


    I teraz policz sobie ,ile potrzeba czasu(cykli)na jego wykonanie :!:

    Zbyt wiele wymagasz od swojego procka i Bascoma.
    Skoro to ma być prosty generator to jedynie w assemblerze można popróbować obsłużyć przerwanie ,a i tak nie osiągniesz zadawalających Cię wyników :cry:

    Pzdr.
    Piotrek Sz.
  • #19 848088
    midas78
    Poziom 19  
    Posty: 360
    Pomógł: 12
    Ocena: 12
    Widzę, że coraz bardziej zbliżamy się do assemblera.
    W bascomie da się wyłączyć generowanie odkładania i pobierania ze stosu rejestrów w czasie ubsługi przerwania:
    On timer1 nazwa_suba NOSAVE

    Ale wtedy to asm w obsłudze przerwania obowiązkowy (bo kto odkryje, które rejestry zmienia Bascom). Ewentualnie można zdekompilować prog sprawdzić i potem dopisać.
  • #20 848134
    luknogal
    Poziom 12  
    Posty: 88
    Ocena: 3
    tak właśnie myślałem
    za długi czas obsługi przerwania
    tylko co ja z tym teraz poczne
    w assemblerze nic nie wstawie bo nie umiem nic sensownego stworzyć

    pisałem kiedyś troche ale to na zupełnie innym procku i wogóle na uczelni
    na takim gotowym zestawie,

    kwarca mógłbym włożyć 16 Mhz tylko nie wiem jak ustawić FuseBity
    i czy kondenstaory 16pF bedą ok??
    może to coś by zmieniło ??
  • #21 848156
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    midas78 napisał:
    Widzę, że coraz bardziej zbliżamy się do assemblera.
    W bascomie da się wyłączyć generowanie odkładania i pobierania ze stosu rejestrów w czasie ubsługi przerwania:
    On timer1 nazwa_suba NOSAVE

    Ale wtedy to asm w obsłudze przerwania obowiązkowy (bo kto odkryje, które rejestry zmienia Bascom). Ewentualnie można zdekompilować prog sprawdzić i potem dopisać.


    W programach w których chcemy zapanować nad czasem bez asm-a ani rusz.Wiadomo przecież że od momentu wystąpienia przerwania do rozpoczęcia jego obsługi może minąć nawet 5 cykli (CALL,RET).
    Przy korzystaniu z przerwań od timerów można to skorygować z dokładnością co do cyklu,bo przecież licznik ciągle się "kręci" :)
    No ale to już wyższy stopień wtajemniczenia :roll:

    Pzdr.
    Piotrek Sz.
  • #22 2339296
    solar1
    Poziom 15  
    Posty: 185
    Pomógł: 2
    Ocena: 11
    a jak przy pomocy assemblera wyslac np 40 bitow na pin np 0.8 ? bo wlasnie ja mam podobny problem staram sie zrobic generator stanow logicznych ... taki w ktorym moglbym sobie zmieniac co ma generowac procesorek w danym czasie ,ale jestem za slaby w programowaniu pomoze ktos ? ;/

Podsumowanie tematu

✨ Problem dotyczy nieprawidłowego działania migającej diody sterowanej przez Timer1 w mikrokontrolerze ATmega8 programowanym w Bascom. Po załadowaniu do 16-bitowego timera wartości 1000 dioda miga zbyt szybko i nieregularnie, mimo że oczekiwano stabilnej częstotliwości. Dyskusja ujawniła błędy w konfiguracji portów (np. użycie Pind zamiast Portd), nieprawidłowe ładowanie wartości do timera oraz wpływ długiego czasu obsługi przerwania, zwłaszcza z powodu operacji na wyświetlaczu LCD w pętli głównej. Zalecano zatrzymanie timera przed załadowaniem wartości, przeniesienie zmiany stanu portu do obsługi przerwania oraz poprawne użycie funkcji LOAD, która automatycznie przelicza wartość do załadowania (dla Timer1 16-bitowego: 65536 - wartość). Wskazano, że przy małych wartościach należy ładować timer przez zmienną typu Word, a nie bezpośrednio. Problemy z czasem impulsów wynikają z ograniczeń prędkości procesora i długości obsługi przerwania generowanego przez Bascom, który automatycznie zapisuje i przywraca wiele rejestrów, co wydłuża czas reakcji. Sugerowano użycie większego kwarcu (np. 16 MHz) z odpowiednią konfiguracją fusebitów, optymalizację kodu przerwania, a nawet pisanie krytycznych fragmentów w assemblerze lub wyłączanie automatycznego zapisu rejestrów (NOSAVE). Ostatecznie, aby uzyskać precyzyjne czasy impulsów rzędu mikrosekund, konieczne jest minimalizowanie czasu obsługi przerwań i poprawne zarządzanie timerem. Dyskusja zawierała także przykładowe fragmenty kodu i wskazówki dotyczące konfiguracji portów i timerów w Bascomie.
Wygenerowane przez model językowy.
REKLAMA