Obsługa przerwania

Pytania, kody i porady dotyczące nie tylko Bascom.
ODPOWIEDZ
JanJJW
Posty: 25
Rejestracja: 17 sty 2018, 0:17

Obsługa przerwania

Post autor: JanJJW » 06 wrz 2021, 22:33

Po przerwaniu program nie wraca do pętli "do loop until". Pomija pętlę i wychodzi z niej. Testowy króciutki program działa ale to za mało.
  1. $regfile = "m8def.dat"
  2. $crystal = 8000000
  3. $hwstack = 64
  4. $swstack = 64
  5. $framesize = 64
  6. $eepromhex
  7. '$sim
  8. Dim Ka , Kb As Bit
  9. Dim X , Y , Z , L1 , L2 , L_t , N As Byte
  10. Dim Tab_u(50) , Tab_i(50) , Tab_t(50) As Word
  11. Dim Tab_l(3) As Byte
  12. Dim K_u , K_i , K_t As Word
  13. Dim S_u , S_t , S_i As Word
  14. Dim Wnt , T As Single
  15. '===============================================================================
  16. Declare Sub Cyfry(wartosc As Word , Byval Korr As Word , Byval Mult As Byte)
  17. '===============================================================================
  18. Config Portb = 255
  19. Portb = 255
  20. Config Portc = 44
  21. Portc = 108
  22. Config Portd = 252
  23. Portd = 255
  24. Config Timer2 = Pwm , Prescale = 256 , Compare Pwm = Clear Up
  25. Config Timer1 = Timer , Prescale = 8 , Clear Timer = 1 , Compare A = Disconnect , Compare B = Disconnect
  26. Config Adc = Single , Prescaler = Auto , Reference = Off
  27. '===============================================================================
  28. Pwm2 = 255 : Kb = 1 : Z = 1 : X = 1
  29. '===============================================================================
  30. Readeeprom K_u , 1
  31. Readeeprom K_i , 3
  32. Readeeprom K_t , 5
  33. Waitms 200
  34. Enable Interrupts
  35. Enable Compare1a
  36. Compare1a = 5000
  37. On Compare1a Pomiar
  38. Start Adc
  39. L1 = 7 : Z = 0
  40. Waitms 200
  41. '===============================================================================
  42. Do
  43.    If Pind.0 = 0 Then
  44.       Waitms 50
  45.       If Pind.0 = 0 Then
  46.          Waitms 50
  47.          If Pind.0 = 0 Then
  48.             Ka = 1
  49.             If Ka = 1 And Kb = 0 Then
  50.                Incr Z
  51.                If Z > 2 Then
  52.                   Z = 0
  53.                End If
  54.             End If
  55.             Kb = 1
  56.          End If
  57.       End If
  58.    Else
  59.       Ka = 0 : Kb = 0
  60.    End If
  61.    If T >= 60 Then
  62.       Do
  63.          Portb.0 = 0
  64.          Pwm2 = 0
  65.       Loop Until T <= 50
  66.       Portb.0 = 1
  67.    End If
  68. Loop
  69. End
  70. '===============================================================================
  71. Pomiar:
  72.    Incr X
  73.    If X > 50 Then
  74.       X = 1
  75.    End If
  76.    S_u = 0 : S_i = 0 : S_t = 0
  77.    Tab_u(x) = Getadc(0)
  78.    Tab_i(x) = Getadc(1)
  79.    Tab_t(x) = Getadc(4)
  80.    For Y = 1 To 50
  81.       S_u = S_u + Tab_u(y)
  82.       S_i = S_i + Tab_i(y)
  83.       S_t = S_t + Tab_t(y)
  84.    Next Y
  85.    T = S_t / K_t
  86.    Wnt = T * -18
  87.    Wnt = Wnt + 900
  88.    Select Case Wnt
  89.       Case Is > 180
  90.          Wnt = 255
  91.       Case Is < 0
  92.          Wnt = 0
  93.    End Select
  94.    Pwm2 = Round(wnt)
  95.    If Pinb.0 = 0 Then
  96.       Call Cyfry(s_t , K_t , 10)
  97.       Incr N
  98.       If N = 100 Then
  99.          Portd = Portd Or 223
  100.          Portd.2 = 0
  101.          Toggle Portd.5
  102.          N = 1
  103.       End If
  104.    Else
  105.       Select Case Z
  106.          Case 0
  107.             Call Cyfry(s_u , K_u , 10)
  108.             Portd = Portd Or 255
  109.             Portd = Portd And 123
  110.          Case 1
  111.             Call Cyfry(s_i , K_i , 100)
  112.             Portd = Portd Or 255
  113.             Portd = Portd And 183
  114.          Case 2
  115.             Call Cyfry(s_t , K_t , 10)
  116.             Portd = Portd Or 255
  117.             Portd = Portd And 219
  118.       End Select
  119.    End If
  120.    Incr L1
  121.    If L1 > 3 Then
  122.       L1 = 1
  123.    End If
  124.    L_t = L1 + 4
  125.    L2 = Lookup(tab_l(l1) , Kody)
  126.    Portb = Portb Or 224
  127.    Shiftout Portc.2 , Portc.3 , L2 , 0
  128.    Portb.l_t = 0
  129. Return
  130. '===============================================================================
  131. Sub Cyfry:
  132.    Local Tmp As Single , Cyfra , Temp As Word , N As Byte
  133.    Tmp = Wartosc / Korr
  134.    Tmp = Tmp * Mult
  135.    Cyfra = Round(tmp)
  136.    For N = 1 To 3
  137.       Temp = Cyfra Mod 10
  138.       Tab_l(n) = Temp
  139.       Cyfra = Cyfra / 10
  140.    Next N
  141. End Sub
  142. '===============================================================================
  143. Kody:
  144.    Data 160 , 249 , 196 , 200 , 153 , 138 , 130 , 248 , 128 , 136
  145. '===============================================================================
  146.    $eeprom
  147.    Data 0 , 3500% , 2000% , 500%
  148.    $data
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Obsługa przerwania

Post autor: niveasoft » 06 wrz 2021, 22:44

To jakoś dziwnie napisane. Na dole Sub Cyfry powinien mieć DOKŁADNIE to samo wpisane co u góry w deklaracji i nie może być dwukropka po słowach Sub Cyfra. Może Bascom to łyka i traktuje ten napis na dole jak Label a wtedy pomija pierwszy Return i przekształca go w Reti a dopiero na End Sub chce skończyć ;)

Zobacz o co mi chodzi:
  1.     $regfile = "m8def.dat"
  2.     $crystal = 8000000
  3.     $hwstack = 64
  4.     $swstack = 64
  5.     $framesize = 64
  6.     $eepromhex
  7.     '$sim
  8.     Dim Ka , Kb As Bit
  9.     Dim X , Y , Z , L1 , L2 , L_t , N As Byte
  10.     Dim Tab_u(50) , Tab_i(50) , Tab_t(50) As Word
  11.     Dim Tab_l(3) As Byte
  12.     Dim K_u , K_i , K_t As Word
  13.     Dim S_u , S_t , S_i As Word
  14.     Dim Wnt , T As Single
  15.     '===============================================================================
  16.     Declare Sub Cyfry(wartosc As Word , Byval Korr As Word , Byval Mult As Byte)
  17.     '===============================================================================
  18.     Config Portb = 255
  19.     Portb = 255
  20.     Config Portc = 44
  21.     Portc = 108
  22.     Config Portd = 252
  23.     Portd = 255
  24.     Config Timer2 = Pwm , Prescale = 256 , Compare Pwm = Clear Up
  25.     Config Timer1 = Timer , Prescale = 8 , Clear Timer = 1 , Compare A = Disconnect , Compare B = Disconnect
  26.     Config Adc = Single , Prescaler = Auto , Reference = Off
  27.     '===============================================================================
  28.     Pwm2 = 255 : Kb = 1 : Z = 1 : X = 1
  29.     '===============================================================================
  30.     Readeeprom K_u , 1
  31.     Readeeprom K_i , 3
  32.     Readeeprom K_t , 5
  33.     Waitms 200
  34.     Enable Interrupts
  35.     Enable Compare1a
  36.     Compare1a = 5000
  37.     On Compare1a Pomiar
  38.     Start Adc
  39.     L1 = 7 : Z = 0
  40.     Waitms 200
  41.     '===============================================================================
  42.     Do
  43.        If Pind.0 = 0 Then
  44.           Waitms 50
  45.           If Pind.0 = 0 Then
  46.              Waitms 50
  47.              If Pind.0 = 0 Then
  48.                 Ka = 1
  49.                 If Ka = 1 And Kb = 0 Then
  50.                    Incr Z
  51.                    If Z > 2 Then
  52.                       Z = 0
  53.                    End If
  54.                 End If
  55.                 Kb = 1
  56.              End If
  57.           End If
  58.        Else
  59.           Ka = 0 : Kb = 0
  60.        End If
  61.        If T >= 60 Then
  62.           Do
  63.              Portb.0 = 0
  64.              Pwm2 = 0
  65.           Loop Until T <= 50
  66.           Portb.0 = 1
  67.        End If
  68.     Loop
  69.     End
  70.     '===============================================================================
  71.     Pomiar:
  72.        Incr X
  73.        If X > 50 Then
  74.           X = 1
  75.        End If
  76.        S_u = 0 : S_i = 0 : S_t = 0
  77.        Tab_u(x) = Getadc(0)
  78.        Tab_i(x) = Getadc(1)
  79.        Tab_t(x) = Getadc(4)
  80.        For Y = 1 To 50
  81.           S_u = S_u + Tab_u(y)
  82.           S_i = S_i + Tab_i(y)
  83.           S_t = S_t + Tab_t(y)
  84.        Next Y
  85.        T = S_t / K_t
  86.        Wnt = T * -18
  87.        Wnt = Wnt + 900
  88.        Select Case Wnt
  89.           Case Is > 180
  90.              Wnt = 255
  91.           Case Is < 0
  92.              Wnt = 0
  93.        End Select
  94.        Pwm2 = Round(wnt)
  95.        If Pinb.0 = 0 Then
  96.           Call Cyfry(s_t , K_t , 10)
  97.           Incr N
  98.           If N = 100 Then
  99.              Portd = Portd Or 223
  100.              Portd.2 = 0
  101.              Toggle Portd.5
  102.              N = 1
  103.           End If
  104.        Else
  105.           Select Case Z
  106.              Case 0
  107.                 Call Cyfry(s_u , K_u , 10)
  108.                 Portd = Portd Or 255
  109.                 Portd = Portd And 123
  110.              Case 1
  111.                 Call Cyfry(s_i , K_i , 100)
  112.                 Portd = Portd Or 255
  113.                 Portd = Portd And 183
  114.              Case 2
  115.                 Call Cyfry(s_t , K_t , 10)
  116.                 Portd = Portd Or 255
  117.                 Portd = Portd And 219
  118.           End Select
  119.        End If
  120.        Incr L1
  121.        If L1 > 3 Then
  122.           L1 = 1
  123.        End If
  124.        L_t = L1 + 4
  125.        L2 = Lookup(tab_l(l1) , Kody)
  126.        Portb = Portb Or 224
  127.        Shiftout Portc.2 , Portc.3 , L2 , 0
  128.        Portb.l_t = 0
  129.     Return
  130.     '===============================================================================
  131.     Sub Cyfry(wartosc As Word , Byval Korr As Word , Byval Mult As Byte)
  132.        Local Tmp As Single , Cyfra , Temp As Word , N As Byte
  133.        Tmp = Wartosc / Korr
  134.        Tmp = Tmp * Mult
  135.        Cyfra = Round(tmp)
  136.        For N = 1 To 3
  137.           Temp = Cyfra Mod 10
  138.           Tab_l(n) = Temp
  139.           Cyfra = Cyfra / 10
  140.        Next N
  141.     End Sub
  142.     '===============================================================================
  143.     Kody:
  144.        Data 160 , 249 , 196 , 200 , 153 , 138 , 130 , 248 , 128 , 136
  145.     '===============================================================================
  146.        $eeprom
  147.        Data 0 , 3500% , 2000% , 500%
  148.        $data
Nie analizowałem do końca i może jeszcze chciałbyś użyć "Byval" przed zmienną Wartość przekazywana w Sub. Bez "byval" domyślnie jest Byref, no ale jak nie zmieniasz tej wartości to prawidłowo bo szybciej jest przekazać zmienną niż robić jej kopię.
Dodatkowo jeśli zmienna "T" typu Single jest używana w przerwaniu to powinno się użyć Saveall no chyba że się ma NoSave Tool :D
This will save all registers that SAVE will save, but it will also save R12-R15. You should use this option when using floating point math in the ISR.
JanJJW
Posty: 25
Rejestracja: 17 sty 2018, 0:17

Re: Obsługa przerwania

Post autor: JanJJW » 09 wrz 2021, 23:51

Dziękuję bardzo za uwagi. Już rozwiązałem problem.
ODPOWIEDZ