mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mit dem ATmega8 Text auf einen Drucker ausgeben klappt nicht.


Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will mit dem ATmega 8 Daten statt auf ein Display auf einen alten 
Star LC10 Drucker mit Parallelport ausgeben.

Zum Verständnis der Parallelschnittstelle habe ich mir ein Board 
gebastelt mit 8 kleinen Schalterchen und einem Taster.

Wenn ich nun die 13 einstelle und den Taster auf Strobe drücke, dann 
zuckt der Drucker, stelle ich die 11 ein, drücke den Taster und dann die 
13 macht der Drucker einen Zeilenvorschub.

Genauso geht das, wenn ich z.B. die 63 einstelle, Taster drücke, usw.
Der Drucker druckt dann auch ein a.

Das Prinzip habe ich also verstanden. Was ich nun aber nicht verstanden 
habe ist die Umsetzung, wie ich das Tasterdrücken in C programmiere und 
wie ich weiß, ob der Drucker mich "verstanden" hat.

Richtigen C Code gibt es noch keinen, weil ich zwar weiß, wie ich 8 Bit 
auf einen Port des ATmega 8 lege, aber dann hört es schon auf, weil ich 
nicht weiß wie ich einen Impuls erzeugen soll _delay_ms(3)    ~PortC(1) 
_delayms(3)    nächstes Byte auf den Augabeport, usw. ...

In der Codesammlung finde ich da auch keinen richtigen Ansatz.

Hat jemand da mal ein nachvollziehbares Beispiel eine Function, von mir 
aus auch als Pseudocode, mit ich dann versuchen kann den ich C zu 
schreiben und zu nutzen.

Danke schon einmal ... Sollte mein erstes, eigenes Projekt mit dem Mega 
8 werden, das ich nicht aus dem Netz nehme und modifiziere ... Leider 
scheitert es schon wieder an irgendwelchen Verständnisschwierigkeiten.

Der Dussel

Autor: Mario Grafe (mario)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du schon mal ein kleines Programm geschrieben á la LED blinken 
lassen oder so?
Nun ja, ich würde doch empfehlen etwas C zu lernen. Du mußt dich auch 
mit dem AVRStudio und WinAVR auseinandersetzen. Die alten Drucker kann 
man auch mit Escape-Zeichenfolgen steuern (wenn du das alte Handbuch 
noch hast, da steht es drin).

Ein Code-snippet zur Ausgabe könnte wie folgt aussehen:
char text[32] = {"Hallo Welt"};

// Todo: Ports einrichten, Variablen definieren usw...

DDRA   = 0xFF;                   // Daten-Port
DDRC  |= (1<<STROBE_PIN)         // Strobe-Port
PORTC |= (1<<STROBE_PIN);

for(i=0; i<strlen(text); ++i)
{
   PORTA = text[i];
   PORTC &= ~(1<<STROBE_PIN);
   _delay_ms(3);
   PORTC |= (1<<STROBE_PIN);
}

bitte nur als Anregung mitnehmen...

Autor: Smarti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Dussel,

also das ganze hört sich recht interessant an, also da wäre doch 
naheliegend ne PS/2 Tastatur her zu nehmen und das ganze zur ner 
elektronichen Schreibmaschine zu erweitern ggf. später schreib Buffer 
und mit LCD Display :D

Zum C-Code hier mal ein paar Ansätze:

1. was du ausgeben willst in n array
2. erst mal dein Register auf Ausgang setzten
3. for schleife

// ist nur quick and dirty pseudo code, schon ne weile nix mehr mit c gemacht

main ()
{
  // var festlegen
  char Text[10]="Hallo World";
  int i;

  // controller ini, portb als ausgang
  PORTB = 0xff;

  //schleife

  for(i=0, i<10, i++)
  {
     PORTB = Text[i];
  }
}



Autor: Smarti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aahh da war jemand schneller, und ich hab das DDRx vergessen... nun ja 
der gute wille zählt :P

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

Bewertung
0 lesenswert
nicht lesenswert
Smarti schrieb:
> aahh da war jemand schneller, und ich hab das DDRx vergessen...

Du hast noch mehr vergessen :-)

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

Bewertung
0 lesenswert
nicht lesenswert
Dussel schrieb:

> Richtigen C Code gibt es noch keinen, weil ich zwar weiß, wie ich 8 Bit
> auf einen Port des ATmega 8 lege, aber dann hört es schon auf, weil ich
> nicht weiß wie ich einen Impuls erzeugen soll _delay_ms(3)    ~PortC(1)
> _delayms(3)    nächstes Byte auf den Augabeport, usw. ...

klingt so doch nicht schlecht

> In der Codesammlung finde ich da auch keinen richtigen Ansatz.

Na ja. Für jede Kleinigkeit wirst du dort auch nichts finden.

Was ist den ein Puls?

Eine Leitung liegt auf 0
dann wird se auf 1 gesetzt und kurz darauf wieder auf 0

Und schon hast du einen Puls. Genau das was du mit deinem Taster auch 
gemacht hast.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Dussel (Gast)

>Richtigen C Code gibt es noch keinen, weil ich zwar weiß, wie ich 8 Bit
>auf einen Port des ATmega 8 lege,

Na immerhin.

> aber dann hört es schon auf, weil ich
>nicht weiß wie ich einen Impuls erzeugen soll _delay_ms(3)    ~PortC(1)
>_delayms(3)    nächstes Byte auf den Augabeport, usw. ...

Genau so.

>In der Codesammlung finde ich da auch keinen richtigen Ansatz.

Warum auch. Dad sind so elementare Grundlagen, die findest du 
bestenfalls im tutorial. Aber auch dort ganz sicher nicht als fertige 
Lösung speziell für dein Problem.

>Hat jemand da mal ein nachvollziehbares Beispiel eine Function, von mir
>aus auch als Pseudocode, mit ich dann versuchen kann den ich C zu
>schreiben und zu nutzen.

Alles Stringausgaben, z.B. hier

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Einfach in der Routinge lcd_string nach jedem Zeichen ein Strobe 
generieren und eine Pause machen. Fertig.

>scheitert es schon wieder an irgendwelchen Verständnisschwierigkeiten.

Dann beschäftige dich mal mit deinem C-Buch und dem Tutorial. Dir fehlen 
noch viele Grundlagen. Ohne die wirst du nicht weit kommen.

MFG
Falk

Autor: pre-increment? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mario Grafe schrieb:
> char text[32] = {"Hallo Welt"};
> 
> // Todo: Ports einrichten, Variablen definieren usw...
> 
> DDRA   = 0xFF;                   // Daten-Port
> DDRC  |= (1<<STROBE_PIN)         // Strobe-Port
> PORTC |= (1<<STROBE_PIN);
> 
> for(i=0; i<strlen(text); ++i)
> {
>    PORTA = text[i];
>    PORTC &= ~(1<<STROBE_PIN);
>    _delay_ms(3);
>    PORTC |= (1<<STROBE_PIN);
> }


das wuerde aber "allo Welt" ausgeben?
also wegen dem ++i in der for schleife

Autor: Mario Grafe (mario)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann eben "i++"... :)

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

Bewertung
0 lesenswert
nicht lesenswert
pre-increment? schrieb:

> das wuerde aber "allo Welt" ausgeben?

Nein, würde es nicht.
Auch hier sei wieder der Hinweis auf ein C Buch angebracht:
Wann genau wird denn der Inkrement ausgeführt?
Macht es daher einen Unterschied, ob man an dieser Stelle ++i oder i++ 
benutzt?

Trotzdem ist das eine Funktion, die man so nicht schreibt. Aus mehreren 
Gründen.

So würde man das machen
#define PRINTER_DATA_PORT      PORTA
#define PRINTER_STROBE_PORT    PORTB
#define STROBE_PIN             PB3

void printer_putc( char c )
{
  PRINTER_DATA_PORT = c;
  PRINTER_STROBE_PORT &= ~(1<<STROBE_PIN);
  delay_ms( 3 );
  PRINTER_STROBE_PORT |=  (1<<STROBE_PIN);
  delay_ms( 3 );
}

void printer_puts( const char* text )
{
  while( *text )
    printer_putc( *text++ );
}

wobei ich mir jetzt nicht sicher bin, ob der Strobe ein Positivpuls oder 
ein Negativpuls ist. Ich lass es mal so, wie Mario das vorgegeben hat. 
Und natürlich sollte man vorher tunlichst auch noch die Statusleitung 
abfragen, mit der der Printer bekannt gibt, das er aufnahmebereit ist. 
Das kann sonst bei einem Seitenvorschub zu ganz unliebsamen 
Überraschungen führen, wenn man dem Printer seinen internen Cache 
Speicher vollballert.


Aber das schreiben wir dem TO nicht, denn ein wenig C muss er dann schon 
auch selbst lernen wenn er kreativ Programmieren möchte und nicht immer 
nur in vorhandenen Programmen Kleinigkeiten ändern will.
Sein Ansatz, die Dinge zuerst händisch mittels einem Taster 
auszuprobieren, gefällt mir grundsätzlich. Nur den Schritt der Analyse, 
welchen Pegel daher eine Leitung hat und wie man das mit Bit setzen bzw. 
löschen in einem Programm nachbildet, den muss er noch machen. Obwohl: 
genau das ist doch eigentlich die erste Übung in der µC Programmiererei: 
Einen Pin gezielt auf 1 oder 0 zu setzen. Nur hängt halt bei den ersten 
Übungen eine LED an diesem Pin und kein Drucker der auf den Puls wartet. 
Aber das Prinzip ist genau das gleiche.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
pre-increment? schrieb:
> das wuerde aber "allo Welt" ausgeben?
> also wegen dem ++i in der for schleife

ihr bringt ja na völlig durcheinandern, aber es ist an dieser stelle 
egal ob ++i oder i++ steht. Es wird immer nach dem schleifendurchlauf 
gerechnet.

(wenn ich mich irre, liegt es an den 30Grad im Zimmer)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz Buchegger (kbuchegg) (Moderator)

>Aber das schreiben wir dem TO nicht, denn ein wenig C muss er dann schon
>auch selbst lernen wenn er kreativ Programmieren möchte

Ähhh, Karl, du führst Selbstgespräche mit offenem Mund . . .

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

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner schrieb:
> @Karl heinz Buchegger (kbuchegg) (Moderator)
>
>>Aber das schreiben wir dem TO nicht, denn ein wenig C muss er dann schon
>>auch selbst lernen wenn er kreativ Programmieren möchte
>
> Ähhh, Karl, du führst Selbstgespräche mit offenem Mund . . .

Das ist eines meiner Markenzeichen.
Meine Kollegen haben sich schon daran gewöhnt, dass ich in 
Nachdenkphasen schon mal durch die Gänge schlürfe und mir selbst das 
Problem erkläre.

Sie amüsieren sich jetzt nur noch darüber, dass ich bei 
Geometrieproblemen auch noch Armverrenkungen dazu mache :-)

Autor: bix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dussel schrieb:
> und
> wie ich weiß, ob der Drucker mich "verstanden" hat.

Da möchte ich noch das Stichwort "Handshake" in the Schredd werfen. Der 
Drucker signalisiert damit, dass er ein Byte empfangen hat. (Wartezeiten 
mittels _delay_ms() sind damit überflüssig und man weiß ja nie, ob das 
gewählte delay nich doch mal zu kurz gewählt ist)

Es gibt auch noch andere interessante Signale am Printer Port. Man kann 
z.B. erkennen ob der Drucker "offline" ist oder ob Papier fehlt.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Falk Brunner schrieb:
>> @Karl heinz Buchegger (kbuchegg) (Moderator)
>>
>>>Aber das schreiben wir dem TO nicht, denn ein wenig C muss er dann schon
>>>auch selbst lernen wenn er kreativ Programmieren möchte
>>
>> Ähhh, Karl, du führst Selbstgespräche mit offenem Mund . . .
>
> Das ist eines meiner Markenzeichen.
> Meine Kollegen haben sich schon daran gewöhnt, dass ich in
> Nachdenkphasen schon mal durch die Gänge schlürfe und mir selbst das
> Problem erkläre.

Das zeugt ja auch von einem belebten Geist! ;-)

Autor: Wolfgang Schmidt (wsm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Strobe ist negativ.

Ob der Drucker Daten empfangen kann oder Busy ist muss abgefragt werden.

Im Netz findet man viele Diagramme für den Parallelport.

Das 8. Bit muss natürlich in der Regel "0" sein.

Im folgenden Programm wird eine Reihe von Zeichen aus einem Array 
ausgegeben. Bit 7 wird als Strobe benutzt und extern auf "0" gesetzt.
 'S-Ausgaben an Plotter
 'Mit Gosub  OUTSTRING aufrufen

Ms:
       S = " MS 0" : Goto Outstring               'Maßstab festlegen
Ap_100_100:
      S = "AP 100 100" : Goto Outstring
Ss:
      S = "SS" : Goto Outstring                   'Stift senken
Sh:
      S = "SH"                                    'Stift Heben

Outstring:
Pos = 0 : L = Len(s)
Do
      Do : Loop Until Pinc.5 = 0                  'Warten bis BUSY=0
      Waitms 5
      Incr Pos

      Portd = S_byte(pos) Or 128                  'Ausgabe des Bytes
      Gosub Wait50                                'Strobe erzeugen
      Portd.7 = 0
      Gosub Wait50
      Portd.7 = 1
Loop Until L = Pos

      Do : Loop Until Pinc.5 = 0                  'Warten bis BUSY=0
      Waitms 5
      Ch = 13 + 128                               ' 0D ausgeben
      Portd = Ch
      Gosub Wait50
                     'Strobe erzeugen
      Portd.7 = 0
      Gosub Wait50
      Portd.7 = 1
      Waitms 5

Return

Wait50:
      Waitus 50
Return

Autor: sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
frage nebenbei gibt es auch eine vergleichbar simple lösung für nen usb 
drucker ?
mfg

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simpel? Eher nicht.
Erstens brauchst Du einen USB-Host (oder OTG). Und zweitens muß irgendwo 
auch der USB-Protokollstack laufen.
Keine Ahnung, ob sowas eventuell mit einem der USB-AVR geht, aber simpel 
mit ziemlicher Sicherheit nicht.
Am ehesten wohl noch mit einem der größeren µC auf denen Linux läuft 
(AVR32,ARM,...).

Autor: Fer T. (fer_t)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sicher nicht simpel, weil USB selber schon recht komplex ist, und ich 
denke man braucht da echt was "großes" wie ein ARM...

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso noch vergessen.
USB-Drucker sind oft reine GDI-Drucker. Das komplette Rastern der 
Ausgabe erfolgt im Druckertreiber auf dem PC und der Drucker bekommt im 
Prinzip nur noch ein riesen Bitmap vorgesetzt.
Wenn Du Glück hast, versteht der Drucker wenigstens noch PCL, oder wenn 
er teuer genug ist, eventuell auch Postscript. Würde die Sache zwar 
erheblich vereinfachen, simpel ist das aber trotzdem noch lange nicht.

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mensch Danke an euch ...

mit LED an den restlichen Leitungen kann ich tatsächlich erkennen, ob 
Paper Out, Busy (Die blitzt kurz, wenn ich meinen Strobe Taster 
(Schaltet Masse auf den Pin und ist mit 10 kOhm gegen Plus im 
Ruhezustand), Offline ...

Habe mir in der Bibliothek mal den Kerningham Richie besorgt ... C ist 
ganz schön kompliziert. Vor allem, wenn man sich das AVR C Tutorial hier 
im Forum anschaut und dann versucht den Code zu verstehen.

Gibt es eigentlich eine deutsche Version der Beschreibung für die AVR C 
Funktionen aus der Bibliothek ?

Ich habe mir die bei Sourceforge mal runtergeladen und dann 
durchgeforstet. Wenn ich das richtig sehe, dann ist bei einem Programm 
für den AVR eigentlich mehr das Verständnis für die AVR Lib gefragt, als 
das Verständnis für C.

Ab morgen habe ich frei bis Montag. Dann werde ich mich mit dem Code aus 
dem Thread hier beschäftigen und vor allem mit den Anderen Signalen auf 
dem Parallelport.

Ich gehe nun auf Nachschicht.

Der Dussel

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

Bewertung
0 lesenswert
nicht lesenswert
Dussel schrieb:

> Habe mir in der Bibliothek mal den Kerningham Richie besorgt ...

Eine kluge Entscheidung!


> Ich habe mir die bei Sourceforge mal runtergeladen und dann
> durchgeforstet. Wenn ich das richtig sehe, dann ist bei einem Programm
> für den AVR eigentlich mehr das Verständnis für die AVR Lib gefragt, als
> das Verständnis für C.

Kommt drauf an.
Auf der Ebene, auf der du momentan arbeitest, brauchst du im 
wesentlichen momentan nur das Veständnis wie man einen Portpin auf 1 
bzw. wieder auf 0 setzt.
Das ist zwar im Grunde auch nur Standard-C, allerdings kommt das in der 
Programmierung ausserhalb der µC selten vor, so dass sich in der 
Standardliteratur da eher wenig darüber findet. Und genau da setzt dann 
das AVR-GCC-Tutorial ein. Es baut darauf auf, das C Kenntnise schon 
vorhanden sind und erklärt die Besonderheiten in der µC Programmierung.

Und ja: spätestens dann, wenn es darum geht, die im µC eingebaute 
Hardware zu benutzen, dann dann sind die Standardwerke logischerweise am 
Ende. Dann gilt nur noch das Datenblatt, bzw. die aus dem Datenblatt 
aufbereitete Form im Tutorial.

Autor: Blackmore (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessantes Projekt, könnt ich später auch gebrauchen...

Im Moment brauch ich jedoch die andere Richtung, Daten, die am 
parallelen Ausgang rauskommen mit'm Mega abfangen, auf SDCard speichern, 
auf nem LCD ausgeben und auf Tastendruck auf nem angeschlossenen Drucker 
ausgeben...

Aber das ist noch Zukunftsmusik...

Gruß Blackmore

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.