Hallo,
ich beschäftige mich erst seit ein paar Wochen mit Microcontrollern und habe daher noch nicht allzu viel Erfahrung. Ich habe folgendes Programm für einen Datenlogger geschrieben:
Der Timer zählt im Sekundentakt die Variable Zeit hoch. Wenn Variable Zeit = Variable Intervall ist, wird der aktuelle Wert vom AD-Wandler gelesen, der Wert und der neue Zählerstand in einem externen EEPROM gespeichert und die Variable Zeit zurückgesetzt. Anschließend können die Daten über UART wieder ausgelesen werden.Code:$regfile = "m8def.dat" $crystal = 1000000 $hwstack = 65 $swstack = 40 $framesize = 100 $baud = 4800 Config Sda = Portc.4 Config Scl = Portc.5 Declare Sub Serial0charmatch Declare Sub Wertlesen(kanal As Word) Declare Sub Speichern(daten As Word) Declare Sub Lesen Declare Sub Intervall(intervall_neu As String) Declare Sub Datenausgabe(bereich As String) Declare Sub Online Dim Schreiben As Word At $250 Dim Schreiben1 As Byte At $250 Overlay Dim Schreiben2 As Byte At $251 Overlay Dim Addresse As Word At $260 Dim Addresse1 As Byte At $260 Overlay Dim Addresse2 As Byte At $261 Overlay Dim Lesen As Word At $270 Dim Lesen1 As Byte At $270 Overlay Dim Lesen2 As Byte At $271 Overlay Dim Befehl As String * 12 Dim Befehlarray(2) As String * 7 Dim Intervall As Word Dim Zeit As Word Dim A As Byte Dim N As Word Dim Ende As Word Dim Zaehler As Word Dim Temp As Word Dim Druck As Word Config Adc = Single , Prescaler = Auto Start Adc Config Timer1 = Timer , Prescale = 64 Timer1 = 49910 On Timer1 Isr_timer1 Config Serialin = Buffered , Size = 15 , Bytematch = 13 Config Pinb.2 = Input Config Portb.1 = Output 'Config Portb.3 = Output Portb.2 = 1 Zeit = 0 Zaehler = 1 Readeeprom Lesen1 , 10 'Intervallzeit lesen Readeeprom Lesen2 , 11 If Lesen >= 1 Then Intervall = Lesen Else Intervall = 1 End If Enable Interrupts 'Programm Anfang Enable Timer1 Do Addresse = Zaehler * 2 Decr Addresse 'Hauptschleife If Zeit >= Intervall Then N = 0 Call Wertlesen(n) Call Speichern(temp) Addresse = 5000 Call Speichern(zaehler) Incr Zaehler End If Loop End Isr_timer1: 'Timer zählt im Sekundentakt Timer1 = 49910 If Pinb.2 = 0 Then Incr Zeit End If Return Sub Serial0charmatch() 'Daten über UART empfangen Input Befehl Noecho If Befehl <> "" Then A = Split(befehl , Befehlarray(1) , " ") Select Case Befehlarray(1) Case "interv" : Call Intervall(befehlarray(2)) Case "lesen" : Call Datenausgabe(befehlarray(2)) Case "online" : Call Online End Select End If End Sub Sub Wertlesen(kanal As Word) Toggle Portb.1 'AD-Wandler auslesen Temp = Getadc(kanal) Zeit = 0 End Sub Sub Speichern(daten As Word) Disable Interrupts Schreiben = Daten I2cstart 'Start I2cwbyte &HA0 'Sende Slavadresse I2cwbyte Addresse2 'Sende Speicheradresse High I2cwbyte Addresse1 'Sende Speicheradresse LOW I2cwbyte Schreiben2 'Sende Wert I2cstop 'stop Waitms 5 'warte 10ms Incr Addresse I2cstart 'Start I2cwbyte &HA0 'Sende Slavadresse I2cwbyte Addresse2 'Sende Speicheradresse High I2cwbyte Addresse1 'Sende Speicheradresse LOW I2cwbyte Schreiben1 'Sende Wert I2cstop 'stop Waitms 5 'warte 10ms Enable Interrupts End Sub Sub Lesen Disable Interrupts I2cstart 'Start I2cwbyte &HA0 'Sende Slavadresse +1 für Schreiben I2cwbyte Addresse2 'Sende Speicheradresse High I2cwbyte Addresse1 'Sende Speicheradresse Low I2cstart 'Start I2cwbyte &HA1 'Sende Slavadresse +1 für Lesen I2crbyte Lesen2 , Nack 'Lese Adresse vom EEprom I2cstop Waitms 5 'Stop Incr Addresse I2cstart 'Start I2cwbyte &HA0 'Sende Slavadresse +1 für Schreiben I2cwbyte Addresse2 'Sende Speicheradresse High I2cwbyte Addresse1 'Sende Speicheradresse Low I2cstart 'Start I2cwbyte &HA1 'Sende Slavadresse +1 für Lesen I2crbyte Lesen1 , Nack 'Lese Adresse vom EEprom I2cstop 'Stop Waitms 5 Enable Interrupts End Sub Sub Intervall(intervall_neu As String) Disable Interrupts Schreiben = Val(intervall_neu) Writeeeprom Schreiben1 , 10 Writeeeprom Schreiben2 , 11 Intervall = Val(intervall_neu) Enable Interrupts Print "Neuer Intervall: " ; Intervall_neu ' Intervallzeit ändern End Sub Sub Datenausgabe(bereich As String) Select Case Bereich Case "z" Addresse = 5000 Call Lesen Print Str(lesen) Case "iv" Print Str(intervall) Case Else Addresse = Val(bereich) Ende = Val(bereich) + 19 Do Call Lesen Print Str(lesen) Incr Addresse Loop Until Addresse > Ende End Select End Sub Sub Online N = 0 Call Wertlesen(n) Print Str(temp) End Sub
Das funktioniert auch soweit, jedoch veränder sich der Zählerstand manchmal beim auslesen. Habe ich vielleicht bei der Variablendeklaration etwas falsch gemacht?
Vielen Dank im Voraus für eure Antworten







Zitieren

Lesezeichen