Hallo, ich habe ein 2x16 Zeichen LCD an einem ATtiny2313 hängen. Damit sich ein einfacheres Platinenlayout einstellt habe ich jetzt die Pinbelegung alternativ belegt: PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0 NC NC RS EN DB4 DB5 DB6 DB7 Jetzt NC NC EN RS DB7 DB6 DB5 DB4 Vorher So brauche ich in Eagle keine Drahtbrücken mehr. Problem sind die genau getauschten Datenpins, wie kann man das am elegantesten bewerkstelligen?
> PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0 > NC NC RS EN DB4 DB5 DB6 DB7 Jetzt > NC NC EN RS DB7 DB6 DB5 DB4 Vorher ^^^^^^^^^^^^^^^ D.h. du musst 4 Bits in Software drehen statt 1:1 den Tutorialcode zu übernehmen. Das ist grundsätzlich machbar, aber für Anfänger fehlerträchtig.
Alternative #1: Nimm BASCOM. Dort kannst du die Pinzuordnung beim LCD frei konfigurieren.
Hi Beschäftige dich doch erst ein mal mit dem Programmieren dann mit dem Layout. Sonst mutiert dein µC als "crashdemon" und du hast probleme und zu viel arbeit hinter/vor dir ;) Grüße
> D.h. du musst 4 Bits in Software drehen statt 1:1 den Tutorialcode zu > übernehmen. Das ist grundsätzlich machbar, aber für Anfänger > fehlerträchtig. Hehe, ja. Dachte da an soetwas wie einen Shift 0001 1000 0011 1100 0111 1110
Nett gemeint schrieb: > Hi > Beschäftige dich doch erst ein mal mit dem Programmieren dann mit dem > Layout. > Sonst mutiert dein µC als "crashdemon" und du hast probleme und zu viel > arbeit hinter/vor dir ;) > Grüße Das Programm steht schon, lief früher auf einem Atmega8 auf Streifenraster, da es dann mal ein wenig schöner werden sollte, platine etc. habe ich es dann auch gleich auf einem ATtiny portiert, der für meinen verwendungszweck mehr als ausreichend ist.
Die Pins füre LCD sind völlig egal, die kannst Du bunt durcheinander würfeln Und im h-File legst Du fest, auf welchem Port und Bit jeder liegt. http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=102296 Peter
Patrick Langosch schrieb: > Dachte da an soetwas wie einen Shift Das ist garantiert kein Bit-Shift. Beim Schieben bleibt die Bitreihenfolge prinzipiell gleich. Was du brauchst, ist ein Bit-Swap...
Brute Force
1 | inline uint8_t swap_nibble(uint8_t in) |
2 | {
|
3 | return ((in & (1<<0))<<3) |
4 | | ((in & (1<<1))<<2) |
5 | | ((in & (1<<2))<<1) |
6 | | ((in & (1<<3))<<0); |
7 | }
|
8 | |
9 | // dann
|
10 | LCD_DATA = (LCD_DATA & 0xF0) | swap_nibble(wert); |
11 | |
12 | // statt
|
13 | LCD_DATA = (LCD_DATA & 0xF0) | wert; |
Hier mal was zum Umdrehn:
1 | unsigned char umkehr(unsigned char n){ |
2 | n=((n>>1)&0x55)|((n<<1)&0xaa); |
3 | n=((n>>2)&0x33)|((n<<2)&0xcc); |
4 | return (n>>4)|(n<<4); |
5 | }
|
Damit machst du aus DB7 DB6 .... DB0 einfach DB0 DB1 .... DB7 Also alles was gesendet wird umdrehen und dann High- und Low-Nibble beachten ;) anr
Hier mal was zum Umdrehn: unsigned char umkehr(unsigned char n){ uint8_t mask, temp; mask = 0x01; temp = 0; do { if(n & mask) temp |= 0x80; mask <<= 1; if(mask) temp >>= 1; } while(mask); return temp; }
avr schrieb: > Hier mal was zum Umdrehn:
1 | > unsigned char umkehr(unsigned char n){ |
2 | > n=((n>>1)&0x55)|((n<<1)&0xaa); |
3 | > n=((n>>2)&0x33)|((n<<2)&0xcc); |
4 | > return (n>>4)|(n<<4); |
5 | > } |
Wenn man mit Flash nicht sparen muß, kann man es so machen. Ansonsten besser so:
1 | static void lcd_nibble( uint8_t d ) |
2 | {
|
3 | LCD_D4 = 0; if( d & 1<<4 ) LCD_D4 = 1; |
4 | LCD_D5 = 0; if( d & 1<<5 ) LCD_D5 = 1; |
5 | LCD_D6 = 0; if( d & 1<<6 ) LCD_D6 = 1; |
6 | LCD_D7 = 0; if( d & 1<<7 ) LCD_D7 = 1; |
7 | |
8 | LCD_E0 = 1; |
9 | _delay_us( 1 ); // 1us |
10 | LCD_E0 = 0; |
Peter
Wenn du den ASCii Code änderst, kannst du dein Code so lassen und die Rechenzeit für die Bit -schieberei sparen. Oder, wenn es nicht allzuviel Text ist einfach als (schon umgewandeltes) Hex eingeben. Ich programmiere zwar ASM, aber in C geht das sicher auch.
Jürgen W. schrieb: > Wenn du den ASCii Code änderst, kannst du dein Code so lassen und die > Rechenzeit für die Bit -schieberei sparen. Und wenn man kaltes Wasser braucht, stellt man heißes Wasser in den Kühlschrank. Peter
Alternativ wäre auch eine Look-Up Table. Bei 16Byte ist das noch überschaubar.
Also irgendwie schein ich da noch eine Bug drin zu haben, zumindest zeigt das LCD nur wirres zeugs an. Mit den Änderungen sollte es dann doch eig. so aussehen:
1 | /******** Befehl an das LCD senden ********/
|
2 | void LCD_command(unsigned char temp1) |
3 | {
|
4 | unsigned char temp2 = temp1; |
5 | |
6 | LCD_PORT &= ~(1 << LCD_RS); // Register Select auf "Transfering Instruction Data" setzen |
7 | |
8 | temp1 = (temp1 >> 4) & 0x0F; // Oberes Nibble holen + Maskieren |
9 | LCD_PORT = (LCD_PORT & 0xF0) | swap_nibble(temp1); // Daten Bits setzen |
10 | LCD_enable(); |
11 | |
12 | temp2 = temp2 & 0x0F; // unteres Nibble holen und maskieren |
13 | LCD_PORT = (LCD_PORT & 0xF0) | swap_nibble(temp2); // Daten Bits setzen |
14 | LCD_enable(); |
15 | |
16 | _delay_us(42); |
17 | }
|
mit
1 | unsigned char swap_nibble(unsigned char in) |
2 | {
|
3 | return((in & (1 << 0)) << 3) | |
4 | ((in & (1 << 1)) << 2) | |
5 | ((in & (1 << 2)) << 1) | |
6 | ((in & (1 << 3)) << 0); |
7 | }
|
Die LCD Initialisierung habe ich auch angepasst, die scheint zu funktionieren.
jop, deswegen bin ich ja irritiert.
1 | /******** Datenbyte an das LCD senden ********/
|
2 | void LCD_data(unsigned char temp1) |
3 | {
|
4 | unsigned char temp2 = temp1; |
5 | |
6 | LCD_PORT |= (1 << LCD_RS); // Register Select auf "Transferring Display Data" setzen |
7 | |
8 | temp1 = temp1 >> 4; |
9 | temp1 = temp1 & 0x0F; |
10 | LCD_PORT = (LCD_PORT & 0xF0) | swap_nibble(temp1); // Daten Bits setzen |
11 | |
12 | LCD_enable(); |
13 | |
14 | temp2 = temp2 & 0x0F; |
15 | LCD_PORT = (LCD_PORT & 0xF0) | swap_nibble(temp2); // Daten Bits setzen |
16 | |
17 | LCD_enable(); |
18 | |
19 | _delay_us(42); |
20 | }
|
Wenn du mit AVR-GCC-Tutorial/LCD-Ansteuerung arbeitest, bietet sich an, die Änderung zentral in lcd_out() zu machen, statt mehrfach in LCD_init, LCD_command und LCD_data.
Der Swapcode ist ja auch falsch. Passt den niemand mehr auf?
1 | unsigned char swap_nibble(unsigned char in) |
2 | {
|
3 | return((in & (1 << 0)) << 3) | // 0001 => 1000 |
4 | ((in & (1 << 1)) << 1) | // 0010 => 0100 |
5 | ((in & (1 << 2)) >> 1) | // 0100 => 0010 |
6 | ((in & (1 << 3)) >> 3); // 1000 => 0001 |
7 | }
|
Helfer schrieb: > Der Swapcode ist ja auch falsch. Passt den niemand mehr auf? tatsache, jetzt fluppt es
>Alternativ wäre auch eine Look-Up Table. Bei 16Byte ist das noch >überschaubar. Keep it simple and stupid :-) Warum blos müssen die Leute für so nen Kiki immer gleich nen Code bauen, obwohl es ein kleines Konstantenarray kurz und schmerzlos erledigen würde?
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.