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

potrzebna wstawka assemblerowa dla przerwania ATmega16

mototest 16 Kwi 2009 15:28 3249 34
  • #1 6421337
    mototest
    Poziom 19  
    Witam kolegów

    Nie znam się na assemblerze
    bascom się nie wyrabia w czasie, czy mógłby ktoś napisać wstawkę assemblerową zamiast poniższego listingu ? ten listing jest w przerwaniu INT0 i zlicza impulsy od enkodera , niezbyt szybko działa, a ja potrzebuję bardzo szybkie działanie.

     If pind.3 = 1 Then
     decr poz
     if poz = 0 then poz = 5000
     else
     incr poz
    
     if poz > 5000 then poz = 1
     end if
    



    A może zna ktoś jakiś dobry kompilator oprócz bascoma, bo w FastAvr chodzi dobrze ale nie da sie go już kupić

    dzięki
    Bogdan
  • #2 6422273
    ZbeeGin
    Poziom 39  
    Pisałem na szybko, sprawdź czy wszsytkie warunki działają poprawnie.

    Testpin:
        PUSH      r30                                           ' zapamiętaj R30:R31
        PUSH      r31
        PUSH      r16                                           ' zapamiętaj _temp1
        PUSH      r26                                           ' zapamiętaj X
        PUSH      r27
    
        Loadadr Poz , X                                         ' adres zmiennej POZ do rej X  (funkcja BASCOMa)
    
        LD        r30, X+                                       ' załaduj zawartość zmiennej do pary R30:R31
        LD        r31, X
    
    'If pind.3 = 1 Then
        SBIS      PIND, 3                                       ' jak bit ustawiony to omiń skok
        JMP       _else
    
    ' Decr Poz
        SUBI      r30, 1                                        ' odejmij 1 od zawartości spod X
        SBCI      r31, 0
    
    ' If Poz = 0 Then Poz = 5000
    
        MOV       r16, r31                                      ' sprawdź czy w R30:R31 jest zero
        !OR       r16, r30
        BRNE      _store                                        ' nie, zatem zapisz aktualną i wyjdź
        LDI       r30, &H88                                     ' inaczej załaduj do pary R30:R31 5000
        LDI       r31, &H13
        JMP       _store                                        ' zapisz i wyjdź
    _else:
    'Else
    ' Incr Poz
        ADIW      r30, 1                                        ' jak bit był zero dodaj 1
    
    ' If Poz > 5000 Then Poz = 1
        CPI       r30, &H89                                     ' sprawdź czy w R30:R31 jest 5001
        LDI       r16, &H13
        CPC       r31, r16
        BRCS      _store                                        ' jest mniej więc zapisz aktualną i wyjdź
        LDI       r30, 1                                        ' inaczej załaduj do pary R30:R31 wartość 1
        LDI       r31, 0
    _store:
        ST        X, r31                                        ' finalnie zapisz zawartość R30:R31 pod adres w X
        ST        -X, r30
    
        POP       r27
        POP       r26
        POP       r16
        POP       r31
        POP       r30
    Return


    Jest kompletna, a w programie wstaw On INT0 TestPin NoSave by była wywoływana.

    EDIT:
    Niech cię nie zwiedzie zastosowanie specjalnie przeznaczonej do tego celu LOADADR. Musi tam być, bo jako jedyna może podać poprawny adres zmiennej w pamięci i załadować go do rejestru wskaźnikowego. Zamieni się ona w dwa rozkazy LDI z poprawnymi bajtami, zatem bez obaw.
  • #3 6424024
    mototest
    Poziom 19  
    dzieki za zainteresowanie
    procedura działa, ale tak samo jak w bascomie, czyli gubi impulsy jak tylko szybciej zakręcę to na obrocie mam 200 impulsów różnicy, gdzieś tutaj bascom bruździ, w fastavr chodzi znakomicie, kręciłem do kilkuset obrotów/min i nie gubi ani jednego...
    a w programie bascomowym mam tylko kilka linijek , wyświetlanie lcd i przerwanie

    B.
  • #4 6424191
    ZbeeGin
    Poziom 39  
    Procedura jest wyraźnie krótsza niż ta którą kompilator sobie wygenerował (około 3 razy, bo wyjątkowo tam naśmiecił).

    Trzeba by wrzucić do AVR Studio kod z pliku OBJ po kompilacji przez FastAVR. Wtedy można zanalizować jak to zrobił FastAVR.
  • #5 6424226
    mototest
    Poziom 19  
    załączam plik obj
    program w fastavr wygląda tak:
    
    $Device = M16                                               ' used device
    $Stack = 32                                                 ' stack depth
    $Clock = 16                                                 ' adjust for used crystal
    $Lcd = PORTA.4 , RS = PORTA.2 , EN = PORTA.3 , 16 , 2       '
    Declare Interrupt Int0()
    Enable Int0
    Int0 Falling
    Enable Interrupts
    Dim poz As Word
    Cls
    poz = 0
    Do                                                          ' place your code in next line
    Locate 1 , 1
    Lcd poz ; "  "
    Loop
    
    
    
    Interrupt Int0() , Save 2
    If PIND.3 = 1 Then
     Decr poz
     If poz = 0 Then poz = 5000
     Else
     Incr poz
    
     If poz > 5000 Then poz = 1
     End If
    End Interrupt
    
  • #6 6425983
    ZbeeGin
    Poziom 39  
    W sumie nie ma tu nic szczególnego w tym przerwaniu, poza nieco nieoptymalnym kodem (Mój był lepszy :D ):
    IntN1:
    	in	r2, SREG
    	push	zl
    	push	zh
    	push	r24
    	push	r25
    	sbis	PIND, 3
    	rjmp	L0003
    L0004:
    	lds	zl, poz
    	lds	zh, poz+1
    	sbiw	zl, 0x01
    	sts	poz, zl
    	sts	poz+1, zh
    	lds	r24, poz
    	lds	r25, poz+1
    	ldi	zl, byte1(0)
    	ldi	zh, byte2(0)
    	cp	r24, zl
    	cpc	r25, zh
    	breq	PC+0x02
    	rjmp	L0006
    L0007:
    	ldi	zl, byte1(5000)
    	ldi	zh, byte2(5000)
    	sts	poz, zl
    	sts	poz+1, zh
    L0006:
    	rjmp	L0002
    L0003:
    	lds	zl , poz
    	lds	zh , poz+1
    	adiw	zl , 1
    	sts	poz , zl
    	sts	poz+1 , zh
    	lds	r24, poz
    	lds	r25, poz+1
    	ldi	zl, byte1(5000)
    	ldi	zh, byte2(5000)
    	adiw	zl, 1
    	cp	r24, zl
    	cpc	r25, zh
    	brsh	PC+0x02
    	rjmp	L0002
    L0010:
    	ldi	zl,byte1(1)
    	ldi	zh,byte2(1)
    	sts	poz,zl
    	sts	poz+1,zh
    L0002:
    	pop	r25
    	pop	r24
    	pop	zh
    	pop	zl
    	out	SREG, r2
    	reti
    

    Wywoływany jest normalnie przez standardowy wektor przerwania.

    Jak w katalogu z FastAVR zachował się plik BasDoc1.asm to załącz go, będzie łatwiej zanalizować resztę.
  • #8 6431614
    ZbeeGin
    Poziom 39  
    Trochę "zamieszałem" w kodzie by czas pomiędzy zgłoszeniem przerwania a testem stanu końcówki był krótszy. To najprawdopodobniej jest ten szczegół, który psuje całą wstawkę. Sprawdź teraz.

    Testpin:
        IN   r16, SREG                                          ' zapamiętaj rejestr flag
        PUSH r16
        PUSH r30                                                ' zapamiętaj R30:R31
        PUSH r31
        PUSH r16                                                ' zapamiętaj _temp1
        SBIS PIND, 3                                            ' jak bit ustawiony to omiń skok
        JMP  _else
        LDS  r30, {poz}                                         ' załaduj zawartość zmiennej do pary R30:R31
        LDS  r31, {poz+1}
        SBIW r30, 1                                             ' odejmij 1
        MOV  r16, r31                                           ' sprawdź czy w R30:R31 jest zero
        !OR  r16, r30
        BRNE _store                                             ' nie, zatem zapisz aktualną i wyjdź
        LDI  r30, &H88                                          ' inaczej załaduj do pary R30:R31 5000
        LDI  r31, &H13
        JMP  _store                                             ' zapisz i wyjdź
    _else:
        LDS  r30, {poz}                                         ' załaduj zawartość zmiennej do pary R30:R31
        LDS  r31, {poz+1}
        ADIW r30, 1                                             ' jak bit był zero dodaj 1
        CPI  r30, &H89                                          ' sprawdź czy w R30:R31 jest 5001
        LDI  r16, &H13
        CPC  r31, r16
        BRCS _store                                             ' jest mniej więc zapisz aktualną i wyjdź
        LDI  r30, 1                                             ' inaczej załaduj do pary R30:R31 wartość 1
        LDI  r31, 0
    _store:
        STS  {poz+1}, r31                                       ' finalnie zapisz zawartość R30:R31 do Poz
        STS  {poz}, r30
        POP  r16                                                ' zdejmij ze stosu co użyliśmy
        POP  r31
        POP  r30
        POP  r16
        !OUT Sreg, r16                                          ' i odtwórz SREG
    Return


    Wywołanie tak jak ostatnio z klauzulą NoSave.
  • #9 6432388
    piotr5000
    Poziom 21  
    Chciałbym zacząć od początku.
    Przy kilkuset obrotach na min (np 900) częstotliwość impulsów = 15 Hz . Przerwania przychodzą co 66 msek.
    BŁęDU SZUKAć TRZEBA GDZIE INDZIEJ ( ale nie mam pomysłu gdzie)
  • #10 6432446
    crazy_phisic
    VIP Zasłużony dla elektroda
    piotr5000 napisał:
    Chciałbym zacząć od początku.
    Przy kilkuset obrotach na min (np 900) częstotliwość impulsów = 15 Hz . Przerwania przychodzą co 66 msek.
    BŁęDU SZUKAć TRZEBA GDZIE INDZIEJ ( ale nie mam pomysłu gdzie)


    To zamieść CAŁY listing programu.
  • #11 6432562
    ZbeeGin
    Poziom 39  
    piotr5000 napisał:
    Chciałbym zacząć od początku.
    Przy kilkuset obrotach na min (np 900) częstotliwość impulsów = 15 Hz . Przerwania przychodzą co 66 msek.
    BŁęDU SZUKAć TRZEBA GDZIE INDZIEJ ( ale nie mam pomysłu gdzie)

    1. Prosimy nie krzyczeć.
    2. Dostałeś to co chciałeś -> nie działa -> trudno.
    3. Są tylko trzy możliwości by reszta programu miała związek z przerwaniem.
    a) błędnie jego skonfigurowane przez CONFIG INT0 lub brak tej instrukcji - nic nie wiemy o tym,
    b) pomimo wyraźnego wskazania nie dopisałeś do ON INT0 klauzuli NOSAVE - też brak możliwości sprawdzenia,
    c) operacje na LCD wyłączają przerwania - odpada; chyba, że masz jakąś ultra dziwną wersję kompilatora.


    Ostatecznie napisz całość w języku C.
  • #12 6432834
    piotr5000
    Poziom 21  
    Koledzy AUTOREM pytanie jest MOTOTEST nie krzyczcie na mnie bo całego listingu w związku z tym nie mogę zamieścić
    { PIOTR5000 }
    Dla kolegi Mototest napisałem programik do sprawdzenie , ale musi zadeklarować prawidłowo piny LCD bo ja "wyrwałem" to ze swojego programu:

    $regfile = "m16def.dat"       ' used device
    $hwstack = 32       ' stack depth
    $crystal = 8000000
    
    
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Lcd = 16 * 2
    
    Dim Poz As Word
    
    On Int0 Test
    Enable Int0
    Config Int0 = Falling
    Enable Interrupts
    
    
    Cls
    Poz = 0
    Do        ' place your code in next line
    Locate 1 , 1
    Lcd Poz ; "  "
    Loop
    
    
    
    Test:
    If Pind.3 = 1 Then
     Decr Poz
     If Poz = 0 Then Poz = 5000
     Else
     Incr Poz
     If Poz > 5000 Then Poz = 1
     End If
    Return



    W symulacji bascoma działa

    Proszę umieszczać listingi programów w znacznikach "Code". [c_p]
  • #13 6433255
    ZbeeGin
    Poziom 39  
    Dlatego następnym razem należy jasno i wyraźnie opisać Swoje intencje.

    I już dwa błędy są w tym programie:
    1. Deklaracja częstotliwości: FastAVR = 16MHz, Bascom = 8MHz. Programowo zauważalna ale tu nieistotna. Sprzętowo zaś bardzo ważna, bo cykl przyjęcia przerwania będzie 2x krótszy.
    2. Konfiguracja przerwań po ich włączeniu. Nie ważne, że Enable Interrupts wpisałeś po Config INT0. Flaga już jest na maszcie i czeka by ją zauważyć.

    Czekam dalej na sprawdzenie wstawki przez kol. mototest.
  • #14 6435532
    mototest
    Poziom 19  
    zgłaszam się po weekendzie
    mój program po sugestiach kol. ZbeeGin wyglądał jak poniżej
    nie zdążyłam jeszcze wstawić poprawki którą zasugerował jako ostatnią

    
    $crystal = 16000000
    $regfile = "m16def.dat"
    Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.2
    Config Lcd = 16 * 4
    
    Dim Poz As Word 
    Config Int0 = falling
    
    On Int0 Get_x nosave
    enable int0
    enable interrupts
    
    config pind.2 = input
    config pind.3 = input
    
    poz = 1
    cls
    cursor off
    
    do
    
    home
    
    lcd poz ; "  "
                   waitms 100
    loop
    
    
    
    get_x:
    'If pind.3 = 1 Then
    ' decr poz
    ' if poz = 0 then poz = 5000
    ' else
    ' incr poz
    
    ' if poz > 5000 then poz = 1
    ' end if
    $asm
       PUSH      r30                                           ' zapamiętaj R30:R31
        PUSH      r31
        PUSH      r16                                           ' zapamiętaj _temp1
        PUSH      r26                                           ' zapamiętaj X
        PUSH      r27
    
        Loadadr Poz , X                                         ' adres zmiennej POZ do rej X  (funkcja BASCOMa)
    
        LD        r30, X+                                       ' załaduj zawartość zmiennej do pary R30:R31
        LD        r31, X
    
    'If pind.3 = 1 Then
        SBIS      PIND, 3                                       ' jak bit ustawiony to omiń skok
        JMP       _else
    
    ' Decr Poz
        SUBI      r30, 1                                        ' odejmij 1 od zawartości spod X
        SBCI      r31, 0
    
    ' If Poz = 0 Then Poz = 5000
    
        MOV       r16, r31                                      ' sprawdź czy w R30:R31 jest zero
        !OR       r16, r30
        BRNE      _store                                        ' nie, zatem zapisz aktualną i wyjdź
        LDI       r30, &H88                                     ' inaczej załaduj do pary R30:R31 5000
        LDI       r31, &H13
        JMP       _store                                        ' zapisz i wyjdź
    _else:
    'Else
    ' Incr Poz
        ADIW      r30, 1                                        ' jak bit był zero dodaj 1
    
    ' If Poz > 5000 Then Poz = 1
        CPI       r30, &H89                                     ' sprawdź czy w R30:R31 jest 5001
        LDI       r16, &H13
        CPC       r31, r16
        BRCS      _store                                        ' jest mniej więc zapisz aktualną i wyjdź
        LDI       r30, 1                                        ' inaczej załaduj do pary R30:R31 wartość 1
        LDI       r31, 0
    _store:
        ST        X, r31                                        ' finalnie zapisz zawartość R30:R31 pod adres w X
        ST        -X, r30
    
        POP       r27
        POP       r26
        POP       r16
        POP       r31
        POP       r30
        $end asm
    return
    


    Dodano po 7 [minuty]:


    jeszcze do koliegi piotr5000, to nie jest częstotliwość 15Hz bo tam jest 5000 impulsów na obrót a nie jeden impuls na obrót, więc czas jednego impulsu wychodzi kilka-kilkanaście mikrosekund... a nie w milisekundach

    Dodano po 25 [minuty]:

    włożyłem tą nową wstawkę ale jest bez zmian ,albo są tak małe że niezauważalne, myslę .że bascom jeszcze coś źle robi poza przerwaniem,
    bo nie ma różnic czy wstawię w przerwaniu instrukcje z bascoma czy asm

    Dodano po 8 [minuty]:

    próbowałem jeszcze w trzecim kompilatorze basica w "mikrobasic PRO" i tam też działa rewelacyjnie, tylko w tym bascomie świruje, problem w tym że bascoma mam komercyjnego ,a tamte demo i niewiele kodu się zmieści
  • #15 6437524
    piotr5000
    Poziom 21  
    Symulator bascoma podaje czas obsługi przerwania w granicach 20 mikrosek.
    Przy 1000 obr / min. następne wywołanie przerwania przychodzi przed zakończeniem obsługi poprzedniego .

    Czy jest możliwa zmiana enkodera (np 500 imp / obrót )
  • #16 6437750
    mototest
    Poziom 19  
    nie ,enkoder musi być taki, bo jest potrzebna duża dokładność położenia do 0.1 stopnia, sprzetowo nic nie da rady zmienić, jedynie coś wstawić z assemblera, ale ja się nie znam na assemblerze, ostatecznie kupię inny kompilator.
  • #17 6437891
    piotr5000
    Poziom 21  
    OK .
    Jeżeli chcesz uzyskać taką dokładność położenia , to wcześniej zwalniasz napęd i dochodzisz do położenia na małej prędkości . Są wersje enkoderów posiadające trzeci kanał dający 1 impuls / obr.
    Jeżeli na dużej prędkości będziesz liczył pełne obroty , a dokładne pozycjonowanie zrobisz na małej prędkości ( np 100 obr / min ==== 120 mikrosek. ) bascom powinien się wyrobić.
  • #18 6438330
    mototest
    Poziom 19  
    gdyby to było takie proste to nie pisałbym o tym na forum, ja potrzebuję czytać pozycje przy pełnej prędkości i to bezbłędnie bez żadnych przekłamań...
  • Pomocny post
    #19 6438827
    Dr_DEAD
    Poziom 28  
    mototest napisał:
    gdyby to było takie proste to nie pisałbym o tym na forum, ja potrzebuję czytać pozycje przy pełnej prędkości i to bezbłędnie bez żadnych przekłamań...

    Maksymalnie schrzaniłeś hardware, teraz to już Cię nic nie uratuje. Do zliczania trzeba było wykorzystać ten większy Timer, a do wykrywania zmiany kierunku przerwanie. Pięknie by to chodziło a procek by się przy tym nudził.
  • #20 6438880
    Dr.Vee
    VIP Zasłużony dla elektroda
    Żeby przyspieszyć przetwarzanie możesz utrzymywać 2 zmienne: pozycja i delta. W przerwaniu INT0 robisz:
                              
        push r_temp                 ; 2 
        in   r_temp, SREG           ; 1
        push r24                    ; 2
        push r25                    ; 2
        lds  r24, LOW(adr_delta)    ; 2
        lds  r25, HIGH(adr_delta)   ; 2
        sbis PIND, 3                ; 1/2
        sbiw r24, 2                 ; 2/0
        adiw r24, 1                 ; 2
        sts  r24, LOW(adr_delta)    ; 2
        sts  r25, HIGH(adr_delta)   ; 2
        pop  r25                    ; 2
        pop  r24                    ; 2
        out  SREG, r_temp           ; 1
        pop  r_temp                 ; 2
        reti                        ; 4
    

    Daje to 30/31 cykli na przerwanie + min. 7 cykli na skok do przerwania, czyli można przerwanie wykonać co 2.4uS = ponad 400k impulsów na sekundę. Gdyby zarezerwować 2 rejestry na zmienną delta, to czas wykonania skraca się o 16 cykli do 1.375uS = ponad 700k impulsów na sekundę.

    Gdy w programie potrzebujesz odczytać pozycję enkodera, to zatrzymujesz przerwania, odczytujesz+zerujesz delta, włączasz przerwania i aktualizujesz zm. pozycja.

    Żeby wykluczyć przepełnienie zmiennej delta możesz automatycznie odświeżyć wartość zm. pozycja co jakiś czas korzystając z przerwania od timera, np. max 200 obr/min po 5000 impulsów = odświeżanie co 180ms.

    Pozdrawiam,
    Dr.Vee
  • #21 6439300
    mototest
    Poziom 19  
    800 obrotów/min to max jakie będą używane w tym enkoderze, ale nie mogę zatrzymywać przerwania, bo impulsy muszą być liczone ciągle, wszystko resztę muszę wykonać pomiędzy przerwaniami.
    800 obrotów to daje impuls przerwania co 15us, a ja w pętli nic nie będę robił oprócz sprawdzania czy jest naciśnięty przycisk STOP, więc teoretycznie wszystko powinno się wyrabiać bez problemu, ale nie w bascomie jak widać. zrobię jeszcze test na oscyloskopie i przedstawię wyniki opóźnień

    Dodano po 1 [godziny] 48 [minuty]:

    wstawiłem w przerwanie zmianę pinu na jednym porcie na czas wykonywania przerwania a następnie zbadałem czasy wykonywania przerwania dla :

    1.Bascoma
    2.Bascoma z wstawką od kolegi ZbeeGin
    3.kompilator basica MIKRObasicPRO

    i wyniki są takie :

    czas od zgłoszenia przerwania do wykonania pierwszej czynności, czyli zmiany stanu portu

    1. bascom 4us
    2. wstawka asm 600ns
    3. mikrobasic 1.5us

    czas wykonania samego przerwania (czyli kolejna zmiana pinu na porcie na końcu przerwania)

    1. bascom 3,1us
    2. wstawka 2.4us
    3. mikrobasic 2.2us


    jak widać z testów bascom jest o wiele wolniejszy, asm jest szybki ale dalej jest jakiś powód złego zlicznia ,mimo że mikrobasic jest nieco wolniejszy to liczy znakomicie...
  • #22 6439908
    Dr.Vee
    VIP Zasłużony dla elektroda
    mototest napisał:
    800 obrotów/min to max jakie będą używane w tym enkoderze, ale nie mogę zatrzymywać przerwania, bo impulsy muszą być liczone ciągle, wszystko resztę muszę wykonać pomiędzy przerwaniami.

    Bzdura. Przerwania będziesz miał wyłączone na max kilka cykli. Po włączeniu przerwań jeśli w międzyczasie nadeszło zbocze wyzwalające to zostanie wykonana procedura zaległego przerwania. Jeśli w te kilka cykli nadejdą dwa zbocza, to nawet bez wyłączania przerwań się nie wyrobisz :)

    mototest napisał:
    800 obrotów to daje impuls przerwania co 15us, a ja w pętli nic nie będę robił oprócz sprawdzania czy jest naciśnięty przycisk STOP

    No to po co Ci przerwania? Możesz wszystko obsłużyć w ciasnej pętli.

    mototest napisał:
    jak widać z testów bascom jest o wiele wolniejszy, asm jest szybki ale dalej jest jakiś powód złego zlicznia ,mimo że mikrobasic jest nieco wolniejszy to liczy znakomicie...

    Jeśli testujesz swój ostatni program, to brakuje w nim zachowywania wartości rejestru SREG na początku przerwania.

    Pozdrawiam,
    Dr.Vee
  • #23 6440137
    mototest
    Poziom 19  
    nie jestem pewien czy w pętli dobrze odczytam enkoder, bo muszę wykrywać zbocze opadające ,a nie konkretny stan styków, poza tym w innych pętlach w programie też czytam enkoder łącznie z wyświetlaniem lcd ,ale już przy wolnych obrotach, chciałbym się głównie dowiedzieć co w bascomie przymula to liczenie, skoro jest tam niewiele linijek programu.
  • #24 6448785
    ZbeeGin
    Poziom 39  
    Dr.Vee napisał:
    Jeśli testujesz swój ostatni program, to brakuje w nim zachowywania wartości rejestru SREG na początku przerwania.

    Tam jest stara wstawka, a Ja w międzyczasie napisałem nową. Zatem kol. mototest raczej testuje tą gdzie SREG jest zapisywany.


    Jak widać po testach czas od zgłoszenia w Mojej wstawce jest dość krótki i nie ma on zbytnio znaczenia bo kod z microbasic ma ten czas dłuższy. Proponuję jeszcze wykonać dodatkowy test pracy wstawki z dodanym na jej początku poleceniem SEI tuż przed SBIS. Jeśli będzie liczył poprawnie, albo nie będzie zliczał wcale (wystąpi zapętlenie się przerwań) to czas trwania wstawki jest tutaj krytyczny.
    Przy czym dodatkowo proponuję powiększyć stos: $HWStack = 64

    Da się nieco poprzerabiać w Mojej wstawce by była krótsza czasowo eliminując podwójne ładownie przez LDS zawartości zmiennej Poz, kosztem opóźnienia wykonania warunku SBIS.
  • #25 6449349
    rpal
    Poziom 27  
    Mysle że kolego musisz zmienić podejście samego programu, impulsy najlepiej zliczacz za pomoca wewnetrznych liczników a masz i 8 i 16 bitowy. Więc zakresu z pewnością wystarczy.
  • #26 6449881
    ZbeeGin
    Poziom 39  
    rpal napisał:
    impulsy najlepiej zliczacz za pomoca wewnetrznych liczników a masz i 8 i 16 bitowy. Więc zakresu z pewnością wystarczy.

    Przy 8 bitach raczej nie wystarczy. Chyba, że masz patent na zapisanie w 8 bitach liczby 5000 poprzez rozwiązanie mieszane z przerwaniem z licznika.
  • #27 6453869
    rpal
    Poziom 27  
    ZbeeGin napisał:
    rpal napisał:
    impulsy najlepiej zliczacz za pomoca wewnetrznych liczników a masz i 8 i 16 bitowy. Więc zakresu z pewnością wystarczy.

    Przy 8 bitach raczej nie wystarczy. Chyba, że masz patent na zapisanie w 8 bitach liczby 5000 poprzez rozwiązanie mieszane z przerwaniem z licznika.
    Tam jest także licznik 16-bitowy. A co do patentu to jeśli zmniejszysz interwał czasu w którym następuje zliczanie i późniejsze zerowanie licznika to te 8 bitów także wystarczy bo będzie to swoiste dzielenie.
    Kiedyś robiłem szybkościomierz co to z impulsów od koła (ABS) brał sobie sygnał prędkości. Fakt że można było w czasie 1 sekundy zapełnić licznik 8 bitowy kilka razy ale ten sam proces zliczania mógł także nastąpić przez 0,25 s i przepełnienie już nie następowało. Przerwanie w tym przypadku było przerwaniem Timera który nic wiecej nie robił jak przepisywał zawartość licznika do zmiennej i go zerował. Proste i szybkie rozwiązanie. NIe wiem czy koledze na coś przydatne.
    Jeszcze jedno, jeśli ilość impulsów jest za duża w jednostce czasu to zawsze można wsadzić jakiś scalony dzielnik np 7593, lub 7493 podzieli przez 16 albo przez 10
  • #28 6454251
    ZbeeGin
    Poziom 39  
    rpal napisał:
    A co do patentu to jeśli zmniejszysz interwał czasu w którym następuje zliczanie i późniejsze zerowanie licznika to te 8 bitów także wystarczy bo będzie to swoiste dzielenie.

    Niestety koledze zależy - jak mniemam - by liczył impulsy 1:1, zatem dzielenie ich nie wchodzi w rachubę.
  • #29 6454979
    mototest
    Poziom 19  
    tak chodzi mi o 1:1 , z tą wstawką asm jest dobrze czasowo, ale jednak się nie wyrabia, coś innego musi być powodem, bo mikrobasic jest wolniejszy od asm a działa
  • #30 6456042
    rpal
    Poziom 27  
    Może kolega najpierw niech jednoznacznie się wypowie co ile czasu (przy najszybszych obrotoach) pojawiać się ma przerwanie. Tak mi się zdaje że zliczanie impulsów poprzez wyzwalanie ich zboczem (obojętnie jakim) może skutkować tym że po prostu precek się nie wyrobi. Dobrze jest policzyć czas wykonania poszczególnych operacji jeśli przerwania następują bardzo szybko. W dalszym ciągu się upieram że obrany przez autora sposób zliczania jest nieefektywny.
REKLAMA