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
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:
1 | char text[32] = {"Hallo Welt"}; |
2 | |
3 | // Todo: Ports einrichten, Variablen definieren usw...
|
4 | |
5 | DDRA = 0xFF; // Daten-Port |
6 | DDRC |= (1<<STROBE_PIN) // Strobe-Port |
7 | PORTC |= (1<<STROBE_PIN); |
8 | |
9 | for(i=0; i<strlen(text); ++i) |
10 | {
|
11 | PORTA = text[i]; |
12 | PORTC &= ~(1<<STROBE_PIN); |
13 | _delay_ms(3); |
14 | PORTC |= (1<<STROBE_PIN); |
15 | }
|
bitte nur als Anregung mitnehmen...
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
1 | // ist nur quick and dirty pseudo code, schon ne weile nix mehr mit c gemacht
|
2 | |
3 | main () |
4 | {
|
5 | // var festlegen
|
6 | char Text[10]="Hallo World"; |
7 | int i; |
8 | |
9 | // controller ini, portb als ausgang
|
10 | PORTB = 0xff; |
11 | |
12 | //schleife
|
13 | |
14 | for(i=0, i<10, i++) |
15 | {
|
16 | PORTB = Text[i]; |
17 | }
|
18 | }
|
aahh da war jemand schneller, und ich hab das DDRx vergessen... nun ja der gute wille zählt :P
Smarti schrieb: > aahh da war jemand schneller, und ich hab das DDRx vergessen... Du hast noch mehr vergessen :-)
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.
@ 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-Tutorial/LCD-Ansteuerung 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
Mario Grafe schrieb:
1 | > char text[32] = {"Hallo Welt"}; |
2 | > |
3 | > // Todo: Ports einrichten, Variablen definieren usw... |
4 | > |
5 | > DDRA = 0xFF; // Daten-Port |
6 | > DDRC |= (1<<STROBE_PIN) // Strobe-Port |
7 | > PORTC |= (1<<STROBE_PIN); |
8 | > |
9 | > for(i=0; i<strlen(text); ++i) |
10 | > { |
11 | > PORTA = text[i]; |
12 | > PORTC &= ~(1<<STROBE_PIN); |
13 | > _delay_ms(3); |
14 | > PORTC |= (1<<STROBE_PIN); |
15 | > } |
das wuerde aber "allo Welt" ausgeben? also wegen dem ++i in der for schleife
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
1 | #define PRINTER_DATA_PORT PORTA
|
2 | #define PRINTER_STROBE_PORT PORTB
|
3 | #define STROBE_PIN PB3
|
4 | |
5 | void printer_putc( char c ) |
6 | {
|
7 | PRINTER_DATA_PORT = c; |
8 | PRINTER_STROBE_PORT &= ~(1<<STROBE_PIN); |
9 | delay_ms( 3 ); |
10 | PRINTER_STROBE_PORT |= (1<<STROBE_PIN); |
11 | delay_ms( 3 ); |
12 | }
|
13 | |
14 | void printer_puts( const char* text ) |
15 | {
|
16 | while( *text ) |
17 | printer_putc( *text++ ); |
18 | }
|
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.
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)
@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 . . .
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 :-)
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.
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! ;-)
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.
1 | 'S-Ausgaben an Plotter |
2 | 'Mit Gosub OUTSTRING aufrufen |
3 | |
4 | Ms: |
5 | S = " MS 0" : Goto Outstring 'Maßstab festlegen |
6 | Ap_100_100: |
7 | S = "AP 100 100" : Goto Outstring |
8 | Ss: |
9 | S = "SS" : Goto Outstring 'Stift senken |
10 | Sh: |
11 | S = "SH" 'Stift Heben |
12 | |
13 | Outstring: |
14 | Pos = 0 : L = Len(s) |
15 | Do |
16 | Do : Loop Until Pinc.5 = 0 'Warten bis BUSY=0 |
17 | Waitms 5 |
18 | Incr Pos |
19 | |
20 | Portd = S_byte(pos) Or 128 'Ausgabe des Bytes |
21 | Gosub Wait50 'Strobe erzeugen |
22 | Portd.7 = 0 |
23 | Gosub Wait50 |
24 | Portd.7 = 1 |
25 | Loop Until L = Pos |
26 | |
27 | Do : Loop Until Pinc.5 = 0 'Warten bis BUSY=0 |
28 | Waitms 5 |
29 | Ch = 13 + 128 ' 0D ausgeben |
30 | Portd = Ch |
31 | Gosub Wait50 |
32 | 'Strobe erzeugen |
33 | Portd.7 = 0 |
34 | Gosub Wait50 |
35 | Portd.7 = 1 |
36 | Waitms 5 |
37 | |
38 | Return |
39 | |
40 | Wait50: |
41 | Waitus 50 |
42 | Return |
frage nebenbei gibt es auch eine vergleichbar simple lösung für nen usb drucker ? mfg
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,...).
Sicher nicht simpel, weil USB selber schon recht komplex ist, und ich denke man braucht da echt was "großes" wie ein ARM...
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.
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
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.
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.