radbruch
29.12.2009, 15:24
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:
http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd1_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd1.jpg) http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd2_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd2.jpg) http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd3_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd3.jpg) http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd4_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd4.jpg) http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd5_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd5.jpg)
http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd6_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd6.jpg)
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/zeigebeitrag.php?t=41805
Das Pinout und die angepassten LCD-Funktionen sehen so aus:
// 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/zeigebeitrag.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:
// 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
Nachdem schon einige I2C-LCD-Lösungen für die bee vorgestellt wurden,
möchte ich euch nun mal meine Variante des Themas zeigen:
http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd1_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd1.jpg) http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd2_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd2.jpg) http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd3_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd3.jpg) http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd4_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd4.jpg) http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd5_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd5.jpg)
http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd6_klein.jpg (http://radbruch.bplaced.net/robot/nibobee/lcd/nibobee-lcd6.jpg)
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/zeigebeitrag.php?t=41805
Das Pinout und die angepassten LCD-Funktionen sehen so aus:
// 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/zeigebeitrag.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:
// 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