Hallo Richard5,
dieses Programm funktioniert bis ca. 2KHz takt für einen Steppermotor.
Das Program steuert einen Steppermotor und bekommt die Geschwindigkeit über den I²C-Bus von einem Master.
Der CB2WFB-Bus ist ein Kontroll-Bus, sollte der Master nicht in einer bestimmten Zeit, eine Antwort senden, sollte der Motor stehen bleiben.
Das Programm musst du wohl noch anpassen...
erst der Code, als attachment die Pinbelegung ...
Gruß
Matthias
Code:
'Commandos für Speed sind 1 - 255 als byte über TWI
'Commandos für Speed sind 1 bis kleiner Compare1b ohne TWI
'######################
'# Grundkonfiguration #
'######################
$regfile = "m8def.dat"
$crystal = 8000000
$baud = 19200
'Check Chip-Typ
Dim Chiptyp As Byte , Chipneed As Byte
Chiptyp = _chip : Chipneed = 17
'If Chip-Typ is wrong then powerdown the MCU ...
If Chiptyp <> Chipneed Then
Print "invalid chip typ: " ; Chiptyp ; " (needed: " ; Chipneed ; " )"
Powerdown
Else
Print "Executing normal program on chip typ: " ; Chiptyp
End If
'##############
'# Interrupts #
'##############
Config Timer1 = Timer , Prescale = 1024 , Compare A = Toggle , Compare B = Toggle
Config Int0 = Falling
Config Int1 = Falling
Enable Compare1a
Enable Compare1b
Enable Int0
On Compare1a Nextstep
On Compare1b Cb2wfb_send
On Int0 Feedback_master
On Int1 Data_form_master
'#####################
'# Portkonfiguration #
'#####################
Config Portb.5 = Output 'Enable_Chip
Portb.5 = 0
Config Portb.4 = Output 'Richtung
Portb.4 = 0
Config Portb.3 = Output 'Duplex / Modus
Portb.3 = 0
'################
'# Alias setzen #
'################
Ena_chip Alias Portb.5
Dirc Alias Portb.4
Duplex Alias Portb.3
'##############
'# Constanten #
'##############
Const Cb2wbf_default = 3000
Const Ein = 1
Const Aus = 0
Const Half = 1
Const Full = 0
Const Links = 0
Const Rechts = 1
Const Hold = 9000
'##################
'# ERAM Variablen #
'##################
Dim Errorarray(16) As Byte 'Fehlerspeicher
'#############
'# Variablen #
'#############
Dim Twi_control As Byte ' Controlrgister lokale kopie
Dim Twi_status As Byte ' Statusregister lokale kopie
Dim Twi_data As Byte ' Datenregister lokal
Dim Newbyte As Byte ' Bin ich gemeint ? Wenn ja = 1
Dim Speed As Integer ' Geschwindigkeit ...
'Dim Stepparray(12) As Byte
Dim Steppcount As Byte ' Schrittzähler ...
Dim Around As Byte ' Umdrehungen des Motors
Dim Cb2wbf_sende As Integer ' Sende Geschwindigkeit des Busses
Dim Command As Byte
Dim Tomaster As Byte ' Der Daten inhalt wird zum Master gesendet !
Dim Errorcode As Byte ' Fehlercode siehe Tabelle "EC_S"
Dim Errornum As Byte
Dim Lasterror As Byte
Dim No_feedback As Byte
'Dim Dirc As Byte
Dim Modus As Byte
Dim Hb_i As Byte
Dim Int_m As Byte
'##############################
'# Subroutinen und Funktionen #
'##############################
Declare Sub Load_cfg
Declare Sub Twi_init_slave
Declare Sub Send_value(s_command As Byte)
Declare Sub Load_speed(ls_command As Byte)
Declare Sub Stepp_up(su_command As Byte)
Declare Sub Stepp_down(sd_command As Byte)
Declare Sub Change_motor(cm_command As Byte)
Declare Sub Save_errors
Declare Function Get_errors(number As Byte) As Byte
'#######################
'# Konfiguration Laden #
'#######################
Call Load_cfg
'#################
'# Hauptprogramm #
'#################
Start Timer1
Do
' schauen ob TWINT gesetzt ist
Twi_control = Twcr And &H80 ' Bit7 von Controlregister
If Twi_control = &H80 Then
Twi_status = Twsr And &HF8 ' Status
If Twi_status = &H80 Or Twi_status = &H88 Then ' wurde ein Byte geschickt
Twi_data = Twdr ' neue Daten merken
Print "Data: " ; Twdr
Newbyte = Newbyte + 1 ' merken das ein neues Byte da ist
' Elseif Twi_status = &HA8 Or Twi_status = &HB8 Then ' will der Master ein Byte haben
' Twdr = 127 ' neue Daten ausgeben
' Tomaster = 0 ' Daten zum Master löschen
' Newbyte = Newbyte + 1
End If
' TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht
Twcr = &B11000100 ' TWINT löschen, erzeugt ACK
End If
' wenn ein neues Byte gekommen ist, dieses zu verarbeiten
If Newbyte <> 0 Then
Command = Twi_data
Select Case Command
Case 0 : Newbyte = 0 'Nicht für diese MCU
Command = 0 'Befehl zurücksetzen
'Case 57 To 62 : Call Stepp_down(command) 'Befehle für "Motor langsamer"
Case 4 To 63 : Speed = Command
Case 64 : Compare1a = Hold 'Befehl für "Motor Stop"
Speed = Hold
' Case 66 To 71 : Call Stepp_up(command) 'Befehle für "Motor schneller"
' Case 110 To 114 : Call Load_speed(command) 'Befehle für eine feste Geschwindigkeit
Case 200 To 254 : Call Change_motor(command) 'Befehle für "Motor Einstellung"
Case Else : Newbyte = 0 'Nicht für diese MCU
Command = 0 'Befehl zurücksetzen
End Select
'If Newbyte = 1 Then Newbyte = 0
Twdr = 0
'If Newbyte = 0 Then
Enable Compare1a
Enable Compare1b
Start Timer1
'End If
End If
If Errorcode <> 0 Then Call Save_errors
' If Timer1 > 2500 Then Timer1 = 0
Loop
'#########################
'# Globale Konfiguration #
'#########################
Sub Load_cfg
Twi_data = 0 'Keine Daten im Register
Call Twi_init_slave 'Slave Konfiguration
Speed = Hold
Timer1 = 0 'Generator zurücksetzen
Compare1a = Hold 'Frequenz neuladen
Compare1b = Cb2wbf_default 'CB2WFB_Bus zurücksetzen
Ena_chip = Aus 'Motorchip einslachten
Duplex = Half 'Half duplex einschalten
Cb2wbf_sende = Cb2wbf_default 'Default für Feedback setzen
If Err <> 0 Then Errorcode = &H9
Wait 2
Enable Int1
Enable Interrupts
End Sub
'###############################################
'# Einstellungen des Motors und der Steuerung #
'###############################################
Sub Change_motor(cm_command As Byte)
Select Case Cm_command
'-----Motor einschalten-----
Case 201 : Ena_chip = Ein
Case 202 : Ena_chip = Aus
'-------Motor Stepps-------
Case 204 : Duplex = Half
Case 205 : Duplex = Full
'-----Links/Rechts lauf----
Case 207 : Dirc = Links
Case 208 : Dirc = Rechts
'------Etwas anderes ------
Case Else : Errorcode = &HCF
Print "NOP found: " ; Errorcode
End Select
If Cm_command = 202 Then
Cb2wbf_sende = Cb2wbf_default
Elseif Cm_command = 201 Then
Cb2wbf_sende = Cb2wbf_default
End If
Command = 0 'Kommando zurücksetzen
Newbyte = 0 'Befehl Bearteitet
End Sub
'###################################################
'# Regelt die Geschwindigkeit des Motors herunter #
'###################################################
Sub Stepp_down(sd_command As Byte)
Select Case Sd_command
Case 57 : Speed = Speed + 100
Case 58 : Speed = Speed + 50
Case 59 : Speed = Speed + 25
Case 60 : Speed = Speed + 10
Case 61 : Speed = Speed + 5
Case 62 : Speed = Speed + 1
Case Else : Errorcode = &HBF
Print "NOP found: " ; Errorcode
End Select
If Speed < 0 Then Speed = Hold
Command = 0 'Kommando zurücksetzen
Newbyte = 0 'Befehl Bearteitet
End Sub
'#################################################
'# Regelt die Geschwindigkeit des Motors herauf #
'#################################################
Sub Stepp_up(su_command As Byte)
Select Case Su_command
Case 66 : Speed = Speed - 1
Case 67 : Speed = Speed - 5
Case 68 : Speed = Speed - 10
Case 69 : Speed = Speed - 25
Case 70 : Speed = Speed - 50
Case 71 : Speed = Speed - 100
Case Else : Errorcode = &HAF
Print "NOP found: " ; Errorcode
End Select
If Speed < 0 Then Speed = Hold
Command = 0 'Kommando zurücksetzen
Newbyte = 0 'Befehl Bearteitet
End Sub
'##############################################
'# Läde eine feste Geschwindigkeit des Motors #
'##############################################
Sub Load_speed(ls_command As Byte)
Select Case Ls_command
Case 110 : Speed = 100
Case 111 : Speed = 70
Case 112 : Speed = 50
Case 113 : Speed = 30
Case 114 : Speed = 10
Case Else : Errorcode = &HDF
Print "NOP found: " ; Errorcode
End Select
Command = 0 'Kommando zurücksetzen
Newbyte = 0 'Befehl Bearteitet
End Sub
'################################################
'# Zu sendende Daten zusammen packen und senden #
'################################################
'Sub Send_value(s_command As Byte)
' Dim Steppstr As String *
' Select Case S_command
' Case 7 : Tomaster = Speed
' Case 8 : Tomaster = Dirc
' Case 9 : Tomaster = Around
' Case 10 : Tomaster = Get_errors(errornum)
' Case 11 : Tomaster = Modus
' End Select
' If Err <> 0 Then Errorcode = &HF
'End Sub
'####################
'# TWI - Slave INIT #
'####################
Sub Twi_init_slave
Twsr = 0 ' status und Prescaler auf 0
Twdr = &HFF ' default
Twar = &H40 ' Slaveadresse setzen
Twcr = &B01000100 ' TWI aktivieren, ACK einschalten
If Err <> 0 Then Errorcode = &HA
End Sub
'################################
'# Frequenzgenerator = TIMER 1a #
'################################
Nextstep:
Disable Compare1a 'Interrupt für Frquenzausgang abschalten
' Print "Motor: " ; Speed ; " " ; Hex(errorcode)
' Print "Stepp Motor" ; " OC1A = " ; Compare1a ; " OC1B = " ; Compare1b ; " Timer = " ; Timer1 ; " Error: " ; Hex(lasterror)
' Steppcount = Steppcount + 1 'Steppzähler um 1 erhöhen
' Nextspeed = Nextspeed + Speed
Compare1a = Compare1a + Speed 'Nächste Zeit laden
If Err <> 0 Then Errorcode = &HD
Enable Compare1a 'Interrupt für Frequenzausgang einschaten
Return
Return
'##############################
'# Überwachungsbus = TIMER 1b #
'##############################
Cb2wfb_send:
Disable Compare1b 'Interrupt für CB2WFB_Bus ausschalten
' Print "Keep"
' Print "Sende Keep" ; " OC1A = " ; Compare1a ; " OC1B = " ; Compare1b ; " Timer = " ; Timer1 ; " Error: " ; Hex(lasterror)
Timer1 = 0 'Timer zurücksetzen
Compare1a = Speed 'Frequenz neuladen
Compare1b = Cb2wbf_sende 'CB2WFB_Bus zurücksetzen
If No_feedback > 7 Then
Speed = Hold
Errorcode = &HFF
Call Save_errors
Else
No_feedback = No_feedback + 1
End If
If Err <> 0 Then Errorcode = &HE
Enable Compare1b 'Interrupt für CB2WFB_Bus einschalten
Return
Return
Feedback_master:
Disable Int0
' Print "Remote Keep"
No_feedback = 0
Enable Int0
Return
Return
Data_form_master:
Disable Int1
Print "INT1 = Master Data / Lasterr: " ; Hex(lasterror)
' Print "Motor: " ; Speed ; " " ; Hex(errorcode)
Disable Compare1a
Disable Compare1b
Stop Timer1
Enable Int1
Return
Return
'########################
'# !! Fehlerspeicher !! #
'########################
Sub Save_errors
Dim Err_temp As Byte
' Print "Save Error: " ; Hex(errorcode)
' Err_temp = Errorarray(errorcode)
' Err_temp = Err_temp + 1
' Errorarray(errorcode) = Err_temp
Lasterror = Errorcode
Errorcode = 0
End Sub
Function Get_errors(number As Byte) As Byte
Get_errors = Errorarray(number)
End Function
Lesezeichen