mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zeichen einem String hinzufügen


Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich möchte solch einem String
.db "Tes",0 

ein zeichen hinzufügen (ans ende)


jemand ne idee wie ich das tun könnte...

Un zugleich wie ich solch einen String löschen kann?


liebe grüsse
Claudio

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR? Zur Laufzeit? Wo liegen die Daten? Wenn im Flash, dann nur über den 
Bootloader. Wenn im EEPROM, dann ganz normal über einen EEPROM-Zugriff.

Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR AtMega8

Sie liegen im EEPROM

Alles in ASM

Ich weiss dennoch nicht wie ein zeichen hinzufügen....

Autor: Winne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was du haben möchtest gab es früher bei einigen Basicinterpretern eine 
dynamische Stringverwaltung (z.B. http://www.berkhan.com/atari/feat5.htm 
). Dies ist bei C meines Wissens nicht üblich obgleich AVR ähnliches gut 
gebrauchen könnten.
Aber vielleicht hilft dir dieser Link weiter (http://www.glglgl.de/pub/)

Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun ist mein Projekt in Assembler

Gibts den dort auch was???

Danke für eure antworten

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein "String" der Form
.db "Tes", 0
ist identisch mit
.db 'T', 'e', 's', 0
Wenn der String jetzt nicht "Tes" sondern "Test" heißen soll, dann füge 
einfach das zusätzliche 't' hinten an. Zusätzlich muss dann noch der 
neue Nullterminator dahintergesetzt werden, damit die Software das 
String-Ende auch findet.

Wie man ins EEPROM ein Zeichen schreibt, steht in der Dokumentation bzw. 
im Tutorial.

Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wie mach ich das in Software form?

add String1, 'H' ?

wohl kaum oder?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du ein Programm geschrieben hast, das den angegebenen String 
verwendet, dann hast Du doch wohl irgendwo eine Funktion, um diesen 
String aus dem EEPROM auszulesen, oder? Und so ähnlich wie das Lesen 
geht auch das Schreiben, nur dass dabei noch ein paar zusätzliche Dinge 
in Sachen Timing beachtet werden müssen.
http://www.mikrocontroller.net/articles/AVR-Tutori...

Autor: Winne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In ASM hast du doch volle Gewalt über den gesamten SRAM Speicher und das 
EEPROM zur Laufzeit.

Der ASM bestimmt lediglich was im Flash dauerhaft angelegt wird. Sowie 
die Ausgangsposition in EEPROM und SRAM wenn du letztere dynamisch 
verwalten willst solltest, du die Prinzipien der dynamischen 
Speicherverwaltung studieren.

Und entsprechende Routinen in dein Programm intergrieren. Vielleicht hat 
sich ja schon mal jemand damit rumgeschlagen. eigentlich ist es relativ 
einfach ein zeiger zeigt auf die erste Variable. dort finden sich 
Status, Länge, Name,und Wert der Variablen sowie ein Zeiger zur nächsten 
Variablen. Enthält dieser eine Null so ist der folgende Speicher frei. 
Tja das Löschen von Variablen ist Leicht. Statusbit löschen... Speicher 
freigeben ist schwieriger. Zur Laufzeit müstest du Quasie den Speicher 
defragmentieren.

Naja ich wünsche Dir viel Spass damit.

Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm....

Also ich glaube wir reden hier aneinader vorbei...

Ich möchte einem string (unabhängig ob er sich im EEPRROM oder sonst wo 
befindet) ein zeichen anhängen

Genauer gesagt... was über den uart hinein kommt.
Aber um den EEPROM zu schonen, wollte ich erstmal quasi einen flüchtigen 
Virtuellen string anlegen und wenn der text fertig ist, den dann in das 
EEProm schreiben....

Ich hoffe ich wisst was ich meine....

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit .db kann man nur konstante Daten im Flash oder im EEPROM anlegen. 
Wenn Du einen String im SRAM verwursten willst, musst Du ihn vor der 
Benutzung aus dem Flash oder dem EEPROM dorthin kopieren. In dem Falle 
gilt aber ähnliches wie oben gesagt: Ein ASCII-String besteht aus einer 
Reihe von Zeichen und dem abschließenden Nullterminator. Wenn Du ein 
Zeichen hinzufügen willst, schreibst Du es an die aktuelle Position des 
Nullterminators und schreibst dahinter einen neuen Nullterminator.

Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber dieses "schreiben" meinst du ja von hand....

aber ich will das die Software das Empfangene zeichen (über uart) dem 
string hinzufügt....

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Claudio H. wrote:
> Aber dieses "schreiben" meinst du ja von hand....
Hä? Hat der µC eine Hand?

> aber ich will das die Software das Empfangene zeichen (über uart) dem
> string hinzufügt....
Das musst Du dem µC aber auch sagen. Und deshalb musst Du ein Programm 
schreiben, dass ein Zeichen über UART empfängt und an den bestehenden 
String anhängt...

Autor: GSP (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das schwierigste an strings anhaengen ist den Speicherplatz zu bekommen. 
Am einfachsten wenn der schon mal frei ist. Dann isses nur noch 
anhaengen und die laenge, resp terminierung anpassen. Da gibt es zwei 
moeglichkeiten. Bei den unpraktischen C- strings ist hinten eine Null. 
Die muss man dann auch neu schreiben. Bei den bequemeren Pascal strings 
ist das nullte byte die Laenge. Dann passt man die an.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@GSP:
Es geht hier um Assembler. Bring den OP nicht noch mehr durcheinander 
(v.a. mit Pascal usw.).

In Assembler hat man selbst die Kontrolle über seinen Speicher. Und die 
Strings in AVR-Assembler sind NICHT nullterminiert. Deshalb muss man 
da ja auch noch die Null explizit dranhängen.

Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist klar das ich ein programm schreiben muss....

Das will ich ja auch aber ich will wissen was ich schreiben muss, das er 
einem string ein zeichen anhängt....

Kann niemand ein beispiel machen, welches zb dem string1 den buchstaben 
h hinzufügt?

Autor: Zyniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich auch!!!

Kann mir bitte jemand zeigen, wie ich zu einer gegebenen Zahl eine 
andere Zahl addieren kann - am besten mit einem kleinen 
Beispielprogramm!

Ich komm da einfach nicht weiter. Auch mit Google findet man da gar 
nichts.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Claudio H. wrote:
> Mir ist klar das ich ein programm schreiben muss....
>
> Das will ich ja auch aber ich will wissen was ich schreiben muss, das er
> einem string ein zeichen anhängt....
>
> Kann niemand ein beispiel machen, welches zb dem string1 den buchstaben
> h hinzufügt?
Lies Dir das AVR-Tutorial sowie das, was ich oben schon geschrieben 
habe, durch und denk ein bisschen nach. Das musst Du mit den gegebenen 
Informationen hinbekommen.

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

Bewertung
0 lesenswert
nicht lesenswert
Claudio H. wrote:
> Mir ist klar das ich ein programm schreiben muss....
>
> Das will ich ja auch aber ich will wissen was ich schreiben muss, das er
> einem string ein zeichen anhängt....
>
> Kann niemand ein beispiel machen, welches zb dem string1 den buchstaben
> h hinzufügt?


In Assembler gibt es keine Strings.
Aber:
Du kannst dir im SRAM einen Speicherbereich reservieren lassen.
Und in diesen Speicherbereich werden dann die einzelnen Zeichen
gesammelt.

ZB. lässt du dir einen Speicherbereich für 20 Zeichen reservieren.
In einer anderen 'Variablen' im SRAM hast du zusätzlich noch
stehen, wieviele Bytes von diesen 20 Bytes tatsächlich für
deinen Text benutzt werden.
Wenn nun über die UAR ein neues Zeichen kommt, dann  musst du machen

* Zunächst mal den Zähler aus dem SRAM holen

* vergleichen ob der schon bei 20 steht
  wenn ja, dann passt logischerweise kein Zeichen mehr in deine
  20 reservierten Bytes hinein

* angenommen der Zähler ist noch nicht bei 20, dann

**  holst du dir die Startadresse des Speicherbereichs

**  zählst den Zähler dazu und kriegst somit
    die Adresse im Speicher, an der du das neue Zeichen ablegen kannst

**  da du jetzt die Speicheradresse hast, speicherst du das Zeichen
    von der UART ganz einfach dort ab

**  erhöhst den Zähler um 1

**  und speicherst den neuen Zählerstand wieder an seine Adresse
    im SRAM zurück

Und damit ist dein 'String' im SRAM um 1 Zeichen länger geworden.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
char text[100] = "Tes";

text[3] = 't';
text[4] = 0;

schon ist text = "Test"

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es sollte dann kein Problem sein, dies in ASM zu übersetzen.

Autor: GSP (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider ist das ein C Beispiel. In ASM geht das anders. Ich mach's mal 
mit meinen Pascal Strings.

.DSEG

mystring:    .byte 20   ;reserviere 20 bytes

.CSEG

    SetYPtr  mystring   ; ein makro : ylo=lo(mystring) yhi=hi(mystring)
    ldi      R16,Y+     ; die laenge ueberspringen
    ldi      R17,'T'
    st       Y+,R17
    ldi      R17,'e'
    st       Y+,R17
    ldi      R17,'s'
    st       Y+,R17
    ldi      R17,'t'
    st       Y+,R17
    SetYPtr  mystring   ; laenge anpassen
    ldi      R17,4
    st       Y,R17

Das war fuer das RAM. Fuer's EEPROM muss man das EEPROM ansprechen.

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

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:

> ZB. lässt du dir einen Speicherbereich für 20 Zeichen reservieren.
> In einer anderen 'Variablen' im SRAM hast du zusätzlich noch
> stehen, wieviele Bytes von diesen 20 Bytes tatsächlich für
> deinen Text benutzt werden.

Ich möchte noch hinzufügen, dass das eine Möglichkeit ist
wie man Strings im Speicher halten kann.

Eine andere Möglichkeit besteht darin, dass man ein spezielles
Zeichen benutzt um das Ende des Strings zu markieren (C benutzt
zb. dieses Verfahren).

In diesem Fall gibt es den Zähler nicht mehr, dafür muss man
allerdings beim anfügen eines Zeichens vom Start des Speicher-
bereichs beginnend nach diesem Zeichen suchen um die Stelle
zu finden, wo das neue Zeichen gespeichert werden muss.
Dahinter kommt dann wieder dieses spezielle Zeichen um
das neue Ende des nun erweiterten Strings zu markieren.

Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke für eure antworten....

Mit diesen tipps werd ichs bestimmt hinkriegen...

grüsschen
Claudio

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

Bewertung
0 lesenswert
nicht lesenswert
Studier das mal
.include "m8def.inc"

.def   zero = r1            ; R1 wird immer eine 0 enthalten
.def   temp = r16
.def   temp1 = r17

.org 0x0000
            rjmp    main
 
main:
           ldi     temp, LOW(RAMEND)
           out     SPL, temp
           ldi     temp, HIGH(RAMEND)
           out     SPH, temp

   ;
   ; den String initialisieren, indem der Zeichenzaehler auf 0 gesetzt wird
   ;
           ldi     temp, 0
           mov     zero, temp
           sts     Str1Count, zero

           ldi     temp, 'T'
           rcall   addChar

           ldi     temp, 'e'
           rcall   addChar

           ldi     temp, 's'
           rcall   addChar

           ldi     temp, 't'
           rcall   addChar

finish:    rjmp    finish

;
; Fügt ein Zeichen zum String Str1 (Str1Count, Str1Bytes) hinzu
addChar:
           lds     temp1, Str1Count       ; Zeichenzaehler holen
           cpi     temp1, 20              ; passt noch was rein?
           brne    addChar1               ; ja!
           ret                            ; nein!

addChar1:  ldi     ZL, LOW( Str1Bytes )   ; Startadresse des 'Strings'
           ldi     ZH, HIGH( Str1Bytes )

           add     ZL, temp1              ; Zaehler dazuzaehlen ->
           adc     ZH, zero               ; dort muss das neue Zeichen
                                          ; gespeichert werden

           st      Z, temp                ; das Zeichen jetzt speichern

           inc     temp1                  ; den Zaehler erhöhen

           sts     Str1Count, temp1       ; und den Zaehler wieder abspeichern
           ret


           .DSEG
Str1Count: .BYTE  1
Str1Bytes: .BYTE  20

Autor: GSP (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn man schon ein extra byte rauswerfen muss, um einen String zu 
verwalten sollte man die aussagekraefigere Methode nehmen. Eine Laenge 
sagt nun mal mehr als eine nichtssagende Null.

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

Bewertung
0 lesenswert
nicht lesenswert
GSP wrote:
> Wenn man schon ein extra byte rauswerfen muss, um einen String zu
> verwalten sollte man die aussagekraefigere Methode nehmen. Eine Laenge
> sagt nun mal mehr als eine nichtssagende Null.

Du spielst auf die C Methode mit der abschliessenden 0 an?

Bin ich nicht ganz einverstanden. Mit Ausnahme des Falls, dass
an einen String etwas angehängt werden muss, ergibt die Terminierungs
0 meist deutlich einfacheren Code.
Des weiteren kann mit der Terminierungs-0 ein String praktisch
beliebig lang werden. Mit einem Länge Byte bist du auf 255 Zeichen
beschränkt (ok: nimmt man halt 2 Bytes und kommt damit lange aus)

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn man schon ein extra byte rauswerfen muss, um einen String zu
> verwalten sollte man die aussagekraefigere Methode nehmen. Eine Laenge
> sagt nun mal mehr als eine nichtssagende Null.

Wie Karl schon sagte, beide Methoden haben ihre Vor- und Nachteile. Das 
ich sowohl im Delphi (Pascal) als auch mit C programmiere, muss ich 
sagen, das mir persönlich die C-Version im allgemeinen besser gefällt.

Autor: GSP (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das sit richtig, dass der Delphi Shortstring mit der Lanege als 
nulltes Byte auf 255 Bytes beschraenkt ist. Hat aber dafuer den Vorteil, 
eine Null als Character enthalten zu koennen. Damit kann ich mit 
Binaerdaten, meist im Zusammenhang mit Kommunikation, auf die 
Funktionalitaet einer Stringklasse zurueckgreifen. Delphi behandelt die 
von selbst inplizit als Referenz. Ich weiss, die C Leute sind Stolz auf 
ihre Stern * Schreibweisen. In einem Controller ist ein String von sagen 
wir mal groesser 64, oder ein Buffer wie ich sie gebrauche, eh 
undenkbar. 255 ist sehr weit weg. In Controllern braucht man wirkliche 
Strings ja eh nur um sie auf einen LCD zu klatschen, oder um einem PC 
GUI die Caption eines Controls mitzuteilen. Beides ist sehr begrent in 
der Laenge.

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.