Gotowe kody obsługi układów elektronicznych udostępnione przez użytkowników forum.
niveasoft
Posty: 1239 Rejestracja: 17 sie 2015, 12:13
Kontakt:
Post
autor: niveasoft » 22 paź 2020, 18:10
Zapomniałem, że nie zamieściłem kodu do tego filmu.
Ten kod
nie myli się nigdy bo używając PCINT reaguje na każdą zmianę stanu pinów. Testowane od kilku lat czasem nawet z trzema enkoderami na raz po 10tyś impulsów na obrót każdy.
UWAGA. Pierwsze dwa kody są właśnie z tego filmu a tam jest użyty enkoder PUSH PULL który przy przejściu daje dwa plusy a nie tak jak te najtańsze zwierane do masy.
To oczywiście dla tych najtańszych tylko kwestia podłączenia, ale niżej zamieszczę kod w którym polaryzację wybiera się stałą Const Intermediate = 0 lub 1
VIDEO
$regfile = "m644pdef.dat"
$crystal = 11059200
$hwstack = 64
$swstack = 32
$framesize = 128
' Cheap encoder PCINT FULLSTEP (one step per click)
' 2017/01/02 by BARTek EDC
Config Submode = New
Config Lcdpin = Pin , Rs = Portc.7 , E = Portc.6 , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2
Config Lcd = 16x2
Cursor Off , Noblink
Cls
Dim Turn_l As Byte , Turn_r As Byte , Steps As Integer , Milis As Byte
Dim Enc_new As Byte , Steps_old As Integer , State As Byte
Config Portd.0 = Output : Led_a Alias Portd.0
Config Portd.1 = Output : Led_b Alias Portd.1
Config Portd.2 = Input : Encoder_a Alias Pind.2 : Set Portd.2
Config Portd.3 = Input : Encoder_b Alias Pind.3 : Set Portd.3
Config Timer2 = Timer , Prescale = 1024 , Compare_a = Disconnect , Clear_timer = 1
Compare2a = 215 '20ms @11MHz/1024
Pcmsk3 = &B 00001100
Enable Pcint3 : On Pcint3 Encoder_isr Nosave
Locate 1 , 6 : : Lcd "Full step"
Sub Show_steps( )
Locate 2 , 9 : If Steps > 0 Then Lcd "+" : Lcd Steps ; " "
End Sub
Call Show_steps( )
Enable Interrupts
Do
If Turn_l > 0 Then
Decr Turn_l
Incr Steps
End If
If Turn_r > 0 Then
Decr Turn_r
Decr Steps
End If
If Tifr2 .ocf2a = 1 Then
Tifr2 .ocf2a = 1
Incr Milis
If Milis > 4 Then '5x20ms
Milis = 0
If Steps_old <> Steps Then
Call Show_steps( )
Steps_old = Steps
End If
End If
End If
Led_a = Encoder_a
Led_b = Encoder_b
Loop
End
Encoder_isr:
$asm
!PUSH R16
!PUSH R24
!PUSH R26
!PUSH R27
!in R24 , sreg
!PUSH R24
$end Asm
Enc_new.0 = Encoder_a
Enc_new.1 = Encoder_b
Select Case Enc_new
Case 1
Select Case State
Case 0 : State = 1 'pocz L krok 1
Case 3 : State = 1 'revers z 2xHI
Case 4 : State = 5 'progress w prawo krok 3 (bo opadaja naprzemian)
End Select
Case 2
Select Case State
Case 0 : State = 2 'pocz R krok 1
Case 4 : State = 2 'revers z 2xHI
Case 3 : State = 6 'progress w lewo krok 3 (bo opadaja naprzemian)
End Select
Case 0 '2xHI
Select Case State
Case 1 : State = 3 'byl pocz L krok 1 ->L krok 2 S3
Case 2 : State = 4 'byl pocz R krok 1 ->R krok 2 S4
Case 5 : State = 4 'revers
Case 6 : State = 3 'revers
End Select
Case 3
Select Case State
Case 5 : Incr Turn_l
Case 6 : Incr Turn_r
End Select
State = 0
End Select
' Tuned with NoSave Tool
$asm
!POP R24
!out sreg , r24
!POP R27
!POP R26
!POP R24
!POP R16
$end Asm
Return
$regfile = "m644pdef.dat"
$crystal = 11059200
$hwstack = 64
$swstack = 32
$framesize = 128
' Cheap encoder PCINT 4xSTEP (four step per click)
' 2017/01/02 by BARTek EDC
Config Submode = New
Config Lcdpin = Pin , Rs = Portc.7 , E = Portc.6 , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2
Config Lcd = 16x2
Cursor Off , Noblink
Cls
Dim Turn_l As Byte , Turn_r As Byte , Steps As Integer , Milis As Byte
Dim Enc_new As Byte , Steps_old As Integer , State As Byte
Config Portd.0 = Output : Led_a Alias Portd.0
Config Portd.1 = Output : Led_b Alias Portd.1
Config Portd.2 = Input : Encoder_a Alias Pind.2 : Set Portd.2
Config Portd.3 = Input : Encoder_b Alias Pind.3 : Set Portd.3
Config Timer2 = Timer , Prescale = 1024 , Compare_a = Disconnect , Clear_timer = 1
Compare2a = 215 '20ms @11MHz/1024
Pcmsk3 = &B 00001100
Enable Pcint3 : On Pcint3 Encoder_isr Nosave
Sub Show_steps( )
Locate 2 , 9 : If Steps > 0 Then Lcd "+" : Lcd Steps ; " "
End Sub
Locate 1 , 5 : : Lcd "Every step"
Call Show_steps( )
Enable Interrupts
Do
If Turn_l > 0 Then
Decr Turn_l
Incr Steps
End If
If Turn_r > 0 Then
Decr Turn_r
Decr Steps
End If
If Tifr2 .ocf2a = 1 Then
Tifr2 .ocf2a = 1
Incr Milis
If Milis > 4 Then '5x20ms
Milis = 0
If Steps_old <> Steps Then
Call Show_steps( )
Steps_old = Steps
End If
End If
End If
Led_a = Encoder_a
Led_b = Encoder_b
Loop
End
Encoder_isr:
$asm
!PUSH R16
!PUSH R24
!PUSH R26
!PUSH R27
!PUSH R30
!PUSH R31
!in R24 , sreg
!PUSH R24
$end Asm
Enc_new.0 = Encoder_a
Enc_new.1 = Encoder_b
Select Case Enc_new
Case 1
Select Case State
Case 0 : State = 1 : Decr Steps 'pocz L krok 1
Case 3 : State = 1 : Incr Steps 'revers z 2xHI
Case 4 : State = 5 : Incr Steps 'progress w prawo krok 3 (bo opadaja naprzemian)
End Select
Case 2
Select Case State
Case 0 : State = 2 : Incr Steps 'pocz R krok 1
Case 4 : State = 2 : Decr Steps 'revers z 2xHI
Case 3 : State = 6 : Decr Steps 'progress w lewo krok 3 (bo opadaja naprzemian)
End Select
Case 0 '2xHI
Select Case State
Case 1 : State = 3 : Decr Steps 'byl pocz L krok 1 ->L krok 2 S3
Case 2 : State = 4 : Incr Steps 'byl pocz R krok 1 ->R krok 2 S4
Case 5 : State = 4 : Decr Steps 'revers
Case 6 : State = 3 : Incr Steps 'revers
End Select
Case 3
Select Case State
Case 1 : State = 0 : Incr Steps
Case 2 : State = 0 : Decr Steps
Case 5 : Incr Steps
Case 6 : Decr Steps
End Select
State = 0
End Select
' Tuned with NoSave Tool
$asm
!POP R24
!out sreg , r24
!POP R31
!POP R30
!POP R27
!POP R26
!POP R24
!POP R16
$end Asm
Return
niveasoft
Posty: 1239 Rejestracja: 17 sie 2015, 12:13
Kontakt:
Post
autor: niveasoft » 22 paź 2020, 18:13
Wersja na trzy enkodery (kod wycięty z jakiegoś projektu).
Jeśli ma być zastosowany enkoder zwierany do masy należy zmienić stałą
Const Intermediate = 0
$regfile = "m644pdef.dat" '64K FLASH, 4K SRAM, 2K EEPROM, 2xUSART
$crystal = 16000000
$hwstack = 128
$swstack = 64
$framesize = 128
$baud1 = 115200
Open "COM2:" For Binary As # 2
Debug Off
Config Submode = New
Const Intermediate = 1 'przy przejściu obydwa plus=1 obydwa minus=0
'*********************************************************
'* *
'*********************************************************
Dim Enc_new As Byte
Dim Steps( 3 ) As Long , Old_steps( 3 ) As Long , Sign( 3 ) As Long
'-----------------------------------[ENC X]---------------
Dim State1 As Byte
Config Portb.0 = Input : Encoder1_a Alias Pinb.0 : Set Portb.0 'PCINT8
Config Portb.1 = Input : Encoder1_b Alias Pinb.1 : Set Portb.1 'PCINT9
Pcmsk1 = &B 0000_0011
Enable Pcint1 : On Pcint1 Encoder1_isr Nosave
'-----------------------------------[ENC Y]---------------
Dim State2 As Byte
Config Portc.0 = Input : Encoder2_a Alias Pinc.0 : Set Portc.0 'PCINT16
Config Portc.1 = Input : Encoder2_b Alias Pinc.1 : Set Portc.1 'PCINT17
Pcmsk2 = &B 0000_0011
Enable Pcint2 : On Pcint2 Encoder2_isr Nosave
'-----------------------------------[ENC Z]---------------
Dim State3 As Byte
Config Portd.0 = Input : Encoder3_a Alias Pind.0 : Set Portd.0 'PCINT24
Config Portd.1 = Input : Encoder3_b Alias Pind.1 : Set Portd.1 'PCINT25
Pcmsk3 = &B 0000_0011
Enable Pcint3 : On Pcint3 Encoder3_isr Nosave
Enable Interrupts
Do
If Old_steps( 1 ) <> Steps( 1 ) Then
Old_steps( 1 ) = Steps( 1 )
End If
If Old_steps( 2 ) <> Steps( 2 ) Then
Old_steps( 2 ) = Steps( 2 )
End If
If Old_steps( 3 ) <> Steps( 3 ) Then
Old_steps( 3 ) = Steps( 3 )
End If
Loop
End
Encoder1_isr:
$asm
!PUSH R16
!PUSH R17
!PUSH R18
!PUSH R19
!PUSH R20
!PUSH R24
!PUSH R26
!PUSH R27
!IN R24 , SREG
!PUSH R24
$end Asm
Enc_new = Pinb And &B 0000_0011
Select Case Enc_new
Case 1
Select Case State1
Case 0 : State1 = 1
Case 3 : State1 = 1
Case 4 : State1 = 5
End Select
Case 2
Select Case State1
Case 0 : State1 = 2
Case 4 : State1 = 2
Case 3 : State1 = 6
End Select
#if Intermediate = 1
Case 3
#else
Case 0
#endif
Select Case State1
Case 1 : State1 = 3
Case 2 : State1 = 4
Case 5 : State1 = 4
Case 6 : State1 = 3
End Select
#if Intermediate = 1
Case 0
#else
Case 3
#endif
Select Case State1
Case 5 : Incr Steps( 1 ) ': Set L_led : Reset R_led
Case 6 : Decr Steps( 1 ) ': Set R_led : Reset L_led
End Select
State1 = 0
End Select
'# PUT YOUR ISR ROUTINES HERE #
' Tuned with NoSave Tool 1.10
$asm
!POP R24
!OUT SREG , R24
!POP R27
!POP R26
!POP R24
!POP R20
!POP R19
!POP R18
!POP R17
!POP R16
$end Asm
Return
Encoder2_isr:
$asm
!PUSH R16
!PUSH R17
!PUSH R18
!PUSH R19
!PUSH R20
!PUSH R24
!PUSH R26
!PUSH R27
!IN R24 , SREG
!PUSH R24
$end Asm
Enc_new = Pinc And &B 0000_0011
Select Case Enc_new
Case 1
Select Case State2
Case 0 : State2 = 1
Case 3 : State2 = 1
Case 4 : State2 = 5
End Select
Case 2
Select Case State2
Case 0 : State2 = 2
Case 4 : State2 = 2
Case 3 : State2 = 6
End Select
#if Intermediate = 1
Case 3
#else
Case 0
#endif
Select Case State2
Case 1 : State2 = 3
Case 2 : State2 = 4
Case 5 : State2 = 4
Case 6 : State2 = 3
End Select
#if Intermediate = 1
Case 0
#else
Case 3
#endif
Select Case State2
Case 5 : Incr Steps( 3 ) ': Set L_led : Reset R_led
Case 6 : Decr Steps( 3 ) ': Set R_led : Reset L_led
End Select
State2 = 0
End Select
'# PUT YOUR ISR ROUTINES HERE #
' Tuned with NoSave Tool 1.10
$asm
!POP R24
!OUT SREG , R24
!POP R27
!POP R26
!POP R24
!POP R20
!POP R19
!POP R18
!POP R17
!POP R16
$end Asm
Return
Encoder3_isr:
$asm
!PUSH R16
!PUSH R17
!PUSH R18
!PUSH R19
!PUSH R20
!PUSH R24
!PUSH R26
!PUSH R27
!IN R24 , SREG
!PUSH R24
$end Asm
Enc_new = Pind And &B 0000_0011
Select Case Enc_new
Case 1
Select Case State3
Case 0 : State3 = 1
Case 3 : State3 = 1
Case 4 : State3 = 5
End Select
Case 2
Select Case State3
Case 0 : State3 = 2
Case 4 : State3 = 2
Case 3 : State3 = 6
End Select
#if Intermediate = 1
Case 3
#else
Case 0
#endif
Select Case State3
Case 1 : State3 = 3
Case 2 : State3 = 4
Case 5 : State3 = 4
Case 6 : State3 = 3
End Select
#if Intermediate = 1
Case 0
#else
Case 3
#endif
Select Case State3
Case 5 : Incr Steps( 2 ) ': Set L_led : Reset R_led
Case 6 : Decr Steps( 2 ) ': Set R_led : Reset L_led
End Select
State3 = 0
End Select
'# PUT YOUR ISR ROUTINES HERE #
' Tuned with NoSave Tool 1.10
$asm
!POP R24
!OUT SREG , R24
!POP R27
!POP R26
!POP R24
!POP R20
!POP R19
!POP R18
!POP R17
!POP R16
$end Asm
Return
Henryk
Posty: 348 Rejestracja: 22 sty 2018, 17:20
Post
autor: Henryk » 23 paź 2020, 10:17
Witam
Ciekawość nie dała mi spokoju , musiałem przetestować program na atmegu 328 .
Aby przystosować program z m644 do atmega328 należy wprowadzić zmiany w poniższych liniach
testowałem dwa pierwsze przykłady .
Pcmsk2 = &B 00001100
Enable Pcint2 : On Pcint2 Encoder_isr Nosave
Dlaczego
.....wyjaśnienie w linku
KLIK
niveasoft
Posty: 1239 Rejestracja: 17 sie 2015, 12:13
Kontakt:
Post
autor: niveasoft » 23 paź 2020, 11:09
No to chyba nie wystarczy
Jak już tak piszesz to lepiej zamieść cały działający przykład bo tu trzeba zmienić Aliasy dla Encoder_a i Encoder_b
Henryk
Posty: 348 Rejestracja: 22 sty 2018, 17:20
Post
autor: Henryk » 23 paź 2020, 12:01
A dlaczego miałbym zmieniać aliasy , jeśli chcę zachować te wejścia Encoder_a i Encoder_b
Ktoś kto będzie chciał sobie zmienić , to je sobie zmieni
$regfile = "m328pdef.dat"
$crystal = 11059200
$hwstack = 64
$swstack = 32
$framesize = 128
' Cheap encoder PCINT 4xSTEP (four step per click)
' 2017/01/02 by BARTek EDC
Config Submode = New
Config Lcd = 20x4
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
Cursor Off , Noblink
Cls
Dim Turn_l As Byte , Turn_r As Byte , Steps As Integer , Milis As Byte
Dim Enc_new As Byte , Steps_old As Integer , State As Byte
Config Portd.0 = Output : Led_a Alias Portd.0
Config Portd.1 = Output : Led_b Alias Portd.1
Config Portd.2 = Input : Encoder_a Alias Pind.2 : Set Portd.2
Config Portd.3 = Input : Encoder_b Alias Pind.3 : Set Portd.3
Config Timer2 = Timer , Prescale = 1024 , Compare_a = Disconnect , Clear_timer = 1
Compare2a = 215 '20ms @11MHz/1024
Pcmsk2 = &B 00001100
Enable Pcint2 : On Pcint2 Encoder_isr Nosave
Sub Show_steps( )
Locate 2 , 9 : If Steps > 0 Then Lcd "+" : Lcd Steps ; " "
End Sub
Locate 1 , 5 : : Lcd "Every step"
Call Show_steps( )
Enable Interrupts
Do
If Turn_l > 0 Then
Decr Turn_l
Incr Steps
End If
If Turn_r > 0 Then
Decr Turn_r
Decr Steps
End If
If Tifr2 .ocf2a = 1 Then
Tifr2 .ocf2a = 1
Incr Milis
If Milis > 4 Then '5x20ms
Milis = 0
If Steps_old <> Steps Then
Call Show_steps( )
Steps_old = Steps
End If
End If
End If
Led_a = Encoder_a
Led_b = Encoder_b
Loop
End
Encoder_isr:
$asm
!PUSH R16
!PUSH R24
!PUSH R26
!PUSH R27
!PUSH R30
!PUSH R31
!in R24 , sreg
!PUSH R24
$end Asm
Enc_new.0 = Encoder_a
Enc_new.1 = Encoder_b
Select Case Enc_new
Case 1
Select Case State
Case 0 : State = 1 : Decr Steps 'pocz L krok 1
Case 3 : State = 1 : Incr Steps 'revers z 2xHI
Case 4 : State = 5 : Incr Steps 'progress w prawo krok 3 (bo opadaja naprzemian)
End Select
Case 2
Select Case State
Case 0 : State = 2 : Incr Steps 'pocz R krok 1
Case 4 : State = 2 : Decr Steps 'revers z 2xHI
Case 3 : State = 6 : Decr Steps 'progress w lewo krok 3 (bo opadaja naprzemian)
End Select
Case 0 '2xHI
Select Case State
Case 1 : State = 3 : Decr Steps 'byl pocz L krok 1 ->L krok 2 S3
Case 2 : State = 4 : Incr Steps 'byl pocz R krok 1 ->R krok 2 S4
Case 5 : State = 4 : Decr Steps 'revers
Case 6 : State = 3 : Incr Steps 'revers
End Select
Case 3
Select Case State
Case 1 : State = 0 : Incr Steps
Case 2 : State = 0 : Decr Steps
Case 5 : Incr Steps
Case 6 : Decr Steps
End Select
State = 0
End Select
' Tuned with NoSave Tool
$asm
!POP R24
!out sreg , r24
!POP R31
!POP R30
!POP R27
!POP R26
!POP R24
!POP R16
$end Asm
Return
W tym programie zmieniłem również LCD , z racji "sztywnego" połączenia na płycie testowej .