Hallo

Nach einer längeren Auszeit habe ich nun ein neues RP6-Projekt begonnen:

Bild hier  
Bild hier   Bild hier   Bild hier  

Ich betreibe das 20x4-LCD im 4-bit-Mode (ohne Busy) an den Erweiterungspins 101-104, BPL und BPR (das sind die LEDs 1-6). Die Adapterplatine wird direkt in die entsprechenden Stiftleisten auf der RP6-Platine eingesteckt . Zusätzlich sind auch die Anschlüsse ADC0 und ADC1 angeschlossen, sie liefern die Versorgungsspannung für das Display. XBUS und UBUS sind nicht angeschlossen, die Stecker dienen nur der Stabilität. Die elektrische Verbindung zum Display besteht aus zwei 6-poligen Stiftleisten in die der 16-polige Stecker des LCDs eingesteckt wird:

1 - GND
2 - Vcc (5V)
3 - Kontrast (0-0,5V)
4 - RS Steuer- oder Datenregister (LED3)
5 - R/W Datenrichtung (GND)
6 - E Datenübernahme (LED6)

11 - D4 Datenbit4 (LED1)
12 - D5 Datenbit5 (LED2)
13 - D6 Datenbit6 (LED4)
14 - D7 Datenbit7 (LED5)
15 - A Anode Hintergrundbeleuchtung (5V)
16 - K Kathode Hintergrundbeleuchtung (GND)

Die rausgenagten Löcher in der Adapterplatine schaffen Platz für die überstehenen Bauteile wie Kondensatoren und Quarz. btw sind diese Bauteile nun auch vor tieffliegenden Katzenpfoten geschützt ;)

Zur Ansteuerung habe ich mir ein kleines C-Programm gebastelt. Es verwendet zwar meine abgespeckte RP6-Lib, sollte aber auch mit den orginalen Libs zusammenarbeiten. Geplant ist eine Erweiterung als Task, aber das dauert noch etwas:

Code:
// LCD 20x4 (LMC-SSC4A20) an den LEDs 1-6                         16.7.2008  mic

// 4-Bit-Ansteuerung ohne busy-Abfrage:

// 1 - GND - GND
// 2 - Vcc - Vcc
// 3 - Kontrast (0-0,5V)
// 4 - RS - LS3 (BPR)
// 5 - R/W - GND
// 6 - E - LS6 (BPL)
// 7
// 8
// 9
// 10
// 11 - Data4 - LS1 (101)
// 12 - Data5 - LS2 (102)
// 13 - Data6 - LS4 (103)
// 14 - Data7 - LS5 (104)
// 15 - A - Vcc
// 16 - K - GND

#include "rblib.h"
#include "rblib.c"

#define demospeed 50
#define d4h  (PORTC|=SL1)
#define d4l (PORTC&=~SL1)
#define d5h  (PORTC|=SL2)
#define d5l (PORTC&=~SL2)
#define d6h  (PORTB|=SL4)
#define d6l (PORTB&=~SL4)
#define d7h  (PORTB|=SL5)
#define d7l (PORTB&=~SL5)
#define rsh  (PORTC|=SL3)
#define rsl (PORTC&=~SL3)
#define eh  (PORTB|=SL6)
#define el (PORTB&=~SL6)
//#define vri_on  (PORTA |= 1)
//#define vri_off (PORTA &= ~1)
//#define vra_on  (PORTA |= 2)
//#define vra_off (PORTA &= ~2)

void delay_ms(uint16_t ms)
{
	while(ms--) delay(5); // delay(5) ~ 1,1 ms
// hier müßte bei Verwendung der orginalen Library die Funktion mSleep() stehen:
	// mSleep(ms);
}
void strobe(void)
{
	eh;
	delay_ms(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_ms(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_ms(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_init(void)
{
	DDRC |= 0x70;						// LED1-3 auf Ausgang und low
	PORTC &= ~0x70;
	DDRB |= 0x83;						// LED4-6 auf Ausgang und low
	PORTB &= ~0x83;
	//DDRA |= 3;        				// ADC0 und ADC1 auf Ausgang und low
   //PORTA &= ~3;
	//DDRC |= 0x3;						// SCL und SDA auf Ausgang und low
	//PORTC &= ~0x3;
	rsl;
	delay_ms(100);
	lcd_write8(0b00100000,100);	// Function Set: 4bit-Modus starten
	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_ms(1);
}
int main(void)
{
	uint8_t i;                    // Hilfsvariable
	rblib_init();                 // rblib initialisieren
	lcd_init();                   // lcd initialisieren

	lcd_cls();                    // Display löschen
	lcd_locate(0,0);              // Schreibpositon festlegen
	for(i=0; i<20; i++) {lcd_writeChar('*'); delay_ms(demospeed); }
	lcd_locate(0,1);
	for(i=0; i<20; i++) {lcd_writeChar('a'+i); delay_ms(demospeed/2); }
	lcd_locate(0,2);
	for(i=0; i<20; i++) {lcd_writeChar('A'+i); delay_ms(demospeed/3); }
	lcd_locate(0,3);
	for(i=0; i<10; i++) {lcd_writeChar('0'+i); delay_ms(demospeed/4); }
	for(i=0; i<10; i++) {lcd_writeChar('0'+i); delay_ms(demospeed/4); }

	delay_ms(2000);
	lcd_cls();
	lcd_locate(2,0);
	lcd_writeString("RP6 ROBOT SYSTEM");
	lcd_locate(0,2);
   lcd_writeString("LC-Display an LED1-6");
	lcd_locate(9,3);
   lcd_writeString("16.7.08 mic");
   
	while(1){
	}
	return 0;
}
Zusammengewurstelt nach den Infos aus:
https://www.roboternetz.de/wissen/in...D-Modul_am_AVR
http://www.mikrocontroller.net/artic...-Tutorial:_LCD
und dem Datenblatt des Displays


Noch ein Filmchen dazu:
Bild hier  
http://www.youtube.com/watch?v=2UtIABxSUXs

Gruß

mic