Hallo

Nachdem schon einige I2C-LCD-Lösungen für die bee vorgestellt wurden,
möchte ich euch nun mal meine Variante des Themas zeigen:

Bild hier   Bild hier   Bild hier   Bild hier   Bild hier  
Bild hier  

Das 20x4-LCD ist am Port C parallel zu den Fühlertastern über die erweiterten Ports X1 und X4 angeschlossen und belegt deshalb nur zwei der freien Mega16-Portpins an X4 (PC0 und PC1). Die zusätzlichen Taster liegen parallel zu den Fühlertasten und werden im Wechsel mit dem LCD angesprochen. Die Grundlagen dafür hatte ich mir schon beim "LCD an RP6-Base" erarbeitet:

https://www.roboternetz.de/phpBB2/ze...ag.php?t=41805

Das Pinout und die angepassten LCD-Funktionen sehen so aus:
Code:
// Paralleles LCD im 4-Bit-Mode ohne busy an nibobee               28.12.2009 mic

// 4-Bit-Ansteuerung ohne busy-Abfrage an Port C und erweiterten X1/X4:

// 1 - GND - GND                      X1                       X4
// 2 - Vcc - Vcc                  PA0    PC4 11         14 PC7    PC0 6
// 3 - Kontrast (0-0,5V)          PA1    PC5 12         13 PC6    PC1 4
// 4 - RS - PC1                   GND                             GND 1
// 5 - R/W - GND                  VCC                             VCC 2
// 6 - E - PC0
// 7
// 8
// 9
// 10
// 11 - Data4 - PC4
// 12 - Data5 - PC5
// 13 - Data6 - PC6
// 14 - Data7 - PC7
// 15 - A - Vcc
// 16 - K - GND

// selbes LCD am RP6-Base:
// https://www.roboternetz.de/phpBB2/ze...ag.php?t=41805


#define d4h  (PORTC|=(1<<PC4))
#define d4l (PORTC&=~(1<<PC4))
#define d5h  (PORTC|=(1<<PC5))
#define d5l (PORTC&=~(1<<PC5))
#define d6h  (PORTC|=(1<<PC6))
#define d6l (PORTC&=~(1<<PC6))
#define d7h  (PORTC|=(1<<PC7))
#define d7l (PORTC&=~(1<<PC7))
#define rsh  (PORTC|=(1<<PC1))
#define rsl (PORTC&=~(1<<PC1))
#define eh   (PORTC|=(1<<PC0))
#define el  (PORTC&=~(1<<PC0))

void strobe(void)
{
   eh;
   delay(1);
   el;
}
void lcd_write8(uint8_t wert, uint8_t pause)
{
   if(wert & 16) d4h; else d4l;
   if(wert & 32) d5h; else d5l;
   if(wert & 64) d6h; else d6l;
   if(wert & 128) d7h; else d7l;
   strobe();
   delay(pause);
}
void lcd_write4(uint8_t wert, uint8_t pause)
{
   if(wert & 16) d4h; else d4l; // high nipple
   if(wert & 32) d5h; else d5l;
   if(wert & 64) d6h; else d6l;
   if(wert & 128) d7h; else d7l;
   strobe();
   if(wert & 1) d4h; else d4l; // low nipple
   if(wert & 2) d5h; else d5l;
   if(wert & 4) d6h; else d6l;
   if(wert & 8) d7h; else d7l;
   strobe();
   delay(pause);
}
void lcd_cls(void)
{
   rsl;
      lcd_write4(1,2);
   rsh;
}
void lcd_locate(uint8_t x, uint8_t y)
{
   rsl;
   switch (y) {
      case 0: lcd_write4(0x80+x, 40); break;    // 0. Zeile
      case 1: lcd_write4(0xc0+x, 40); break;    // 1. Zeile
      case 2: lcd_write4(0x94+x, 40); break;    // 2. Zeile
      case 3: lcd_write4(0xd4+x, 40); break;    // 3. Zeile
   }
   rsh;
}
void lcd_writeChar(uint8_t zeichen)
{
   lcd_write4(zeichen,1);
}
void lcd_writeString(char *string)
{
   while(*string)
      lcd_writeChar(*string++);
}
void lcd_writeInteger(int16_t number, uint8_t base)
{
   char buffer[17];
   itoa(number, &buffer[0], base);
   lcd_writeString(&buffer[0]);
}
uint8_t lcd_getkeys(void)
{
   uint8_t keys=0;
   el;
   DDRC &= ~0b11110010;                  	// LCD-Pins auf Eingang mit PullUp
   PORTC |= 0b11110010;
   delay(1);

   if(PINC & (1<<PC1)) keys |= 16;
   if(PINC & (1<<PC4)) keys |= 8;
   if(PINC & (1<<PC5)) keys |= 4;
   if(PINC & (1<<PC6)) keys |= 2;
   if(PINC & (1<<PC7)) keys |= 1;

   DDRC |= 0b11110011;							// LCD-Pins auf Ausgang und low
   PORTC &= ~0b11110011;                // nanu ???
   return(~keys & 0b11111);
}

uint8_t lcd_first_init=1;
void lcd_init(void)
{
   DDRC |= 0b11110011;                  	// LCD-Pins auf Ausgang und low
   PORTC &= ~0b11110011;
   rsl;
   delay(100);
   if(lcd_first_init)
	{
		lcd_write8(0b00100000,100);			// Function Set: 4bit-Modus starten
		lcd_first_init=0;
	}
   lcd_write4(0b00101000,40);      	// Function Set: 2 Zeilen, Font 0 (0010NFxx)
   lcd_write4(0b00000001,40);      	// Display Clear
   lcd_write4(0b00000110,40);     	// Entry Mode Set: inc, no shift
   lcd_write4(0b00001100,40);      	// Display On and Cursor
   //lcd_write4(0b00001111,40);   	// Display On and Cursor
   rsh;
   delay(1);
}
Mein aktueller, ungeputzter Arbeitscode sieht grad so aus:
Code:
 // nibobee: LCD 20x4 (LMC-SSC4A20) an Port C                   28.12.2009  mic

#include <nibobee/iodefs.h>
#include <nibobee/analog.h>
#include <nibobee/delay.h>
#include <nibobee/base.h>
#include <nibobee/led.h>
#include <stdlib.h>
#include "lcd_lib.c"

int main(void)
{
	uint8_t i=0;                  // Hilfsvariable
   led_init();                   // ist ätzend die Libteile einzubinden...
   analog_init();
	lcd_init();                   // lcd initialisieren
   lcd_cls();                    // lcd Inhalt löschen
   lcd_locate(2,0);
   lcd_writeString("NIBOBee mit LCD");
   lcd_locate(4,2);
   lcd_writeString("28.12.09 mic");
   led_set(0,1);
   delay(2000);
   led_set(0,0);
   lcd_locate(0,2);
   lcd_writeString("Bitte Taste druecken");
   while(!lcd_getkeys());
   i=16;
   
   while(1)
   {
      if(i & 8) led_set(0,1); else led_set(0,0);
      if(i & 4) led_set(1,1); else led_set(1,0);
      if(i & 2) led_set(2,1); else led_set(2,0);
      if(i & 1) led_set(3,1); else led_set(3,0);
      if(i & 16)
		{
			lcd_init();
			lcd_cls();
			lcd_writeString("Liniensensoren");
			while(lcd_getkeys());
			lcd_locate(0,1);
   		lcd_writeString("L:");
   		lcd_locate(0,2);
   		lcd_writeString("C:");
   		lcd_locate(0,3);
   		lcd_writeString("R:");
		}

   	lcd_locate(3,1);
		lcd_writeInteger(analog_getValue(5),10);
   	lcd_locate(3,2);
		lcd_writeInteger(analog_getValue(6),10);
   	lcd_locate(3,3);
		lcd_writeInteger(analog_getValue(7),10);
		delay(100);
      i=lcd_getkeys();
	}
   return 0;
}
Die AAAs sind einfach zu klein.

Gruß

mic