LCD alternativ anschließen

OP #2071517
Lesenswert?

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?
Gast #2071530
Lesenswert?

> 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.
OP #2071546
Lesenswert?

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.
Gast #2071556
Lesenswert?

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;
Gast #2071569
Lesenswert?

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
Gast #2071594
Lesenswert?

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;
}
#2071605
Lesenswert?

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
OP #2071686
Lesenswert?

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.
OP #2071704
Lesenswert?

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
}
Gast #2071724
Lesenswert?

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
}
Gast #2071805
Lesenswert?

>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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren