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
Lesezeichen