mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Verzweigungen


Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine Frage ist, ob diese Verzweigung die ich hier habe prinzipiell 
funktioniert oder es halt nicht üblich ist so zu verzweigen:
;*****************************Hauptprogramm************************************
Hauptprogramm:
rcall  ADC_Kanal0
rcall    StartADC
        in Messergebnisleft, ADCH
        cp Messergebnisleft, Schwellwertleft
        brsh LinksGroesser
MessungZW05:                        ;LINIENERKENNUNG linker LDR
        cp Messergebnisleft, Schwellwertleft
        brlo LinksKleiner
MessungZW1: 

rcall  ADC_Kanal1
rcall    StartADC
        in Messergebnismiddle, ADCH
        cp Messergebnismiddle, Schwellwertmiddle
        brsh MitteGroesser
MessungZW15:                        ;LINIENERKENNUNG mittlerer LDR
        cp Messergebnismiddle, Schwellwertmiddle
        brlo MitteKleiner
MessungZW2:

rcall  ADC_Kanal2
rcall    StartADC
        in Messergebnisright, ADCH
        cp Messergebnisright, Schwellwertright
        brsh RechtsGroesser
MessungZW25:                        ;LINIENERKENNUNG rechter LDR
        cp Messergebnisright, Schwellwertright
        brlo RechtsKleiner
          
MessungZW3:

;#######Motoransteuerung##########
      cpi Linienerkennung, 0b00000001
      breq MotorLinks
MotorZW:
      cpi Linienerkennung, 0b00000010
      breq MotorMitte
MotorZW2:
      cpi Linienerkennung, 0b00000100
      breq MotorRechts
MotorZW3:
;#################################


    sbis PIND, 2        ;Überprüfe PIND.0
    rcall Messeschwellwert     ;Wenn PIND.0 = 0 (Taster betätigt)--> Messung
rjmp Hauptprogramm          ;ansosnten wieder von vorne
;*********************************************************************************

;Motoren setzen####################################
MotorLinks:
  sbi PORTB, 2
  cbi PORTB, 1
rjmp MotorZW

MotorMitte:
  sbi PORTB, 2
  sbi PORTB, 1
rjmp MotorZW2

MotorRechts:
  cbi PORTB, 2
  sbi PORTB, 1
rjmp MotorZW3
;##################################################

;Setze Bits in Byte für die Linienerkennung########
LinksGroesser:
  sbr Linienerkennung, 1  
rjmp MessungZW05

LinksKleiner:
  cbr Linienerkennung, 1
rjmp MessungZW1


MitteGroesser:
  sbr Linienerkennung, 2
rjmp MessungZW15
  
MitteKleiner:
  cbr Linienerkennung, 2
rjmp MessungZW2


RechtsGroesser:
  sbr Linienerkennung, 4
rjmp MessungZW25

RechtsKleiner:
  cbr Linienerkennung, 4
rjmp MessungZW3

;##################################################

lg andy

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>rcall  ADC_Kanal0
>rcall    StartADC
>in Messergebnisleft, ADCH

Diese Aufteilung der ADC-Messung ist relativ sinnfrei.

>cp Messergebnisleft, Schwellwertleft
>brsh LinksGroesser
>MessungZW05:                        ;LINIENERKENNUNG linker LDR
>cp Messergebnisleft, Schwellwertleft
>brlo LinksKleiner

Wenn Messergebnisleft nicht >= Schwellwertleft ist, ist es 
zwangsläufig kleiner. Da es keine dritte Möglichkeit gibt, ist der 
zweite Vergleich überflüssig.

>;Setze Bits in Byte für die Linienerkennung########
>....
Warum macht du das nicht sofort nach dem Vergleich. Das Herumgespringe 
ist unübersichtlich.

MfG Spess

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Diese Aufteilung der ADC-Messung ist relativ sinnfrei.
ich finde, wenn ich es auskommentiere ist es viel unübersichtlicher als 
wie ernn ich dafür eigene unterprogramme schreibe


>Wenn Messergebnisleft nicht >= Schwellwertleft ist, ist es
>zwangsläufig kleiner. Da es keine dritte Möglichkeit gibt, ist der
>zweite Vergleich überflüssig.
Richtig, da is mal gleich ein fehler drinn, denn richtig ist es so:
;*****************************Hauptprogramm************************************
Hauptprogramm:
rcall  ADC_Kanal0
rcall    StartADC
        in Messergebnisleft, ADCH
        cp Messergebnisleft, Schwellwertleft
        brsh LinksGroesser
MessungZW05:                        ;LINIENERKENNUNG linker LDR
        cp Messergebnisleft, Linksaus
        brlo LinksKleiner
MessungZW1: 

rcall  ADC_Kanal1
rcall    StartADC
        in Messergebnismiddle, ADCH
        cp Messergebnismiddle, Schwellwertmiddle
        brsh MitteGroesser
MessungZW15:                        ;LINIENERKENNUNG mittlerer LDR
        cp Messergebnismiddle, Mitteaus
        brlo MitteKleiner
MessungZW2:

rcall  ADC_Kanal2
rcall    StartADC
        in Messergebnisright, ADCH
        cp Messergebnisright, Schwellwertright
        brsh RechtsGroesser
MessungZW25:                        ;LINIENERKENNUNG rechter LDR
        cp Messergebnisright, Rechtsaus
        brlo RechtsKleiner
          
MessungZW3:

;#######Motoransteuerung##########
      cpi Linienerkennung, 0b00000001
      breq MotorLinks
MotorZW:
      cpi Linienerkennung, 0b00000010
      breq MotorMitte
MotorZW2:
      cpi Linienerkennung, 0b00000100
      breq MotorRechts
MotorZW3:
;#################################


    sbis PIND, 2        ;Überprüfe PIND.0
    rcall Messeschwellwert     ;Wenn PIND.0 = 0 (Taster betätigt)--> Messung
rjmp Hauptprogramm          ;ansosnten wieder von vorne
;*********************************************************************************

;Motoren setzen####################################
MotorLinks:
  sbi PORTB, 2
  cbi PORTB, 1
rjmp MotorZW

MotorMitte:
  sbi PORTB, 2
  sbi PORTB, 1
rjmp MotorZW2

MotorRechts:
  cbi PORTB, 2
  sbi PORTB, 1
rjmp MotorZW3
;##################################################

;Setze Bits in Byte für die Linienerkennung########
LinksGroesser:
  sbr Linienerkennung, 1  
rjmp MessungZW05

LinksKleiner:
  cbr Linienerkennung, 1
rjmp MessungZW1


MitteGroesser:
  sbr Linienerkennung, 2
rjmp MessungZW15
  
MitteKleiner:
  cbr Linienerkennung, 2
rjmp MessungZW2


RechtsGroesser:
  sbr Linienerkennung, 4
rjmp MessungZW25

RechtsKleiner:
  cbr Linienerkennung, 4
rjmp MessungZW3

;##################################################

spess53 schrieb:
> Warum macht du das nicht sofort nach dem Vergleich. Das Herumgespringe
> ist unübersichtlich.

weil, wenn ich die Marke gleich nach dem Vergleich aufschreibe, er dann 
so oder so hineinspringt, denn wenn die bedingung nicht eintrifft,dann 
macht er weiter im coding, es wäre natürlich viel schöner.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie wärs damit:

PROGRAMM:
S1:
falls ADC1 kleiner Wert, springe zu S2

Mach was (ADC1>Wert)

S2:
falls ADC2 kleiner Wert, springe zu S3

Mach was (ADC2>Wert)

S3:
falls ADC3 kleiner Wert, springe zu ENDE

Mach was (ADC3>Wert)

ENDE:
zurück zu S1

;-)

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> PROGRAMM:
> S1:
> falls ADC1 kleiner Wert, springe zu S2
>
> Mach was (ADC1>Wert)
>
> S2:
> falls ADC2 kleiner Wert, springe zu S3
>
> Mach was (ADC2>Wert)
>
> S3:
> falls ADC3 kleiner Wert, springe zu ENDE
>
> Mach was (ADC3>Wert)
>
> ENDE:

das funktioniert leider nicht

siehdir mal diesen Bascom code an, nach dem habe ich mich gerichtet:

Do
    Start Adc

    Messergebnisleft = Getadc(0)
    If Messergebnisleft > Schwellwertleft Then Zustand.0 = 1       'Else Zustand = 0
    If Messergebnisleft < Linksaus Then Zustand.0 = 0       'schreibe Information von sensor rechts in Byte Zustand

    Messergebnismiddle = Getadc(1)
    If Messergebnismiddle > Schwellwertmiddle Then Zustand.1 = 1       'Else Zustand = 0
    If Messergebnismiddle < Mitteaus Then Zustand.1 = 0     'schreibe Information von sensor mitte in Byte Zustand

    Messergebnisright = Getadc(2)
    If Messergebnisright > Schwellwertright Then Zustand.2 = 1       'Else Zustand = 0
    If Messergebnisright < Rechtsaus Then Zustand.2 = 0     'schreibe Information von sensor links in Byte Zustand

    Select Case Zustand

        Case &B00000001 :
            Portb = &B00000100
            Letzterzustand = "Links"                        'Merke dir den letzten Zustand

        Case &B00000100 :
            Portb = &B00000010
            Letzterzustand = "Rechts"

        Case &B00000010 :
            Portb = &B00000110
            Letzterzustand = "Mitte"

        Case &B00000000                                     'Falls undefinierter Zustand dann behalte letzten Zustand
            If Letzterzustand = "Links" Then
                Portb = &B00000100
            End If

            If Letzterzustand = "Rechts" Then
                Portb = &B00000010
            End If

    End Select

    Debounce Pind.2 , 0 , Messeschwellwert                  'Gehe zu Messeschwellwert wenn PinD2= 1

Loop

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, das Programm haste mit deinem Assemblercode noch nicht ganz 
getroffen ;-)
Es fehlt noch die Behandlung für den Fall, dass sich nichts ändert.
Ohne diesen wäre ein Statusspeicher nämlich überhaupt nicht nötig 
gewesen, deshalb mein Ansatz.
Du willst ner Linie hinterher, oder?

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Es fehlt noch die Behandlung für den Fall, dass sich nichts ändert.

wenn sich nichts ändert, wie meinst du das denn?
meinst du jetzt den letzten Fall case Zustand = 0b00000000
wenn ja, dann brauch ich diesen nicht, denn ohne abfrage ändert sich 
auch nicht am letzten Zustand, theoretisch könnt eich den weglassen

>Du willst ner Linie hinterher, oder?
das ist richtig, und das Bascom programm funktioniert, jedoch habe ich 
einwenig probleme mit assembler, uch mein das programm funktioniert so 
aus irgendeinem grund noch nicht, aber deshalb ja diese Fragen

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>weil, wenn ich die Marke gleich nach dem Vergleich aufschreibe, er dann
>so oder so hineinspringt, denn wenn die bedingung nicht eintrifft,dann
>macht er weiter im coding, es wäre natürlich viel schöner.

Dann mach die Bedingung passend.

Der nachfolgende Code ist ohne Gewähr:
;*****************************Hauptprogramm************************************
Hauptprogramm:
rcall  ADC_Kanal0
rcall    StartADC
        in Messergebnisleft, ADCH
        cp Messergebnisleft, Schwellwertleft
        brlo MssungZW05

MessungZW05:                        ;LINIENERKENNUNG linker LDR
        cp Messergebnisleft, Linksaus
        brshlo MessungZW1
       cbr Linienerkennung, 1

MessungZW1: 

rcall  ADC_Kanal1
rcall    StartADC
        in Messergebnismiddle, ADCH
        cp Messergebnismiddle, Schwellwertmiddle
        brlo MessungZW15
        sbr Linienerkennung, 2

MessungZW15:                        ;LINIENERKENNUNG mittlerer LDR
        cp Messergebnismiddle, Mitteaus
        brsh MessungZW2
        cbr Linienerkennung, 2

MessungZW2:

rcall  ADC_Kanal2
rcall    StartADC
        in Messergebnisright, ADCH
        cp Messergebnisright, Schwellwertright
        brlo MessungZW25
        sbr Linienerkennung, 4

MessungZW25:                        ;LINIENERKENNUNG rechter LDR
        cp Messergebnisright, Rechtsaus
        brsh MessungZW3
        cbr Linienerkennung, 4
         
MessungZW3:
;#######Motoransteuerung##########
      cpi Linienerkennung, 0b00000001
      sbi PORTB, 2
      cbi PORTB, 1
MotorZW:
      cpi Linienerkennung, 0b00000010
      sbi PORTB, 2
      sbi PORTB, 1
MotorZW2:
      cpi Linienerkennung, 0b00000100
      cbi PORTB, 2
      sbi PORTB, 1
MotorZW3:
;#################################
    sbis PIND, 2        ;Überprüfe PIND.0
    rcall Messeschwellwert     ;Wenn PIND.0 = 0 (Taster betätigt)--> Messung
rjmp Hauptprogramm          ;ansosnten wieder von vorne
;********************************************************************************

MfG Spess

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
MessungZW05:                        ;LINIENERKENNUNG linker LDR
        cp Messergebnisleft, Linksaus
        brshlo MessungZW1
        sbr Linienerkennung, 1  !!! Das hat noch gefehlt

MfG Spess

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Hauptprogramm:
> rcall  ADC_Kanal0
> rcall    StartADC
>         in Messergebnisleft, ADCH
>         cp Messergebnisleft, Schwellwertleft
>         brlo MssungZW05
>
> MessungZW05:                        ;LINIENERKENNUNG linker LDR
>         cp Messergebnisleft, Linksaus
>         brshlo MessungZW1
>        cbr Linienerkennung, 1

Das Problem hierbei ist, dass wenn die Bedingung eintrifft oder auch 
nicht er bei der Marke MessungZW05 weitermacht
habe ich neulich getestet, und deswegen die zusätzlichen Rücksprünge

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Das Problem hierbei ist, dass wenn die Bedingung eintrifft oder auch
>nicht er bei der Marke MessungZW05 weitermacht
>habe ich neulich getestet, und deswegen die zusätzlichen Rücksprünge

Bei dir doch auch. Du solltest aber beachten, das ich brsh und brlo 
vertauscht habe.

MfG Spess

P.S. Beachte meine Korrektur.

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Bei dir doch auch.

nein, denn bei mir springt er bei eintreffen des Ereignisses auf die 
richtige Marke und anschließend wieder zur richtigen Stelle zurück, und 
bei nicht eintreffen macht er einfach weiter im Programmcode und lasst 
den Sprung weg

>Du solltest aber beachten, das ich brsh und brlo
>vertauscht habe.
ok, du kommst aber trotzdem nicht drum herum, denn in deinem Fall hast 
du keine Verzweigung mehr, denn du machst es so und so durch

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Dein Code:

>        cp Messergebnisleft, Schwellwertleft
>        brsh LinksGroesser
>MessungZW05:                        ;LINIENERKENNUNG linker LDR

>LinksGroesser:
>  sbr Linienerkennung, 1
>rjmp MessungZW05

Du landest in jedem Fall bei 'MessungZW05'

Mein Code:

>        cp Messergebnisleft, Schwellwertleft
>        brlo MssungZW05
>        sbr Linienerkennung, 1
>MessungZW05:                        ;LINIENERKENNUNG linker LDR

Ich lande auch immer bei 'MessungZW05'. Nur ohne Umwege.

MfG Spess

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Ich lande auch immer bei 'MessungZW05'. Nur ohne Umwege.

es geht hier nicht um ZW05, denn das ist nur eine Hilfsmarke

es ging mir um sbr Linienerkennung, aber ich sehe grad, dass du das doch 
umangen hast. Deine Methode ist sicher besser, aber ich möchte jetzt mal 
wissen wieso meins nicht hinhaut, denn im endeffekt laufts ja aufs selbe 
hinaus oder nicht?

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht malst du mal ein Flussdiagramm, damit klar wird, was wo 
angesprungen werden muss.
Hilft ungemein weeiter ;-)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>aber ich möchte jetzt mal wissen wieso meins nicht hinhaut, denn im
>endeffekt laufts ja aufs selbe hinaus oder nicht?...

Wenn ich mich nicht vertan habe, ja.
Ich habe dein Programm nicht auf die logische Richtigkeit überprüft. Was 
geht denn nicht?

MfG Spess

Autor: Andy11 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Wenn ich mich nicht vertan habe, ja.
> Ich habe dein Programm nicht auf die logische Richtigkeit überprüft. Was
> geht denn nicht?

tja nun jetzt weiß ich halt wieder nicht ob ich das ganze Programm 
posten soll oder nicht, großteils wurde das Programm schon teilweise im 
FOrum korriegiert, also Problem ist halt, dass er bei pind = 1 (siehe 
Abfrage unten) er die Messungen macht, das nehme ich jedenfalls an, denn 
er simbolisiert die LEDs und wenn die Messung fertig ist, dann tut sich 
nichts mehr, ich hoffe das coding ist ausreichend auskommentiert:

;**********************************Header**************************************
;* Projektname:  Roboter-Linienverfolgung                    *
;* Name des Erstellers: Shamoon Andy                      *
;* Zuletzt aktualisiert: 7.4.2010                        *
;* Beschreibung: Ein ROboter, der einer ca1,5-2cm breiten Linie nachfaährt    *                                      
;******************************************************************************


;*****************************Initialisierungen********************************
.include "m8def.inc" ;Definitionsdatei des Mega8

;Stackpointer-init***********
  ldi r16, High(Ramend)
  out SPH, r16

  ldi r16, Low(Ramend)
  out SPL, r16

HH:
  


RJMP HH

;ADC-init***********
  ldi r16, 0x20    ;Externe Referenz, Ergebnis linksbündig, Kanal 0 0b00100000
  out ADMUX, r16    ;Ausgabe

  ldi r16, 0x87    ;Enable ADC, Prescaler = 16  
  out ADCSRA, r16    ;Ausgabe


;*************************Variablendeklarationen*******************************
.def Messergebnisleft = r16
.def Messergebnisright = r17
.def Messergebnismiddle = r18

.def Schwellwertleft = r19
.def Schwellwertmiddle = r20
.def Schwellwertright = r21

.def Linksaus = r22
.def Mitteaus = r23
.def Rechtsaus = r24

.def Linienerkennung = r29

;*****************************Ein-Ausgänge*************************************
  sbi DDRB, 1    ;PORTB.1 als Ausgabeport
  sbi DDRB, 2    ;PORTB.2 als Ausgabeport

  cbi DDRD, 2    ;PORTD.2 als Eingabeport
  sbi PORTD, 2  ;Pullups aktivieren

;******************************************************************************
;Lese Werte von vorheriger Messung aus und speichere diese in 
;die Schwellwerte rein
  
  ;Lese SchwellwertLeft aus------------------------------------------------
  ldi ZL, 1  ;niederwertigen Bits laden, lese Adresse 1 aus
  ldi ZH, 0   ;unteres Byte des MessergebnisERAMleft
  rcall Read_EEPROM
  in Schwellwertleft, EEDR      ;Daten aus EPROM in Variable laden
  ;------------------------------------------------------------------------
  ;Lese SchwellwertMiddle aus----------------------------------------------
  ldi ZL, 2  ;niederwertigen Bits laden, lese Adresse 2 aus
  ldi ZH, 0   ;unteres Byte des MessergebnisERAMleft
  rcall Read_EEPROM
  in Schwellwertmiddle, EEDR      ;Daten aus EPROM in Variable laden
  ;-------------------------------------------------------------------------
  ;Lese SchwellwertRechts aus----------------------------------------------
  ldi ZL, 3  ;niederwertigen Bits laden, lese Adresse 3 aus
  ldi ZH, 0   ;unteres Byte des MessergebnisERAMleft
  rcall Read_EEPROM
  in Schwellwertright, EEDR      ;Daten aus EPROM in Variable laden
  ;-------------------------------------------------------------------------


  ;Lese Linksaus aus--------------------------------------------------------
  ldi ZL, 4      ;niederwertigen Bits laden, lese Adresse 4 aus
  ldi ZH, 0    ;Null für höhere Bits
  rcall Read_EEPROM
  in Linksaus, EEDR          ;Daten aus EPROM in Variable laden
  ;-------------------------------------------------------------------------
  ;Lese Mitteaus aus--------------------------------------------------------
  ldi ZL, 5      ;niederwertigen Bits laden, lese Adresse 5 aus
  ldi ZH, 0    ;Null für höhere Bits
  rcall Read_EEPROM
  in Mitteaus, EEDR          ;Daten aus EPROM in Variable laden
  ;-------------------------------------------------------------------------
  ;Lese Rechtsaus aus----------------------------------------------
  ldi ZL, 6    ;niederwertigen Bits laden, lese Adresse 6 aus
  ldi ZH, 0    ;Null für höhere Bits
  rcall Read_EEPROM
  in Rechtsaus, EEDR          ;Daten aus EPROM in Variable laden
  ;-------------------------------------------------------------------------
  
;*****************************Hauptprogramm************************************
Hauptprogramm:
rcall  ADC_Kanal0
rcall    StartADC
        in Messergebnisleft, ADCH
        cp Messergebnisleft, Schwellwertleft
        brsh LinksGroesser
MessungZW05:                        ;LINIENERKENNUNG linker LDR
        cp Messergebnisleft, Linksaus
        brlo LinksKleiner
MessungZW1: 

rcall  ADC_Kanal1
rcall    StartADC
        in Messergebnismiddle, ADCH
        cp Messergebnismiddle, Schwellwertmiddle
        brsh MitteGroesser
MessungZW15:                        ;LINIENERKENNUNG mittlerer LDR
        cp Messergebnismiddle, Mitteaus
        brlo MitteKleiner
MessungZW2:

rcall  ADC_Kanal2
rcall    StartADC
        in Messergebnisright, ADCH
        cp Messergebnisright, Schwellwertright
        brsh RechtsGroesser
MessungZW25:                        ;LINIENERKENNUNG rechter LDR
        cp Messergebnisright, Rechtsaus
        brlo RechtsKleiner
          
MessungZW3:

;#######Motoransteuerung##########
      cpi Linienerkennung, 0b00000001
      breq MotorLinks
MotorZW:
      cpi Linienerkennung, 0b00000010
      breq MotorMitte
MotorZW2:
      cpi Linienerkennung, 0b00000100
      breq MotorRechts
MotorZW3:
;#################################


    sbis PIND, 2        ;Überprüfe PIND.0
    rcall Messeschwellwert     ;Wenn PIND.0 = 0 (Taster betätigt)--> Messung
rjmp Hauptprogramm          ;ansosnten wieder von vorne
;*********************************************************************************

;Motoren setzen####################################
MotorLinks:
  sbi PORTB, 2
  cbi PORTB, 1
rjmp MotorZW

MotorMitte:
  sbi PORTB, 2
  sbi PORTB, 1
rjmp MotorZW2

MotorRechts:
  cbi PORTB, 2
  sbi PORTB, 1
rjmp MotorZW3
;##################################################

;Setze Bits in Byte für die Linienerkennung########
LinksGroesser:
  sbr Linienerkennung, 1  
rjmp MessungZW05

LinksKleiner:
  cbr Linienerkennung, 1
rjmp MessungZW1


MitteGroesser:
  sbr Linienerkennung, 2
rjmp MessungZW15
  
MitteKleiner:
  cbr Linienerkennung, 2
rjmp MessungZW2


RechtsGroesser:
  sbr Linienerkennung, 4
rjmp MessungZW25

RechtsKleiner:
  cbr Linienerkennung, 4
rjmp MessungZW3

;##################################################

;***********************Unterprogramme/Funktionen******************************
Messeschwellwert:
rcall  EnableADC
;***************************************
rcall  ADC_Kanal0
rcall    StartADC
        in r25, ADCH

rcall  ADC_Kanal1
rcall    StartADC
        in r26, ADCH      ;Messe alle Werte der LDRs bei weißem Untergrund

rcall  ADC_Kanal2
rcall    StartADC
        in r27, ADCH
;***************************************

rcall wait1        ;WARTE 1 SEK

sbi PORTB, 1

rcall wait3        ;WARTE 3 SEK

cbi PORTB, 1

;Linker Schwellwert--------------
rcall  ADC_Kanal0
rcall    StartADC
        push r28
        clr r28
        in Messergebnisleft, ADCH    ;Messe Wert auf schwarz vom linken LDR
        add r25, Messergebnisleft    ;Summe von Wert auf Schwarz und Wert auf Weiß
        in r28, SREG
        sbrc r28, 0
        ldi r28, 0b10000000        
        mov r30, r25          ;Lade Divident in Divisionsregister r30
        ldi r31, 2            ;Lade Divisor in Divisionsregister r31
rcall      division            ;dividiere die zwei zahlen
        mov Schwellwertleft, Ergebnis  ;bringe errechneten Schwellwert in definierte Variable(Register)
        add Schwellwertleft, r28
        push Ergebnis          ;sichere Ergebnis
          
          mov r25, Schwellwertleft    ;da r25 in Write EEPROM zum schreiben der Variable 
                          ;verwendet wird muss das Register kopiert werden  
          ldi ZH, 0             ;niederwertige Bit der EEPROM Adresse = 0
          ldi ZL, 1            ;schreibe EEPROM an adresse 1
rcall        Write_EEPROM          ;schreibe Wert in EEPROM
        
        pop Ergebnis          ;stelle ergebnis wieder her        
        subi Ergebnis, 5        ;Ausschaltschwelle (Schmitttriggerfunktion)
        mov Linksaus, Ergebnis      ;Lade es in fixen SPeicher
          
          mov r25, Linksaus        ;da r25 in Write EEPROM zum schreiben der Variable 
                          ;verwendet wird muss das Register kopiert werden  
          ldi ZH, 0             ;niederwertige Bit der EEPROM Adresse = 0
          ldi ZL, 4            ;schreibe EEPROM an adresse 1
rcall        Write_EEPROM          ;schreibe Wert in EEPROM  
        pop r28
rcall wait1   
;--------------------------------

sbi PORTB, 1
sbi PORTB, 2

rcall wait3

cbi PORTB, 1
cbi PORTB, 2

;Mittlerer Schwellwert-----------
rcall  ADC_Kanal1
rcall    StartADC
        push r28
        clr r28
        in Messergebnismiddle, ADCH    ;Messe Wert auf schwarz vom mittleren LDR
        add r26, Messergebnismiddle    ;Summe von Wert auf Schwarz und Wert auf Weiß
        in r28, SREG
        sbrc r28, 0
        ldi r28, 0b10000000  
        mov r30, r26          ;Lade Divident in Divisionsregister r30
        ldi r31, 2            ;Lade Divisor in Divisionsregister r31
rcall      division            ;dividiere die zwei zahlen
        mov Schwellwertmiddle, Ergebnis  ;bringe errechneten Schwellwert in definierte Variable(Register)  
         add Schwellwertmiddle, r28
        push Ergebnis          ;sichere Ergebnis
          
          mov r25, Schwellwertmiddle    ;da r25 in Write EEPROM zum schreiben der Variable 
                          ;verwendet wird muss das Register kopiert werden  
          ldi ZH, 0             ;niederwertige Bit der EEPROM Adresse = 0
          ldi ZL, 2            ;schreibe EEPROM an adresse 1
rcall        Write_EEPROM          ;schreibe Wert in EEPROM
        
        pop Ergebnis          ;stelle ergebnis wieder her  
        subi Ergebnis, 5        ;Ausschaltschwelle (Schmitttriggerfunktion)
        mov Mitteaus, Ergebnis      ;Lade es in fixen SPeicher
        
          mov r25, Mitteaus        ;da r25 in Write EEPROM zum schreiben der Variable 
                          ;verwendet wird muss das Register kopiert werden  
          ldi ZH, 0             ;niederwertige Bit der EEPROM Adresse = 0
          ldi ZL, 5            ;schreibe EEPROM an adresse 1
rcall        Write_EEPROM          ;schreibe Wert in EEPROM  
        pop r28
rcall wait1        
;--------------------------------

sbi PORTB, 2

rcall wait3

cbi PORTB, 2

;Rechter Schwellwert-------------
rcall  ADC_Kanal2
rcall    StartADC
        push r28
        clr r28
        in Messergebnisright, ADCH    ;Messe Wert auf schwarz vom rechten LDR
        add r27, Messergebnisright    ;Summe von Wert auf Schwarz und Wert auf Weiß
        in r28, SREG
        sbrc r28, 0
        ldi r28, 0b10000000
        mov r30, r27          ;Lade Divident in Divisionsregister r30
        ldi r31, 2            ;Lade Divisor in Divisionsregister r31
rcall      division            ;dividiere die zwei zahlen
        mov Schwellwertright, Ergebnis  ;bringe errechneten Schwellwert in definierte Variable(Register)  
        add Schwellwertright, r28
        push Ergebnis          ;sichere Ergebnis
          
          mov r25, Schwellwertright    ;da r25 in Write EEPROM zum schreiben der Variable 
                          ;verwendet wird muss das Register kopiert werden  
          ldi ZH, 0             ;niederwertige Bit der EEPROM Adresse = 0
          ldi ZL, 3            ;schreibe EEPROM an adresse 1
rcall        Write_EEPROM          ;schreibe Wert in EEPROM
        
        pop Ergebnis    
        subi Ergebnis, 5        ;Ausschaltschwelle (Schmitttriggerfunktion)
        mov Rechtsaus, Ergebnis    ;Lade es in fixen SPeicher
        
          mov r25, Rechtsaus        ;da r25 in Write EEPROM zum schreiben der Variable 
                          ;verwendet wird muss das Register kopiert werden  
          ldi ZH, 0             ;niederwertige Bit der EEPROM Adresse = 0
          ldi ZL, 6            ;schreibe EEPROM an adresse 1
rcall        Write_EEPROM          ;schreibe Wert in EEPROM    
        pop r28
rcall wait1           
;--------------------------------

rcall  DisableADC
ret
;*************************************
;*************************************


;################################################################################
.include "Division8Bit+Rest.asm"   ;8 Bit division    //call division
;.include "WaitCA1s.asm"        ;Warte ca 1s ab    //call wait
;.include "Stack_init.asm"      ;Stackinitialisieung//call Stack_init
;.include "ADC_init.asm"        ;ADCinitialisieung  //call ADC_init
.include "EnableADC.asm"      ;ADC erlauben    //call EnableADC
.include "DisableADC.asm"      ;ADC sperren    //call DisableADC
.include "StartADC.asm"        ;Starte Messung    //call StartADC
;.include "EndADC.asm"        ;Stoppe Messung    //call EndADC      
.include "ADC_Kanal0.asm"      ;Wechsel zu Kanal 0 //call ADC_Kanal0
.include "ADC_Kanal1.asm"      ;Wechsel zu Kanal 1 //call ADC_Kanal1
.include "ADC_Kanal2.asm"      ;Wechsel zu Kanal 2 //call ADC_Kanal2
;.include "ADC_Kanal3.asm"      ;Wechsel zu Kanal 3 //call ADC_Kanal3
;.include "ADC_Kanal4.asm"      ;Wechsel zu Kanal 4 //call ADC_Kanal4
;.include "ADC_Kanal5.asm"      ;Wechsel zu Kanal 5 //call ADC_Kanal5
;.include "ADC_Kanal6.asm"      ;Wechsel zu Kanal 6 //call ADC_Kanal6
;.include "ADC_Kanal7.asm"      ;Wechsel zu Kanal 7 //call ADC_Kanal7
;.include "PRESCALER=2.asm"      ;PSECALER einstellung für ADC
;.include "PRESCALER=8.asm"      ;PSECALER einstellung für ADC
;.include "PRESCALER=32.asm"    ;PSECALER einstellung für ADC
;.include "PRESCALER=128.asm"    ;PSECALER einstellung für ADC
.include "wait1.asm"
.include "wait3.asm"
.include "ReadEEPROM.asm"      ;        //call Read_EEPROM
.include "WriteEEPROM.asm"      ;        //call Write_EEPROM
;################################################################################




Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Das muss ich mir erst mal in Ruhe zu Gemüte führen. Allerdings ein 
erzeugt ein erster Überblick gesträubte Nackenhaare.

MfG Spess

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Das muss ich mir erst mal in Ruhe zu Gemüte führen. Allerdings ein
> erzeugt ein erster Überblick gesträubte Nackenhaare.

ok, das
HH:



RJMP HH

vergiss mal, das hab ich nur wegen vorhin reingemacht wegen den Sprüngen

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andy11 schrieb:
> spess53 schrieb:
>> Das muss ich mir erst mal in Ruhe zu Gemüte führen. Allerdings ein
>> erzeugt ein erster Überblick gesträubte Nackenhaare.
>
> ok, das
> HH:
>
>
>
> RJMP HH
>
> vergiss mal, das hab ich nur wegen vorhin reingemacht wegen den Sprüngen

Das ist es nicht, es ist Dein Programmierstil. Dein Spaghetticode ist 
extrem schwer nachvollziehbar. Es ist zuviel Hinundherspringerei zu 
Sprungzielen, die auch noch in anderen Dateien liegen. Das ist unnötig 
unübersichtlich. Und effizient ist Deine Vorgehensweise auch nicht, Du 
hast zuviel Wartezeit auf den ADC. Wenn man mehrere Kanäle messen muss, 
dann lohnt es sich, dies in einer Statemachine im Hintergrund zu tun. 
Klar, als Anfänger kann man das noch nicht, aber als Anfänger beginnt 
man auch nicht gleich mir einer Robotersteuerung mit Linienverfolgung. 
Ehe man das macht, erarbeitet man sich an kleineren Basteleien das 
nötige Knowhow (Statemachine, Timer-Interrupt, ...).

Dazu kommt noch die grauenhafte Formatierung (Einrückung). Hier mal ein 
Beispiel, wie man einen ASM-Quelltext formatieren kann damit er halbwegs 
lesbar bleibt:
http://www.mikrocontroller.net/attachment/67466/IR...
Noch ein Tip zur Formatierung: Solltest Du Interesse daran haben, dass 
die Formatierung auch außerhalb von AVR-Studio korrekt angezeigt wird, 
dann könntest Du in den Einstellungen zum Editor mal die Tabs durch 
Spaces ersetzen lassen. Das macht den Quelltext zwar geringfügig größer, 
wird dann aber von jedem Textbetrachterprogramm korrekt dargestellt.

Ich weiß nicht, wo Du Dir diesen Programmierstil abgeschaut hast, mir 
ist das jedenfalls zu unübersichtlich. Deshalb habe ich mich auch bisher 
aus diesem Thread herausgehalten.

Mir geht es nicht darum, Dich "niederzumachen". Aber wenn es Dir keiner 
sagt, dann kannst Du es ja nicht ändern...

...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hannes Lux schrieb:

> Mir geht es nicht darum, Dich "niederzumachen". Aber wenn es Dir keiner
> sagt, dann kannst Du es ja nicht ändern...

Puuh, bin ich froh.
Ich hab mich zurückgehalten, damit ich nicht schon wieder als Nörgler 
dastehe.


Meines Erachtens wurde zuviel Wert darauf gelegt, den BASCOM Code 
möglichst 1:1 zu übernehmen (in dem Fall frag ich mich dann, warum 
bleibt man nicht gleich bei BASCOM, das könnte man wenigstens lesen), 
anstatt sich die Idee des Codes, das Prinzip, herauszuextrahieren und 
mit dieser Idee im Hinterkopf ein Assemblerprogramm zu konzipieren. Ich 
sag absichtlich 'konzipieren', denn wenn man einfach drauflos 
programmiert, dann kommt genau sowas raus.

Zum Thema 100-tausend Files mit 'Funktionen' die aus 3 Anweisungen 
bestehen, sag ich nichts mehr, das wurde in einem anderen Thread schon 
angesprochen, dass das Murks ist. Nicht notwendigerweise die Funktion an 
sich, sondern das Auslagern in die vielen Files. Da findet man doch 
nichts mehr.

An den TO
Sieh dir auch an, wie Hannes kommentiert.
Einen Kommentar wie diesen hier
rcall        Write_EEPROM          ;schreibe Wert in EEPROM  
kannst du dir schenken. Ich nenn das gerne einen Alibi-Kommentar. Das da 
etwas ins EEPROM geschrieben wird, kann ich zur Not auch erraten, wenn 
ich mich frage, welche Funktionalität sich hinter einer Funktion 
'Write_EEPROM' verstecken wird. Man muss nicht Uri Geller heissen um das 
zu erraten. Kommentier lieber was im EEPROM wo abgelegt wird. Generell: 
Kommentiere das Warum und nicht das Wie. Ein Kommentar soll mir erzählen 
warum etwas passiert, welche Nebenbedingungen es gibt, was sich aus 
einer höheren Sichtweise gesehen an dieser Stelle abspielt. Wie das 
gemacht wird steht im Code.
Zum Teil laufen deine Kommentare schon in diese Richtung, aber die 
meisten sind von der ersten Sorte.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Hannes und Karl Heinz haben meine Meinung zu deinem Programm schon auf 
den Punkt gebracht. Erspart mir einige Schreiberei. Danke.

Ein paar Bemerkungen zu deinem Programm:

>;*************************Variablendeklarationen*********************** ********
>.def Messergebnisleft = r16
>.def Messergebnisright = r17
>.....
>.def Rechtsaus = r24
>.def Linienerkennung = r29

Was soll das in den Registern? Dein AVR hat Ram.


>;*****************************Hauptprogramm**************************** ********
>Hauptprogramm:
>rcall  ADC_Kanal0
>rcall    StartADC

Mach dir ein Unterprogramm das die AD-Wandlung macht. Übergabe des 
Kanals in
einem Register und Rückgabe des Wertes in einem/dem Register.

.....
>RechtsKleiner:
>  cbr Linienerkennung, 4
>rjmp MessungZW3
>;##################################################

Das hatten wir schon. (sinnloses herumgehüpfe)

>in Messergebnisleft, ADCH    ;Messe Wert auf schwarz vom linken LDR
>add r25, Messergebnisleft    ;Summe von Wert auf Schwarz und Wert auf Weiß

>in r28, SREG
>sbrc r28, 0

Das ist No go
Lesbar und auch noch kürzer:
         add r25, Messergebnisleft    ;Summe von Wert auf Schwarz und Wert auf Weiß
         brnc xyz
         ldi r28, 0b10000000        
xyz:     mov r30, r25

>ldi r28, 0b10000000

>mov r30, r25
>ldi r31, 2
>rcall division

Die Division kannst du dir sparen. Ein 'lsr r25' reicht.

>mov Schwellwertleft, Ergebnis
>add Schwellwertleft, r28

Bist du sicher, das du u.U. SREG addieren willst (->in r28, SREG) ?

>push Ergebnis

Ich habe nicht alle deine Threads komplett verfolgt, aber etliche 
Vorschläge kommen mir bekannt vor. Kann es sein, das du etwas 
beratungsresistent bist.

MfG Spess

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und um auch mal etwas Konkretes beizusteuern:
Schau dir mal diese Sequenz an
;#######Motoransteuerung##########
      cpi Linienerkennung, 0b00000001
      breq MotorLinks
MotorZW:
      cpi Linienerkennung, 0b00000010
      breq MotorMitte
MotorZW2:
      cpi Linienerkennung, 0b00000100
      breq MotorRechts
MotorZW3:
;#################################


    sbis PIND, 2        ;Überprüfe PIND.0
    rcall Messeschwellwert     ;Wenn PIND.0 = 0 (Taster betätigt)--> Messung
rjmp Hauptprogramm          ;ansosnten wieder von vorne
;*********************************************************************************

;Motoren setzen####################################
MotorLinks:
  sbi PORTB, 2
  cbi PORTB, 1
rjmp MotorZW

MotorMitte:
  sbi PORTB, 2
  sbi PORTB, 1
rjmp MotorZW2

MotorRechts:
  cbi PORTB, 2
  sbi PORTB, 1
rjmp MotorZW3

Wie ist das der Programmfluss?
Wenn Linienerkennung 0x01, 0x02, 0x04 ist, dann geht es einmal runter zu 
einem Label, da sind dann 2 Befehle und es wird wieder hochgesprungen.
Ziel der Sache ist es, dass diese Befehle nur dann ausgeführt werden, 
wenn eine bestimmte Bedinungung wahr ist.

Das kann man auch in der Logik umdrehen: Wenn die entsprechende Bedinung 
nicht wahr ist, dann werden ganz einfach die beiden Befehle 
übersprungen.
Das sieht dann so aus
;#######Motoransteuerung##########
      cpi   Linienerkennung, 0b00000001
      brne  MotorZW
      sbi   PORTB, 2         ; Motoren auf Links schalten
      cbi   PORTB, 1

MotorZW:
      cpi   Linienerkennung, 0b00000010
      brne  MotorZW2
      sbi   PORTB, 2         ; Motoren auf Mitte schalten
      sbi   PORTB, 1

MotorZW2:
      cpi   Linienerkennung, 0b00000100
      brne  MotorZW3
      cbi   PORTB, 2         ; Motoren auf Rechts schalten
      sbi   PORTB, 1

MotorZW3:
      sbis  PIND, 2             ;Überprüfe PIND.0
      rcall Messeschwellwert    ;Wenn PIND.0 = 0 (Taster betätigt)--> Messung
      rjmp  Hauptprogramm       ;ansosnten wieder von vorne
;*********************************************************************************

Die ganze Sequenz ist fast um die Hälfte kürzer geworden. Ausserdem muss 
man nicht mehr ständig auf und ab scrollen um zu sehen, was die Abfragen 
bei Linienerkennung überhaupt bewirken. Auf einer halben Bildschirmseite 
kann man mit '3 Augenbewegungen' sowohl die Bedingungen als auch die 
davon abhängige Operation überblicken. In der Logik hat sich nichts 
geändert, aber durch die Schreibweise hat alles an Klarheit gewonnen.


Warum wir auf solchen Dingen so dermassen rumreiten:
Weil ein gutes, möglichst fehlerfreies Programm auch immer eine Frage 
des Programmierstils ist. Programme die unübersichtlich sind, bei denen 
wie wild herumgespungen wird, es schwierig ist den Programmfluss zu 
verfolgen, sind tendenziell genau die Programme, bei denen laufend 
irgendwelche Fehler auftreten. Fehler die dann nicht dadurch behoben 
werden, dass man zunächst die Programmstruktur bereinigt, sondern 
dadurch, dass wieder irgendwo ein 'Heftpflaster' aufgeklebt wird, 
welches sich dann oft genug als neuer Quell von neuen Fehlern entpuppt. 
Man würde ja gerne sauber korrigieren aber in der Jump-Flut findet man 
die Stelle gar nicht, wo mein eigentlich ansetzen muss.

Programme hingegen, die eine saubere äussere Form haben, bei denen der 
Programmfluss im wesentlichen von oben nach unten verfläuft und nur in 
Ausnahmefällen kommt ab und zu ein Sprung vor (der dann meistens auch 
nicht sehr weit geht), das sind die Programme, die man im Kopf gut 
verfolgen kann, bei denen sich einem die dahintersteckende Logik 
förmlich aufdrängt und das sind auch die Programme, die meistens 
wesentlich weniger Probleme machen.

Ob Programme mmöglichst fehlerfrei sind oder nicht, ist nicht nur eine 
Frage der Logik, sondern auch oft eine Frage der äußeren Form und wie 
kompliziert ein Programm aufgebaut ist. Je verwickelter desto 
wahrscheinlicher ist es, das Problemstellen unentdeckt bleiben. Je 
geradliniger, desto besser sieht man Probleme.

Ein Programm in kleinere Blöcke zu zerteilen ist grundsätzlich eine gute 
Sache, keine Frage. Aber du hast es ganz einfach übertrieben. Deine 2 
Zeilen Unterprogramme ADC_Kanal0, ADC_Kanal1, ADC_Start und was da noch 
so alles kreucht und fleucht, verschleiern mehr als sie Klarheit ins 
Programm bringen. Man muss ständig rumscrollen (oder Files wechseln) um 
sich zu vergewissern ob und wenn ja welche Register verändert werden, ob 
sie ordnungsgemäss gesichert werden oder nicht, welche global 
verwendeten Register verändert werden, etc ...

Autor: Andy11 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ok, da es anscheinend wirklich unübersichtlich ist habe ich das ganze 
verbessert:
;**********************************Header**************************************
;* Projektname:  Roboter-Linienverfolgung                    *
;* Name des Erstellers: Shamoon Andy                      *
;* Zuletzt aktualisiert: 7.4.2010                        *
;* Beschreibung: Ein ROboter, der einer ca1,5-2cm breiten Linie nachfaährt    *                                      
;******************************************************************************


;*****************************Initialisierungen********************************
.include "m8def.inc" ;Definitionsdatei des Mega8

;Stackpointer-init***********
  ldi r16, High(Ramend)
  out SPH, r16

  ldi r16, Low(Ramend)
  out SPL, r16

;ADC-init***********
  sbi ADCSRA, ADEN  ;ADC erlauben
  cbi ADCSRA, ADPS0  
  sbi ADCSRA, ADPS1  
  sbi ADCSRA, ADPS2  ;PRESCALER 64 

;*************************Variablendeklarationen*******************************
.def Messergebnisleft = r16
.def Messergebnisright = r17
.def Messergebnismiddle = r18

.def Schwellwertleft = r19
.def Schwellwertmiddle = r20
.def Schwellwertright = r21

.def Linksaus = r22
.def Mitteaus = r23
.def Rechtsaus = r24

.def Linienerkennung = r29

;*****************************Ein-Ausgänge*************************************
  sbi DDRB, 1    ;PORTB.1 als Ausgabeport
  sbi DDRB, 2    ;PORTB.2 als Ausgabeport

  cbi DDRD, 2    ;PORTD.2 als Eingabeport
  sbi PORTD, 2  ;Pullups aktivieren

  
;*****************************Hauptprogramm************************************
Hauptprogramm:
clr Linienerkennung ;Virbereitung auf neue Messung

    
;TEIL1...................START.......................Messe aktuelle Werte der Linie aus
rcall  StartADConChanel0_8bit      
      in Messergebnisleft, ADCH
rcall  StartADConChanel1_8bit      
      in Messergebnismiddle, ADCH
rcall  StartADConChanel2_8bit      
      in Messergebnisright, ADCH    

;TEIL2...................START.......................Erstelle aktuelle Werte für Linienerkennung
    cp Messergebnisleft, Schwellwertleft  ;Vergleiche LDR links aktuell mit vorher ausgerechnetem
                        ;Schwellwert
    brlo FahreFort0                  
    ldi Linienerkennung, 0b00000100        ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
                        
FahreFort0:



    cp Messergebnismiddle, Schwellwertmiddle  ;Vergleiche LDR mitte aktuell mit vorher ausgerechnetem
                          ;Schwellwert
    brlo FahreFort1                  
    ldi Linienerkennung, 0b00000010        ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
                        
FahreFort1:                    ;wenn kleiner dann lass es auf Null
    


    cp Messergebnisright, Schwellwertright  ;Vergleiche LDR rechts aktuell mit vorher ausgerechnetem
                        ;Schwellwert
    brlo FahreFort2                  
    ldi Linienerkennung, 0b00000001        ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
                        
FahreFort2:                    ;wenn kleiner dann lass es auf Null  

;TEIL3...................START.......................Auswertung-->Motorsteuerung
    
    sbrc Linienerkennung, 2  
      ldi r28, 0b00000010    ;Motor = Rechts
      out PORTB, r28
    sbrc Linienerkennung, 1    
      ldi r28, 0b00000110    ;Motor = Beide
      out PORTB, r28
    sbrc Linienerkennung, 0    
      ldi r28, 0b00000100    ;Motor = Links
      out PORTB, r28
;TEIL4...................START.......................Falls neie Messung vorgesehen dann mache sie zuerst
    sbis PIND, 2        ;Überprüfe PIND.0
    rcall Messeschwellwert     ;Wenn PIND.0 = 0 (Taster betätigt)--> Messung
rjmp Hauptprogramm          ;ansosnten wieder von vorne
;*********************************************************************************



;***********************Unterprogramme/Funktionen******************************
Messeschwellwert:
rcall  StartADConChanel0_8bit      ;Messe linken LDR bei weißem Untergrund
      in r25, ADCH
rcall  StartADConChanel1_8bit      ;Messe mittleren LDR bei weißem Untergrund
      in r26, ADCH
rcall  StartADConChanel2_8bit      ;Messe rechten LDR bei weißem Untergrund
      in r27, ADCH
rcall Wait1
sbi PORTB,1
rcall Wait3
cbi PORTB, 1

  ;Linker Schwellwert--------------
  push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
  clr r28  ;lösche registerinhalt in r28 zur neuen Anwendung
  rcall  StartADConChanel0_8bit
        in Messergebnisleft, ADCH   ;Messe LDRleft bei schwarzem Untergrund
        add  r25, Messergebnisleft  ;Addiere Weißen Wert mit Schwarzen Wert
        BRCC RechneWeiter0;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
        ;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür 
        ;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
        ;ergibt den richtigen Schwellwert
        
        ldi r28, 128  ;wenn Carry 1 dann lade 128 in carry-register

  RechneWeiter0:        ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
        mov r16, r25  ;Den Dividenten ins Register der Division kopieren
                ;Diese Register ist als Messergebnisleft definiert
                ;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
        ldi r17, 2    ;Den Divisor ins Register der Division laden
                ;Dieses Register ist Messergebnismiddle, dass tört aber keinen
                ;da hier nicht verwendet
        rcall Division
                ;Ergebnis steht jetzt in Register Ergebnis (r30)

        add r28, Ergebnis  ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
                  ;bei verschiedenen Linienfarben unterschiedlich, kann es sein
                  ;dass es kleinere Spannungen auch geben kann, daher muss
                  ;ein möglicher Überlauf berücksichtigt werden
        
        ;Endergebnis steht jetzt in r28

        mov Schwellwertleft, r28  ;Kopiere den Schwellwert in definiertes Register
                      ;für diesen Wert
  rcall Wait1  
  pop r28    
    ;--------------------------------

sbi PORTB, 1
sbi PORTB, 2                                      
rcall Wait3
cbi PORTB, 1
cbi PORTB, 2

    ;Mittlerer Schwellwert-----------
  push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
  clr r28  ;lösche registerinhalt in r28 zur neuen Anwendung
  rcall  StartADConChanel1_8bit
        in Messergebnismiddle, ADCH   ;Messe LDRleft bei schwarzem Untergrund
        add  r26, Messergebnismiddle  ;Addiere Weißen Wert mit Schwarzen Wert
        BRCC RechneWeiter1;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
        ;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür 
        ;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
        ;ergibt den richtigen Schwellwert
        
        ldi r28, 128  ;wenn Carry 1 dann lade 128 in carry-register

  RechneWeiter1:        ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
        mov r16, r26  ;Den Dividenten ins Register der Division kopieren
                ;Diese Register ist als Messergebnisleft definiert
                ;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
        ldi r17, 2    ;Den Divisor ins Register der Division laden
                ;Dieses Register ist Messergebnismiddle, dass tört aber keinen
                ;da hier nicht verwendet
        rcall Division
                ;Ergebnis steht jetzt in Register Ergebnis (r30)

        add r28, Ergebnis  ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
                  ;bei verschiedenen Linienfarben unterschiedlich, kann es sein
                  ;dass es kleinere Spannungen auch geben kann, daher muss
                  ;ein möglicher Überlauf berücksichtigt werden
        
        ;Endergebnis steht jetzt in r28

        mov Schwellwertmiddle, r28  ;Kopiere den Schwellwert in definiertes Register
                      ;für diesen Wert
  rcall Wait1  
  pop r28    
    ;--------------------------------

sbi PORTB, 2 
rcall Wait3
cbi PORTB, 2

    ;Rechter Schwellwert-------------
   push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
  clr r28  ;lösche registerinhalt in r28 zur neuen Anwendung
  rcall  StartADConChanel2_8bit
        in Messergebnisright, ADCH   ;Messe LDRleft bei schwarzem Untergrund
        add  r27, Messergebnisright  ;Addiere Weißen Wert mit Schwarzen Wert
        BRCC RechneWeiter2;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
        ;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür 
        ;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
        ;ergibt den richtigen Schwellwert

        ldi r28, 128  ;wenn Carry 1 dann lade 128 in carry-register

  RechneWeiter2:        ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
        mov r16, r27  ;Den Dividenten ins Register der Division kopieren
                ;Diese Register ist als Messergebnisleft definiert
                ;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
        ldi r17, 2    ;Den Divisor ins Register der Division laden
                ;Dieses Register ist Messergebnismiddle, dass tört aber keinen
                ;da hier nicht verwendet
        rcall Division
                ;Ergebnis steht jetzt in Register Ergebnis (r30)

        add r28, Ergebnis  ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
                  ;bei verschiedenen Linienfarben unterschiedlich, kann es sein
                  ;dass es kleinere Spannungen auch geben kann, daher muss
                  ;ein möglicher Überlauf berücksichtigt werden
        
        ;Endergebnis steht jetzt in r28

        mov Schwellwertright, r28  ;Kopiere den Schwellwert in definiertes Register
                      ;für diesen Wert
  rcall Wait1  
  pop r28    
    ;--------------------------------

ret
;*************************************
;*************************************


;################################################################################
.include "Division8Bit+Rest.asm"   ;8 Bit division    //call division
.include "wait1.asm"
.include "wait3.asm"
.include "ReadEEPROM.asm"      ;        //call Read_EEPROM
.include "WriteEEPROM.asm"      ;        //call Write_EEPROM
.include "StartADConCHANEL0_8bit.asm"
.include "StartADConCHANEL1_8bit.asm"
.include "StartADConCHANEL2_8bit.asm"
;################################################################################

Autor: Andy11 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ok, da es anscheinend wirklich unübersichtlich ist habe ich das ganze 
verbessert:
;**********************************Header**************************************
;* Projektname:  Roboter-Linienverfolgung                    *
;* Name des Erstellers: Shamoon Andy                      *
;* Zuletzt aktualisiert: 7.4.2010                        *
;* Beschreibung: Ein ROboter, der einer ca1,5-2cm breiten Linie nachfaährt    *                                      
;******************************************************************************


;*****************************Initialisierungen********************************
.include "m8def.inc" ;Definitionsdatei des Mega8

;Stackpointer-init***********
  ldi r16, High(Ramend)
  out SPH, r16

  ldi r16, Low(Ramend)
  out SPL, r16

;ADC-init***********
  sbi ADCSRA, ADEN  ;ADC erlauben
  cbi ADCSRA, ADPS0  
  sbi ADCSRA, ADPS1  
  sbi ADCSRA, ADPS2  ;PRESCALER 64 

;*************************Variablendeklarationen*******************************
.def Messergebnisleft = r16
.def Messergebnisright = r17
.def Messergebnismiddle = r18

.def Schwellwertleft = r19
.def Schwellwertmiddle = r20
.def Schwellwertright = r21

.def Linksaus = r22
.def Mitteaus = r23
.def Rechtsaus = r24

.def Linienerkennung = r29

;*****************************Ein-Ausgänge*************************************
  sbi DDRB, 1    ;PORTB.1 als Ausgabeport
  sbi DDRB, 2    ;PORTB.2 als Ausgabeport

  cbi DDRD, 2    ;PORTD.2 als Eingabeport
  sbi PORTD, 2  ;Pullups aktivieren

  
;*****************************Hauptprogramm************************************
Hauptprogramm:
clr Linienerkennung ;Virbereitung auf neue Messung

    
;TEIL1...................START.......................Messe aktuelle Werte der Linie aus
rcall  StartADConChanel0_8bit      
      in Messergebnisleft, ADCH
rcall  StartADConChanel1_8bit      
      in Messergebnismiddle, ADCH
rcall  StartADConChanel2_8bit      
      in Messergebnisright, ADCH    

;TEIL2...................START.......................Erstelle aktuelle Werte für Linienerkennung
    cp Messergebnisleft, Schwellwertleft  ;Vergleiche LDR links aktuell mit vorher ausgerechnetem
                        ;Schwellwert
    brlo FahreFort0                  
    ldi Linienerkennung, 0b00000100        ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
                        
FahreFort0:



    cp Messergebnismiddle, Schwellwertmiddle  ;Vergleiche LDR mitte aktuell mit vorher ausgerechnetem
                          ;Schwellwert
    brlo FahreFort1                  
    ldi Linienerkennung, 0b00000010        ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
                        
FahreFort1:                    ;wenn kleiner dann lass es auf Null
    


    cp Messergebnisright, Schwellwertright  ;Vergleiche LDR rechts aktuell mit vorher ausgerechnetem
                        ;Schwellwert
    brlo FahreFort2                  
    ldi Linienerkennung, 0b00000001        ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
                        
FahreFort2:                    ;wenn kleiner dann lass es auf Null  

;TEIL3...................START.......................Auswertung-->Motorsteuerung
    
    sbrc Linienerkennung, 2  
      ldi r28, 0b00000010    ;Motor = Rechts
      out PORTB, r28
    sbrc Linienerkennung, 1    
      ldi r28, 0b00000110    ;Motor = Beide
      out PORTB, r28
    sbrc Linienerkennung, 0    
      ldi r28, 0b00000100    ;Motor = Links
      out PORTB, r28
;TEIL4...................START.......................Falls neie Messung vorgesehen dann mache sie zuerst
    sbis PIND, 2        ;Überprüfe PIND.0
    rcall Messeschwellwert     ;Wenn PIND.0 = 0 (Taster betätigt)--> Messung
rjmp Hauptprogramm          ;ansosnten wieder von vorne
;*********************************************************************************



;***********************Unterprogramme/Funktionen******************************
Messeschwellwert:
rcall  StartADConChanel0_8bit      ;Messe linken LDR bei weißem Untergrund
      in r25, ADCH
rcall  StartADConChanel1_8bit      ;Messe mittleren LDR bei weißem Untergrund
      in r26, ADCH
rcall  StartADConChanel2_8bit      ;Messe rechten LDR bei weißem Untergrund
      in r27, ADCH
rcall Wait1
sbi PORTB,1
rcall Wait3
cbi PORTB, 1

  ;Linker Schwellwert--------------
  push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
  clr r28  ;lösche registerinhalt in r28 zur neuen Anwendung
  rcall  StartADConChanel0_8bit
        in Messergebnisleft, ADCH   ;Messe LDRleft bei schwarzem Untergrund
        add  r25, Messergebnisleft  ;Addiere Weißen Wert mit Schwarzen Wert
        BRCC RechneWeiter0;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
        ;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür 
        ;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
        ;ergibt den richtigen Schwellwert
        
        ldi r28, 128  ;wenn Carry 1 dann lade 128 in carry-register

  RechneWeiter0:        ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
        mov r16, r25  ;Den Dividenten ins Register der Division kopieren
                ;Diese Register ist als Messergebnisleft definiert
                ;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
        ldi r17, 2    ;Den Divisor ins Register der Division laden
                ;Dieses Register ist Messergebnismiddle, dass tört aber keinen
                ;da hier nicht verwendet
        rcall Division
                ;Ergebnis steht jetzt in Register Ergebnis (r30)

        add r28, Ergebnis  ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
                  ;bei verschiedenen Linienfarben unterschiedlich, kann es sein
                  ;dass es kleinere Spannungen auch geben kann, daher muss
                  ;ein möglicher Überlauf berücksichtigt werden
        
        ;Endergebnis steht jetzt in r28

        mov Schwellwertleft, r28  ;Kopiere den Schwellwert in definiertes Register
                      ;für diesen Wert
  rcall Wait1  
  pop r28    
    ;--------------------------------

sbi PORTB, 1
sbi PORTB, 2                                      
rcall Wait3
cbi PORTB, 1
cbi PORTB, 2

    ;Mittlerer Schwellwert-----------
  push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
  clr r28  ;lösche registerinhalt in r28 zur neuen Anwendung
  rcall  StartADConChanel1_8bit
        in Messergebnismiddle, ADCH   ;Messe LDRleft bei schwarzem Untergrund
        add  r26, Messergebnismiddle  ;Addiere Weißen Wert mit Schwarzen Wert
        BRCC RechneWeiter1;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
        ;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür 
        ;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
        ;ergibt den richtigen Schwellwert
        
        ldi r28, 128  ;wenn Carry 1 dann lade 128 in carry-register

  RechneWeiter1:        ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
        mov r16, r26  ;Den Dividenten ins Register der Division kopieren
                ;Diese Register ist als Messergebnisleft definiert
                ;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
        ldi r17, 2    ;Den Divisor ins Register der Division laden
                ;Dieses Register ist Messergebnismiddle, dass tört aber keinen
                ;da hier nicht verwendet
        rcall Division
                ;Ergebnis steht jetzt in Register Ergebnis (r30)

        add r28, Ergebnis  ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
                  ;bei verschiedenen Linienfarben unterschiedlich, kann es sein
                  ;dass es kleinere Spannungen auch geben kann, daher muss
                  ;ein möglicher Überlauf berücksichtigt werden
        
        ;Endergebnis steht jetzt in r28

        mov Schwellwertmiddle, r28  ;Kopiere den Schwellwert in definiertes Register
                      ;für diesen Wert
  rcall Wait1  
  pop r28    
    ;--------------------------------

sbi PORTB, 2 
rcall Wait3
cbi PORTB, 2

    ;Rechter Schwellwert-------------
   push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
  clr r28  ;lösche registerinhalt in r28 zur neuen Anwendung
  rcall  StartADConChanel2_8bit
        in Messergebnisright, ADCH   ;Messe LDRleft bei schwarzem Untergrund
        add  r27, Messergebnisright  ;Addiere Weißen Wert mit Schwarzen Wert
        BRCC RechneWeiter2;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
        ;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür 
        ;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
        ;ergibt den richtigen Schwellwert

        ldi r28, 128  ;wenn Carry 1 dann lade 128 in carry-register

  RechneWeiter2:        ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
        mov r16, r27  ;Den Dividenten ins Register der Division kopieren
                ;Diese Register ist als Messergebnisleft definiert
                ;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
        ldi r17, 2    ;Den Divisor ins Register der Division laden
                ;Dieses Register ist Messergebnismiddle, dass tört aber keinen
                ;da hier nicht verwendet
        rcall Division
                ;Ergebnis steht jetzt in Register Ergebnis (r30)

        add r28, Ergebnis  ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
                  ;bei verschiedenen Linienfarben unterschiedlich, kann es sein
                  ;dass es kleinere Spannungen auch geben kann, daher muss
                  ;ein möglicher Überlauf berücksichtigt werden
        
        ;Endergebnis steht jetzt in r28

        mov Schwellwertright, r28  ;Kopiere den Schwellwert in definiertes Register
                      ;für diesen Wert
  rcall Wait1  
  pop r28    
    ;--------------------------------

ret
;*************************************
;*************************************


;################################################################################
.include "Division8Bit+Rest.asm"   ;8 Bit division    //call division
.include "wait1.asm"
.include "wait3.asm"
.include "ReadEEPROM.asm"      ;        //call Read_EEPROM
.include "WriteEEPROM.asm"      ;        //call Write_EEPROM
.include "StartADConCHANEL0_8bit.asm"
.include "StartADConCHANEL1_8bit.asm"
.include "StartADConCHANEL2_8bit.asm"
;################################################################################

Problem ist jetzt: Portb, 1 ist immer 1 nach der Messung

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sry fürs 2mal posten is mir unabsichtlich passiert

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andy11 schrieb:
> sry fürs 2mal posten is mir unabsichtlich passiert

Ich habe (nach Lesen des Anhangs) den Eindruck, Du operierst hier an 
etwas herum, was Du nicht selbst ausgedacht hast und was Du auch nicht 
verstehst.

Ich traue mich zu behaupten, dass ich AVR-ASM halbwegs verstehe, mir 
gelingt es aber nicht, den Sinn Deines Programms bzw. Deiner Algorithmen 
zu erschließen. Gut, ich könnte mir mehr Mühe geben, Dein Programm zu 
analysieren. Aber einige Dinge sind dermaßen unsinnig, dass sich in mir 
etwas wehrt, weiterzumachen.

Wenn Dir einer helfen soll, dann wirf das Programm weg und beginne von 
vorn. Aber nicht gleich mit Programmcode, sondern erstmal mit dem 
Konzept, also mit einer klaren und eindeutigen Beschreibung der zu 
erledigenden Aufgaben in deutscher Sprache. Es muss ja nicht unbedingt 
ein genormter Programmablaufplan oder Struktogramm sein, aber man sollte 
die Gesamtaufgabe und die Aufteilung in einzelne Jobs (und deren 
Abhängigkeiten voneinander) klar und unmissverständlich erkennen können.

Es schadet auch nicht, im ersten Schritt eine Auflistung zu machen, 
welche verschiedenen Aufgaben das Programm erledigen soll/muss.

...

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Wenn Dir einer helfen soll, dann wirf das Programm weg und beginne von
>vorn.

Dein Wort in Gottes Ohr.

MfG Spess

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hannes Lux schrieb:
> Ich habe (nach Lesen des Anhangs) den Eindruck, Du operierst hier an
> etwas herum, was Du nicht selbst ausgedacht hast und was Du auch nicht
> verstehst.

den Eindruck bekomme ich bei deinem Schreiben allerdings auch schon!!

>Ich traue mich zu behaupten, dass ich AVR-ASM halbwegs verstehe,
scheinbar tust du es nicht!


>Gut, ich könnte mir mehr Mühe geben, Dein Programm zu
>analysieren.

hättest du vielleicht zuerst machen müssen und dann posten

>Aber einige Dinge sind dermaßen unsinnig, dass sich in mir
>etwas wehrt, weiterzumachen.

argumente?!!?


>Wenn Dir einer helfen soll, dann wirf das Programm weg und beginne von
>vorn.
das habe ich mit dem vorigen schon gemacht: Das erkennt man auch daran 
das ich viel weniger code verbrauche und fast alle unterprogramme 
optimiert habe


>Aber nicht gleich mit Programmcode, sondern erstmal mit dem
>Konzept, also mit einer klaren und eindeutigen Beschreibung der zu
>erledigenden Aufgaben in deutscher Sprache.
Meiner MEinung nach ist das neue coding, das allerdings ich geschrieben 
habe, viel lesbarer als das ältere und mehr Kommentare passen erstens 
mal nicht rein und zweitens sind sie nicht notwendig.
Ich habe alles was spess gesagt hat gemacht ohne noch zu wissen, dass er 
es gesagt hat. Erst als ich es gepostet habe ist es mir aufgefallen.

>Es schadet auch nicht, im ersten Schritt eine Auflistung zu machen,
>welche verschiedenen Aufgaben das Programm erledigen soll/muss.
Wenn du meinst, dass ich das noch nicht gemacht habe, dann nehme ich das 
in Kenntniss

spess53 schrieb:
> Dein Wort in Gottes Ohr.
anscheinend hast du mein neues coding auch noch nicht wirklich 
durchgeschaut, daher die Bemerkung wahrscheinlich.

Ich erwarte mir jetzt sicher keine Antworten mehr, ich wollte lediglich 
manche Dinge klarstellen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.