gibt es eine Möglichkeit um zu testen, wie ausgelastet der µC ist? Also nicht von der Speicherkapazität, sondern von der Zykluszeit?
Tobias
Druckbare Version
gibt es eine Möglichkeit um zu testen, wie ausgelastet der µC ist? Also nicht von der Speicherkapazität, sondern von der Zykluszeit?
Tobias
Hallo Tobias,Zitat:
Zitat von TobiasBlome
da ist aber mehr falsch als nur ein Schönheitsfehler.
Usb_auslesen ist eine Subroutine, in die das Programm gleich zu Anfang rein läuft. Ohne auf ein Return zu kommen - was hier auch fatal wäre - geht es in die main loop. Dort kann dann wieder usb_auslesen aufgerufen werden. Dies wird relativ schnell zu einem Stack Overflow führen.
Setze deine Subs alle hinter das End und schließe sie immer mit einem Return ab.
Mehr habe ich mir noch nicht angesehen.
Gruß
Rolf
hab das Programm geändert - aber es lief vorher auch schon: hab es aber immer nur ein paar Minuten getestet...
Aber ich möchte es natürlich nicht riskieren das der µC sich "aufhängt"
Code:'-------------------------------------------------------------------------------
'Konfiguration µC:
$regfile = "m32def.dat" 'AT-Mega32
$crystal = 14745600 'Quarz: 14,7456 MHz
$baud = 9600 'Baudrate definieren
$hwstack = 80 ' default use 32 for the hardware stack
$swstack = 80 ' default use 10 for the SW stack
$framesize = 80 ' default use 40 for the frame space
'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddra = &B00000000 '1 Ausgang, 0 Eingang = Pin PA7-0
Ddrb = &B11111111 '1 Ausgang, 0 Eingang = Pin PB7-0
Ddrc = &B11111111 '1 Ausgang, 0 Eingang = Pin PC7-0
Ddrd = &B01111111 '1 Ausgang, 0 Eingang = Pin PD7-0
Porta = &B00000000 '1 = Pullup
Portb = &B00000000 '1 = Pullup
Portc = &B11111111 '1 = Pullup
Portd = &B00000000 '1 = Pullup
'-------------------------------------------------------------------------------
'Timer1 = 16 Bit
Config Timer1 = Timer , Prescale = 64 'Teiler 1/8/64/256/1024
Enable Timer1 'timer einschalten
Const Timer1vorgabe = 7936 '7936 = 4 mal pro Sekunde
Timer1 = Timer1vorgabe
On Timer1 Ontimer1overflow 'Unteprogramm aufrufen
'-------------------------------------------------------------------------------
'Analogmessung:
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc 'Starte analog Messung
'-------------------------------------------------------------------------------
'USB Confi!!!!
Echo Off '///für USB-Stick
Open "com1:" For Binary As #1 '///für USB-Stick
'Dim Samples As Word 'Anzahl der Messungen
Dim Delayms As Long 'Messintervall in ms (Long bis 2.147.483.647)
Dim Channels As Word 'Anzahl der Messkanäle (8Kanäle -> 0-7)(Word bis 65535)
Dim N As Integer
Dim I As Integer
Dim L As Integer
Dim S As String * 40
Dim Ad As Integer
Dim Messung As Long 'Anzahl der gemessenen Werte (Long bis 2.147.483.647)
Dim Wartezeit As Long 'Wartezeit über Timer
Dim Auslesen_ok As Bit 'ausleseroutine erfolgreich
Dim Logging As Bit '1 = Daten werden aufgezeichnet
'-------------------------------------------------------------------------------
'Vor Programmstart:
Auslesen_ok = 0
Logging = 0
Wartezeit = 999
Delayms = 0
Start Adc 'Analogmessung starten
Stop Timer1
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Do
'_______________________________________________________________________________
'Reset
If Pind.7 = 0 Then 'RESET
Auslesen_ok = 0 'Speicher zurücksetzen
End If
'_______________________________________________________________________________
'Auslesen
If Auslesen_ok = 0 Then
Logging = 0
Messung = 0 'Zähler für Messungen zurücksetzen
Portb.0 = 0 'schreib LED aus
Auslesen_ok = 0 'Speicher zurücksetzen
Gosub Usb_auslesen
End If
'_______________________________________________________________________________
'speichern
If Logging = 1 Then
Logging = 0
Gosub Usb_schreiben
End If
Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'ENDE - Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Usb_auslesen:
Stop Timer1
Do
Input S
Loop Until S = "D:\>" 'USB Controller abfragen, bis D:\> gesendet wird
Waitms 1000
Print "rd todo.txt" + Chr(13); 'todo.txt Datei LESEN
Input Delayms 'Wartezeit zwischen den Messungen aus Datei übernehmen
Get #1 , L
Input Channels 'Anzahl der Messkanäle aus Datei übernehmen
Get #1 , L
Input S
Auslesen_ok = 1
Enable Interrupts
Start Timer1
Return
'-------------------------------------------------------------------------------
Usb_schreiben:
Print "OPW Log.txt" + Chr(13); 'Datei Log.txt öffnen
Input S
Portb.0 = 1 'schreib LED an
Incr Messung
S = Str(messung) + Chr(9)
For I = 0 To Channels 'Kanäle 0-7 MAX
Ad = Getadc(i) 'hole Analogwert von Kanal = (Variable "I")
S = S + Str(ad) 'S + aktuellen Analogkanal
If I < Channels Then S = S + Chr(9) 'wenn noch nicht alle Kanäle abgefragt wurden kommt ein Chr(9) = Tab drann!!!
Next I
S = S + Chr(13) + Chr(10) 'zum Schluss noch Zeichen 13+10 Carriage Return + Line Feed
L = Len(s) 'gibt die Länge von String "S" wieder
Print "WRF "; 'Befehl um in die geöffnete Datei zu schreiben
Put #1 , 0
Put #1 , 0
Put #1 , 0
Put #1 , L 'L ist die Länge vom String S
Put #1 , 13
Print S ;
Input S
Print "CLF log.txt" + Chr(13); 'Datei log.txt schließen
Input S
Portb.0 = 0 'schreib LED aus
Return
'-------------------------------------------------------------------------------
'TIMER SPRUNGMARKEN:
Ontimer1overflow:
Timer1 = Timer1vorgabe
Incr Wartezeit
'Toggle Portb.0 'nur zum testen ob timer1 läuft
If Wartezeit => Delayms And Auslesen_ok = 1 Then 'Wartezeit zwischen den Messungen
Wartezeit = 0 'Wartezeit zurücksetzen
Logging = 1 'Daten werden aufgezeichnet
End If
Return
@for_ro
Dies wird relativ schnell zu einem Stack Overflow führen.
warum führt das zu einem Stack Overflow? Allgemein oder bei Programmierfehlern?
vielen Dank,
Tobias
Was meinst du damit?Zitat:
Zitat von TobiasBlome
Nachdem eine Sub ausgeführt worden ist, wird das Programm mit dem Befehl nach dem Gosub fortgesetzt. Die Speicherstelle des Befehls wird dazu im Stack abgelegt. Dann werden die Befehle in der Sub ausgeführt. Kommt jetzt das nächste Gosub, wird wieder die Rücksprungadresse in den Stack gelegt und zwar in die nächste Zelle. Wird dann ein Return Befehl ausgeführt, springt das Programm an die letzte gespeicherte Stelle zurück und löscht diese vom Stack. Wenn also zu einem Gosub kein Return gefunden wird, bleibt die entsprechende Rücksprungadresse im Stack liegen. Da der Stack nur eine begrenzte Größe hat, läuft er irgendwann voll. Die nächste Adresse wird dann in einen Bereich geschrieben, der nicht dafür reserviert ist und es passieren meistens vollkommen ungewollte und nicht nachvollziehbare Aktionen.
Gruß
Rolf
Ach so,
dann habe ich ja "Glück gehabt" weil ich diese Sub nur max 2-3 mal benutze. Nämlich jedesmal wenn ich den Taster an Pind.7 betätige um eine neue Aufzeichnung zu starten. Meisten zeichnet man ja nur 1 mal auf ;-) - nach einem Neustart ist der Stack ja dann sowieso leer.
Danke,
Tobias
TobiasBlome: Das Projekt interessiert nich sehr, da ich schon lange
nach einer Möglichkeit suche. Daten von AVR auf einen USB-Stick
ohne Umwege zu loggen. Gibts dazu ne Schaltungg? Vielen Dank und
Viele Grüße Micha
@hardware.bas
ich benutze den "Vinculum" der Firma FTDI. In der Elektor(11/2008 S.42) ist ein ausführlicher Artikel. Ausserdem kann man das IC(smd 48pin) als fertig Modul mit USB-Buchse auf einer Platine bei Elektor im shop kaufen.
Angesteuert wird das IC über die serielle Schnittstelle - also relativ bequem vom µC ansteuerbar.
Tobias