so... nachdem der Port A nun blinkt habe ich an PortB (Tiny26) ein LCD Display angeschlossen. Ich betreibe (oder möchte) es im 4 Bit Modus und die Leitungen RS und E sind ebenfalls am Port B an geschlossen. Wie geht es nun weiter. Habe hier schon die Dateien lcd.c und lcd.h gefunden aber die beziehen sich ja wohl auf den Busbetrieb. Wo finde ich die entsprechenden Dateien die ich in mein Programm einbinden muß bzw. welche Änderungen muß ich für meine Hardwareconfigurationen vornehmen??
Hallo, was meinst du mit Busbetrieb? Ich hab mir aus dem Tutorial die lcd.h und lcd.c so umgeschrieben, dass man da die gewünschten Pins angeben kann, also frei wählen... Brauchst du das oder was meinst du?
ich denke mal, das wird es sein. Mit Busbetrieb meine ich,dass das Display über einen Adressdekoder (z.B. 74ls138) selektiert wird. Was muß ich in den Routinen ändern??
Ich Poste einfach mal das was ich da geändert habe... Is warscheinlich nicht optimal, läuft aber. Das ist die lcd.c
1 | //********************************************************************************
|
2 | // sendet ein Datenbyte an das LCD
|
3 | |
4 | void lcd_data(unsigned char data8){ |
5 | |
6 | LCD_RSP |= (1<<LCD_RS); // RS auf 1 setzen |
7 | |
8 | setPin(); |
9 | if(data8 & 128)LCD_D3P |=(1<<LCD_D3); //hi nibbels |
10 | if(data8 & 64)LCD_D2P |=(1<<LCD_D2); |
11 | if(data8 & 32)LCD_D1P |=(1<<LCD_D1); |
12 | if(data8 & 16)LCD_D0P |=(1<<LCD_D0); |
13 | lcd_enable(); |
14 | |
15 | setPin(); |
16 | if(data8 & 8)LCD_D3P |=(1<<LCD_D3); //low nibbels |
17 | if(data8 & 4)LCD_D2P |=(1<<LCD_D2); |
18 | if(data8 & 2)LCD_D1P |=(1<<LCD_D1); |
19 | if(data8 & 1)LCD_D0P |=(1<<LCD_D0); |
20 | lcd_enable(); |
21 | |
22 | waitms(1); |
23 | }
|
24 | |
25 | //********************************************************************************
|
26 | //rücksetzen der Daten pins
|
27 | |
28 | void setPin(void){ |
29 | |
30 | LCD_D3P &= ~(1<<LCD_D3); |
31 | LCD_D2P &= ~(1<<LCD_D2); |
32 | LCD_D1P &= ~(1<<LCD_D1); |
33 | LCD_D0P &= ~(1<<LCD_D0); |
34 | }
|
35 | |
36 | //********************************************************************************
|
37 | // sendet einen Befehl an das LCD
|
38 | |
39 | void lcd_command(unsigned char cmd8){ |
40 | |
41 | LCD_RSP &= ~(1<<LCD_RS); // RS auf 0 setzen |
42 | |
43 | setPin(); |
44 | if(cmd8 & 128)LCD_D3P |=(1<<LCD_D3); //hi nibbels |
45 | if(cmd8 & 64)LCD_D2P |=(1<<LCD_D2); |
46 | if(cmd8 & 32)LCD_D1P |=(1<<LCD_D1); |
47 | if(cmd8 & 16)LCD_D0P |=(1<<LCD_D0); |
48 | lcd_enable(); |
49 | |
50 | setPin(); |
51 | if(cmd8 & 8)LCD_D3P |=(1<<LCD_D3); //low nibbels |
52 | if(cmd8 & 4)LCD_D2P |=(1<<LCD_D2); |
53 | if(cmd8 & 2)LCD_D1P |=(1<<LCD_D1); |
54 | if(cmd8 & 1)LCD_D0P |=(1<<LCD_D0); |
55 | lcd_enable(); |
56 | |
57 | waitms(1); |
58 | }
|
59 | |
60 | //********************************************************************************
|
61 | // erzeugt den Enable-Puls
|
62 | |
63 | void lcd_enable(void) |
64 | {
|
65 | LCD_ENP |= (1<<LCD_EN); // kurze Pause (?!?) |
66 | LCD_ENP &= ~(1<<LCD_EN); |
67 | }
|
68 | |
69 | //********************************************************************************
|
70 | // Initialisierung:
|
71 | // Muss ganz am Anfang des Programms aufgerufen werden.
|
72 | |
73 | void lcd_init(void) |
74 | {
|
75 | LCD_RSDDR |= (1<<LCD_RS); //initial der ports (ausgänge schalten) |
76 | LCD_ENDDR |= (1<<LCD_EN); |
77 | LCD_D3DDR |=(1<<LCD_D3); |
78 | LCD_D2DDR |=(1<<LCD_D2); |
79 | LCD_D1DDR |=(1<<LCD_D1); |
80 | LCD_D0DDR |=(1<<LCD_D0); |
81 | |
82 | // muss 3mal hintereinander gesendet werden zur Initialisierung
|
83 | |
84 | waitms(15); //nach power on warten.. |
85 | |
86 | setPin(); |
87 | LCD_D1P |=(1<<LCD_D1); |
88 | LCD_D0P |=(1<<LCD_D0); |
89 | LCD_RSP &= ~(1<<LCD_RS); // RS auf 0 |
90 | lcd_enable(); //1. |
91 | waitms(5); |
92 | |
93 | lcd_enable(); //2. |
94 | waitms(1); |
95 | |
96 | lcd_enable(); //3. |
97 | waitms(1); |
98 | |
99 | |
100 | setPin(); // 4 Bit Modus aktivieren |
101 | LCD_D2P |= (1<<LCD_D2); |
102 | lcd_enable(); |
103 | waitms(1); |
104 | |
105 | lcd_command(0x28); // 4Bit / 2 Zeilen / 5x7 char größe |
106 | |
107 | lcd_command(0x0C); // Display ein / Cursor aus / kein Blinken |
108 | |
109 | lcd_command(0x06); // inkrement / kein Scrollen |
110 | |
111 | lcd_clear(); |
112 | }
|
113 | |
114 | //********************************************************************************
|
115 | // Sendet den Befehl zur Löschung des Displays
|
116 | |
117 | void lcd_clear(void) |
118 | {
|
119 | lcd_command(CLEAR_DISPLAY); |
120 | waitms(5); |
121 | }
|
122 | |
123 | //********************************************************************************
|
124 | // Sendet den Befehl: Cursor Home
|
125 | |
126 | void lcd_home(void) |
127 | {
|
128 | lcd_command(CURSOR_HOME); |
129 | waitms(5); |
130 | }
|
131 | |
132 | //********************************************************************************
|
133 | // setzt den Cursor in Zeile y (1..2) Spalte x (0..15)
|
134 | |
135 | void set_cursor(uint8_t x, uint8_t y) |
136 | {
|
137 | uint8_t tmp=0; |
138 | |
139 | switch (y) { |
140 | case 1: tmp=0x80+0x00+x; break; // 1. Zeile |
141 | case 2: tmp=0x80+0x40+x; break; // 2. Zeile |
142 | }
|
143 | lcd_command(tmp); |
144 | }
|
145 | |
146 | //********************************************************************************
|
147 | // Schreibt einen String auf das LCD
|
148 | |
149 | void lcd_string(char *data) |
150 | {
|
151 | while(*data) { |
152 | lcd_data(*data); |
153 | data++; |
154 | }
|
155 | }
|
und das die lcd.h
1 | void lcd_data(unsigned char temp1); //einzelnes Zeichen |
2 | void lcd_string(char *data); //string ausgeben |
3 | void lcd_command(unsigned char temp1); //komando an lcd |
4 | void lcd_enable(void); //leachen der daten |
5 | void lcd_init(void); //initialisierung |
6 | void lcd_home(void); //cursor at home |
7 | void lcd_clear(void); //bildschirm löschen |
8 | void set_cursor(uint8_t x, uint8_t y); //cursor positionieren |
9 | void setPin(void); //alle 4 Daten pins auf 0 setzen |
10 | |
11 | // Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!
|
12 | |
13 | #define F_CPU 8000000UL
|
14 | |
15 | // LCD Befehle
|
16 | |
17 | #define CLEAR_DISPLAY 0x01
|
18 | #define CURSOR_HOME 0x02
|
19 | |
20 | //********************************************************
|
21 | // Pinbelegung für das LCD, an verwendete Pins anpassen !!
|
22 | |
23 | #define LCD_RSDDR DDRC //rs und en ,ddr ,port ,pin
|
24 | #define LCD_ENDDR DDRB
|
25 | |
26 | #define LCD_RSP PORTC
|
27 | #define LCD_ENP PORTB
|
28 | |
29 | #define LCD_RS PC2
|
30 | #define LCD_EN PB2
|
31 | |
32 | //********************************************************
|
33 | #define LCD_D0DDR DDRB //4 daten ,pins ,ddr ,port
|
34 | #define LCD_D1DDR DDRC
|
35 | #define LCD_D2DDR DDRB
|
36 | #define LCD_D3DDR DDRB
|
37 | |
38 | #define LCD_D0P PORTB
|
39 | #define LCD_D1P PORTC
|
40 | #define LCD_D2P PORTB
|
41 | #define LCD_D3P PORTB
|
42 | |
43 | #define LCD_D0 PB1
|
44 | #define LCD_D1 PC3
|
45 | #define LCD_D2 PB5
|
46 | #define LCD_D3 PB0
|
47 | |
48 | //********************************************************
|
49 | #include "D:\avr\AVR\cprogs\libs\lcd\lcd.c" |
ich bin was c betrifft hier absoluter neuling, von daher mal die frage: ich habe wie folgt angeschlossen: 1 Vss GND 2 Vcc 5V 3 Vee GND 4 RS PB4 am AVR 5 RW GND 6 E PB5 am AVR 7 DB0 nicht angeschlossen 8 DB1 nicht angeschlossen 9 DB2 nicht angeschlossen 10 DB3 nicht angeschlossen 11 DB4 PB0 am AVR 12 DB5 PB1 am AVR 13 DB6 PB2 am AVR 14 DB7 PB3 am AVR wo muß ich ändern??
Also erstmal in der lcd.h Als Beispiel: #define LCD_RSDDR DDRB #define LCD_ENDDR DDRB #define LCD_RSP PORTB #define LCD_ENP PORTB #define LCD_RS PB4 #define LCD_EN PB5 für die beiden Ports RS und EN LCD_D0 wäre bei dir dann PB0 und so weiter... Wichtig ist das der eigentliche Port z.B. LCD_RS und die beiden dazugehörigen anderen defines übereinstimmen (LCD_RSP und LCD_RSDDR).
Da du die lcd Routinen hier aus dem gcc Tutorial benutzt. In der lcd.h gibt es einen Abschnitt
1 | // Pinbelegung für das LCD, an verwendete Pins anpassen
|
2 | #define LCD_PORT PORTD
|
3 | #define LCD_DDR DDRD
|
4 | #define LCD_RS PD4
|
5 | #define LCD_EN PD5
|
dort trägst du die Pinbelegung ein. Dein LCD hängt am Port B. Also wird das wohl heissen
1 | #define LCD_PORT PORTB
|
mit dem Port einher geht das Data Direction Register
1 | #define LCD_DDR DDRB
|
Die Datenleitungen sind beim Tutorial Code fix auf Bit 0 bis Bit4. Das passt mit deiner Belegung überein. Deine RS Leitung hängt am Pin PB4. Also schreibst du das auch so rein
1 | #define LCD_RS PB4
|
und deine Enable-Leitung vom LCD geht auf Pin PB5
1 | #define LCD_EN PB5
|
Ist doch nicht so schwer, oder?
na ja dafür,dass ich erst seit zwei Tagen dabei bin und es immerhin schon blinkt und läuft...geht doch oder??
Ingo Laabs wrote: > Ähhhhhh......wo finde ich die Dateien lcd.h und lcd.c ?? Dazu müsste man erst mal wissen, welche do dir aus dem Netz geholt hast. Die sind nicht beim Compiler dabei. LCD Routinen gibt es wie Sand am Meer. zb hier http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#LCD-Ansteuerung oder auch hier Beitrag "Re: LCD AVR C ROUTINEN" oder diese hier http://homepage.hispeed.ch/peterfleury/avr-software.html
So nun läuft mein LCD, habe jetzt nur ein Problem mit der Zeile set_cursor. Ich bekomme den cursor nur in die 2. Zeile mit der Anweisung set_cursor(0,2). obwohl der Syntax doch eigentlich Zeile y(1..2) und Spalte x(0..15) ist. Was ist hier falsch?? #define F_CPU 800000UL #include <avr/io.h> #include <util/delay.h> #include <lcd.h> #include <lcd.c> int main(void) lcd_init(); set_cursor(1,0); lcd_string("ZEILE 1 "); set_cursor(0,2); lcd_string("ZEILE 2 ");
Hallo, ich nehme mal an du benutzt die lcd-routinen von mikrocontroller.net ! Du musst dir die Quellcodes schon mal anschauen, dann ist dir auch klar warum du nur mit 2 in die 2.Zeile kommst. Der erstes aufruf ist übrigens falsch mit setcursor(1,0). Der funktioniert nur weil du vorher lcd_init() gemacht hast, der den Cursor schon auf Anfang setzt. da steht nämlich ..... void set_cursor(unsigned char x, unsigned char y) { unsigned char command; switch (y) { case 1: command=0x80+0x00+x; break; // 1. Zeile case 2: command=0x80+0x40+x; break; // 2. Zeile } das bedeutet also mit setcursor(0,1) -> 1.Zeile , 1.Zeichen und setcursor (0,2) -> 2.Zeile , 1.Zeichen. GRUSS
gibt es da noch weitere kommandos, was kann ich noch bei lcd_init() einsetzen??
Hier http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD#Welche_Befehle_versteht_das_LCD.3F findest du eine Übersicht über die Befehle, die so ein LCD normalerweise versteht.
Die sind mir bekannt.Ich meinte die kommandos von C aus ..sowie set_cursor Ich kann doch mit sicherheit von c aus auch scrollen oder den cursor blinken lassen. sowas meint ich
Der Controller versteht gewisse Kommandos, nachzulesen im Datenblatt oder hier : http://www.mikrocontroller.net/articles/HD44780
Ingo Laabs wrote: > Die sind mir bekannt.Ich meinte die kommandos von C aus ..sowie > set_cursor > Ich kann doch mit sicherheit von c aus auch scrollen oder den cursor > blinken lassen. sowas meint ich Du hast die Kommandoübersicht. Was hindert dich daran, dir diese Funktionen selber zu schreiben? Immerhin bist du auf dem Weg Programmierer zu werden. Gewöhn dich schon mal daran, dass das auch heisst: Sich selbst Werkzeuge zu basteln. "Malen nach Zahlen" war gestern. Heute entwirfst du selbst deine Motive und mischt auch die Farben selbst.
Als Tipp : Die Funktion lcd_command() kann schon Kommandos senden... Musst jetzt noch ermitteln welchen Hex wert dein Kommando hat :)
Bin dabei. Habe die Ansteuerung schon in Assembler mal geschrieben nur fehlt mir noch in C die gewisse Erfahrung da ich mich jetzt als Umsteiger betrachte. Denke aber mal ich bekomme das hin. In Assembler hat auch alles geklappt. Ist nur alles ein wenig gewöhnungsbedürftig in C..trotzdem DANKE :-)
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.