JoeM1978
29.09.2013, 19:55
Hey... folgende sache...
Ich habe bereits timer für servos und Motor-PWM in verwendung und möchte deshalb einen
Ultraschallsensor (SRF04) am D6 (PCINT22) abfragen.
Da nurnoch timer 2 dafür zur verfügung steht hatte ich mir überlegt, den wert einfach mit den Überläufen hochzurechnen.
Nun hab ich noch herausgefunden, das der gesamte D-Port reagiert, wenn man es nicht über Pcmsk beschränkt.
Ich hoffe das ist soweit richtig gelöst.
soweit so gut...
allerdings habe ich hier ein kleines Testprogramm... das trotzdem recht
verwirrende Werte ausgibt.
$regfile = "m328pdef.dat" 'eingesetzter Mikrocontroller
$crystal = 8000000 'eingestellte Taktfrequenz (8MHz)
$hwstack = 100 'Standardwert
$swstack = 100 'Standardwert
$framesize = 100 'Standardwert
$baud = 9600
'-------------------------------------------------------------------------------
'Ports/Pins/Configs
'-------------------------------------------------------------------------------
Config Portb.0 = Output 'Funkmodul ENABLE
Funk_enable Alias Portb.0
Config Portb.1 = Output 'Motor2 Geschwindigkeit (PWM)
Motor2speed Alias Portb.1
Config Portb.2 = Output 'Motor1 Geschwindigkeit (PWM)
Motor1speed Alias Portb.2
Config Portb.3 = Output 'Servo1 (PWM)
Servo1 Alias Portb.3
Config Portb.4 = Output 'Motor2a
Motor2b Alias Portb.4
Config Portb.5 = Output 'Motor2b
Motor2a Alias Portb.5
Config Portc.0 = Output 'Motor1b
Motor1b Alias Portc.0
Config Portc.1 = Output 'Motor1a
Motor1a Alias Portc.1
'Config Portc.2 = Output
'Xx Alias Portc.2
'Config Portc.3 = Output
'Xx Alias Portc.3
'Config Portc.4 = Output
'Xx Alias Portc.4
'Config Portc.5 = Output
'Xx Alias Portc.5
'Config Portd.2 = Output
'Xx Alias Pind.2
'Config Portd.3 = Output
'Xx Alias Portd.3
'Config Portd.4 = Output
'Xx Alias Portd.4
'Config Portd.5 = Output
'Xx Alias Portd.5
Config Pind.6 = Input 'Ultraschall Echo
Us_echo Alias Pind.6
Config Portd.7 = Output 'Ultraschall Trigger
Us_trigger Alias Portd.7
'-------------------------------------------------------------------------------
'Timer/OCR/PWM/ISR usw. setzen
'-------------------------------------------------------------------------------
Pcicr = &B100
Pcmsk2 = &B01000000
On Pcint2 Echowechsel
Enable Pcint2
Config Timer2 = Timer , Prescale = 1 ' Echo vom Ultraschallsensor zählen
On Timer2 Isr_timer2
Enable Timer2
Enable Interrupts 'Interrupts global aktivieren
'-------------------------------------------------------------------------------
'Variablen
'-------------------------------------------------------------------------------
Dim Temp_string As String * 10
Dim Temp_long As Long
Dim Timerueberlauf As Long
Timerueberlauf = 0
Dim Messung_starten As Bit ' Zeigt an, ob Messung gestartet werden soll
Messung_starten = 1
Dim Messung_beendet As Bit ' Zeigt an, ob Messung beendet ist
Messung_beendet = 0
Dim Messergebniss As Long ' Ergebniss der Messung in us
Messergebniss = 0
Dim Entfernung As Long ' Entfernung in mm
Entfernung = 0
Dim Position_x_soll As Word
Dim Start_pause As Single
Start_pause = 1000
Dim Triggersignal_laenge As Single
Triggersignal_laenge = 10
Dim Timer_ueberlauf As Word
Timer_ueberlauf = 0
Declare Sub Triggersignal_senden(byval Start_pause As Single , Byval Triggersignal_laenge As Single)
'-------------------------------------------------------------------------------
'Hauptprogramm
'-------------------------------------------------------------------------------
Hauptprogramm:
Do
For Position_x_soll = 8 To 22 Step 2
Timerueberlauf = 0
Messergebniss = 0
Temp_long = 0
Entfernung = 0
Messung_beendet = 0
Call Triggersignal_senden(start_pause , Triggersignal_laenge)
Do
Waitus 1
Loop Until Messung_beendet = 1
If Messung_beendet = 1 Then
Print "'t=" ; Timerueberlauf
Print "_T=" ; Temp_long
Messergebniss = Messergebniss + Temp_long
Print "_M=" ; Messergebniss
Entfernung = Messergebniss * 172
Entfernung = Entfernung / 10000 ' Ergebniss in mm ?
Temp_string = Str(entfernung)
Temp_string = Format(temp_string , "000000")
Waitms 500
Print "==" ; Temp_string ; "mm" ' Ausgabe des Ergebniss
End If
Next
Loop
End
'-------------------------------------------------------------------------------
'Subs
'-------------------------------------------------------------------------------
Sub Triggersignal_senden(byval Start_pause As Single , Byval Triggersignal_laenge As Single)
Messung_beendet = 0
Waitms Start_pause ' minimale Wartezeit um "Fehlechos" auszuschliessen
Portd.7 = 1 ' Impuls an Triggerport senden
Waitus Triggersignal_laenge ' Impulsdauer 10us
Portd.7 = 0
End Sub
'-------------------------------------------------------------------------------
'Interrupt
'-------------------------------------------------------------------------------
Isr_timer2:
Timerueberlauf = Timerueberlauf + 1 'Timerüberläufe zählen
Return
Echowechsel: ' Interrupt startet bei Signalwechsel am Echopin
If Pind.6 = 1 Then ' Wenn Pin zu High wechselt ...
Timer2 = 0
Else ' wenn Pin zu LOW wechselt....
Messergebniss = Timer2 ' Messergebniss in Variable speichern
Temp_long = Timerueberlauf * 255 ' aktuelle Timerüberläufe übernehmen
Messung_beendet = 1 ' Anzeigen, das Messung beendet is
End If
Return
nichtmal der wert "Temp_long" wird korrekt berechnet...
kann es sein, das der 328p mir da irgendwie rechenfehler reinbaut ? o.O
NACHTRAG:
Es werden z.b. solche (nur mit geringen Schwankungen) Werte ausgegeben:
t=5241 _T=1327530 _M1327777 ==022837mm
und als Quarz ist ein 8mhz-Quarz verbaut und als fuse ist eingestellt:
Ext.Crystal Osc.; Frequ. 3,0-8,0MHz; ... 16/14/65ms
Kann bitte jemand meinen blinden Augen auf die sprünge helfen ?
Ich habe bereits timer für servos und Motor-PWM in verwendung und möchte deshalb einen
Ultraschallsensor (SRF04) am D6 (PCINT22) abfragen.
Da nurnoch timer 2 dafür zur verfügung steht hatte ich mir überlegt, den wert einfach mit den Überläufen hochzurechnen.
Nun hab ich noch herausgefunden, das der gesamte D-Port reagiert, wenn man es nicht über Pcmsk beschränkt.
Ich hoffe das ist soweit richtig gelöst.
soweit so gut...
allerdings habe ich hier ein kleines Testprogramm... das trotzdem recht
verwirrende Werte ausgibt.
$regfile = "m328pdef.dat" 'eingesetzter Mikrocontroller
$crystal = 8000000 'eingestellte Taktfrequenz (8MHz)
$hwstack = 100 'Standardwert
$swstack = 100 'Standardwert
$framesize = 100 'Standardwert
$baud = 9600
'-------------------------------------------------------------------------------
'Ports/Pins/Configs
'-------------------------------------------------------------------------------
Config Portb.0 = Output 'Funkmodul ENABLE
Funk_enable Alias Portb.0
Config Portb.1 = Output 'Motor2 Geschwindigkeit (PWM)
Motor2speed Alias Portb.1
Config Portb.2 = Output 'Motor1 Geschwindigkeit (PWM)
Motor1speed Alias Portb.2
Config Portb.3 = Output 'Servo1 (PWM)
Servo1 Alias Portb.3
Config Portb.4 = Output 'Motor2a
Motor2b Alias Portb.4
Config Portb.5 = Output 'Motor2b
Motor2a Alias Portb.5
Config Portc.0 = Output 'Motor1b
Motor1b Alias Portc.0
Config Portc.1 = Output 'Motor1a
Motor1a Alias Portc.1
'Config Portc.2 = Output
'Xx Alias Portc.2
'Config Portc.3 = Output
'Xx Alias Portc.3
'Config Portc.4 = Output
'Xx Alias Portc.4
'Config Portc.5 = Output
'Xx Alias Portc.5
'Config Portd.2 = Output
'Xx Alias Pind.2
'Config Portd.3 = Output
'Xx Alias Portd.3
'Config Portd.4 = Output
'Xx Alias Portd.4
'Config Portd.5 = Output
'Xx Alias Portd.5
Config Pind.6 = Input 'Ultraschall Echo
Us_echo Alias Pind.6
Config Portd.7 = Output 'Ultraschall Trigger
Us_trigger Alias Portd.7
'-------------------------------------------------------------------------------
'Timer/OCR/PWM/ISR usw. setzen
'-------------------------------------------------------------------------------
Pcicr = &B100
Pcmsk2 = &B01000000
On Pcint2 Echowechsel
Enable Pcint2
Config Timer2 = Timer , Prescale = 1 ' Echo vom Ultraschallsensor zählen
On Timer2 Isr_timer2
Enable Timer2
Enable Interrupts 'Interrupts global aktivieren
'-------------------------------------------------------------------------------
'Variablen
'-------------------------------------------------------------------------------
Dim Temp_string As String * 10
Dim Temp_long As Long
Dim Timerueberlauf As Long
Timerueberlauf = 0
Dim Messung_starten As Bit ' Zeigt an, ob Messung gestartet werden soll
Messung_starten = 1
Dim Messung_beendet As Bit ' Zeigt an, ob Messung beendet ist
Messung_beendet = 0
Dim Messergebniss As Long ' Ergebniss der Messung in us
Messergebniss = 0
Dim Entfernung As Long ' Entfernung in mm
Entfernung = 0
Dim Position_x_soll As Word
Dim Start_pause As Single
Start_pause = 1000
Dim Triggersignal_laenge As Single
Triggersignal_laenge = 10
Dim Timer_ueberlauf As Word
Timer_ueberlauf = 0
Declare Sub Triggersignal_senden(byval Start_pause As Single , Byval Triggersignal_laenge As Single)
'-------------------------------------------------------------------------------
'Hauptprogramm
'-------------------------------------------------------------------------------
Hauptprogramm:
Do
For Position_x_soll = 8 To 22 Step 2
Timerueberlauf = 0
Messergebniss = 0
Temp_long = 0
Entfernung = 0
Messung_beendet = 0
Call Triggersignal_senden(start_pause , Triggersignal_laenge)
Do
Waitus 1
Loop Until Messung_beendet = 1
If Messung_beendet = 1 Then
Print "'t=" ; Timerueberlauf
Print "_T=" ; Temp_long
Messergebniss = Messergebniss + Temp_long
Print "_M=" ; Messergebniss
Entfernung = Messergebniss * 172
Entfernung = Entfernung / 10000 ' Ergebniss in mm ?
Temp_string = Str(entfernung)
Temp_string = Format(temp_string , "000000")
Waitms 500
Print "==" ; Temp_string ; "mm" ' Ausgabe des Ergebniss
End If
Next
Loop
End
'-------------------------------------------------------------------------------
'Subs
'-------------------------------------------------------------------------------
Sub Triggersignal_senden(byval Start_pause As Single , Byval Triggersignal_laenge As Single)
Messung_beendet = 0
Waitms Start_pause ' minimale Wartezeit um "Fehlechos" auszuschliessen
Portd.7 = 1 ' Impuls an Triggerport senden
Waitus Triggersignal_laenge ' Impulsdauer 10us
Portd.7 = 0
End Sub
'-------------------------------------------------------------------------------
'Interrupt
'-------------------------------------------------------------------------------
Isr_timer2:
Timerueberlauf = Timerueberlauf + 1 'Timerüberläufe zählen
Return
Echowechsel: ' Interrupt startet bei Signalwechsel am Echopin
If Pind.6 = 1 Then ' Wenn Pin zu High wechselt ...
Timer2 = 0
Else ' wenn Pin zu LOW wechselt....
Messergebniss = Timer2 ' Messergebniss in Variable speichern
Temp_long = Timerueberlauf * 255 ' aktuelle Timerüberläufe übernehmen
Messung_beendet = 1 ' Anzeigen, das Messung beendet is
End If
Return
nichtmal der wert "Temp_long" wird korrekt berechnet...
kann es sein, das der 328p mir da irgendwie rechenfehler reinbaut ? o.O
NACHTRAG:
Es werden z.b. solche (nur mit geringen Schwankungen) Werte ausgegeben:
t=5241 _T=1327530 _M1327777 ==022837mm
und als Quarz ist ein 8mhz-Quarz verbaut und als fuse ist eingestellt:
Ext.Crystal Osc.; Frequ. 3,0-8,0MHz; ... 16/14/65ms
Kann bitte jemand meinen blinden Augen auf die sprünge helfen ?