_maddin
29.07.2008, 18:12
hallo
ich habe ein glcd an meinem mega32 hängen, das bis vorhin noch super lief. ein port war für die daten zuständig, einer als CTRL port. jetzt brauchte ich am Datenport (PORTC) die SDA und SCL leitung. also habe ich statt PC0&PC1 PB0&PB1 mit dem datenport des lcd verlötet, weil die noch frei waren. dann hab ich das programm umgeschrieben, bis ich dachte, so müsste es funktionieren. die lötverbindungen sind einwandfrei, aber es tut sich nix. ich glaube ich habe einen einfachen fehler bei der bitmanipulation in diesen zeilen gemacht, ich komm aber nich drauf was es ist.
statt
DATAPORT=command;
steht jetzt
DATAPORT &=(1<<0)|(1<<1);
DATAPORT |= command&(~((1<<0)|(1<<1)));
DATAPORT2 &=~((1<<0)|(1<<1));
DATAPORT2 |= command&((1<<0)|(1<<1));
wo ist der denkfehler, tut mir etwas leid wenn die frage total dumm ist aber ich hab nen brett vorm kopf.
hier der komplette code:
#define DATAPORT PORTC
#define DATADDR DDRC
#define DATAPIN PINC
#define DATAPORT2 PORTB
#define DATADDR2 DDRB
#define DATAPIN2 PINB
#define CTRLPORT PORTB
#define CTRLDDR DDRB
#define RS 2
#define RW 3
#define E 4
#define lcd_busy _delay_us(2)
void lcd_enable(void){
// Erzeugt eine fallende Flanke am Enable-Pin
CTRLPORT |= (1<<E);
lcd_busy;
CTRLPORT &= ~(1<<E);
lcd_busy;
}
void lcd_writecommand(uint8_t command) {
// Kommandobyte -> HD61830
lcd_busy;
CTRLPORT &= ~(1<<RW); // R/W auf logisch 0 -> W
CTRLPORT |= (1<<RS); // RS auf logisch 1 -> aktiv
DATAPORT &=(1<<0)|(1<<1);
DATAPORT |= command&(~((1<<0)|(1<<1))); // übergebenes Kommandobyte wird ausgegeben
DATAPORT2 &=~((1<<0)|(1<<1));
DATAPORT2 |= command&((1<<0)|(1<<1)); // übergebenes Kommandobyte wird ausgegeben
lcd_enable();
}
void lcd_writedata(uint8_t data) {
// Datenbyte -> HD61830
lcd_busy;
CTRLPORT &= ~(1<<RW); // R/W auf logisch 0 -> W
CTRLPORT &= ~(1<<RS); // RS auf logisch 0 -> inaktiv
DATAPORT &=(1<<0)|(1<<1);
DATAPORT |= data&(~((1<<0)|(1<<1))); // übergebenes Kommandobyte wird ausgegeben
DATAPORT2 &=~((1<<0)|(1<<1));
DATAPORT2 |= data&((1<<0)|(1<<1)); // übergebenes Kommandobyte wird ausgegeben
lcd_enable();
}
void lcd_send(uint8_t command, uint8_t data) {
// Kombination aus Kommando- und Datenbyte
lcd_writecommand(command);
lcd_writedata(data);
}
void lcd_init(unsigned char modus){
// Initialisiert das Display
DATADDR |= ~((1<<0)|(1<<1)); // Datenport wird als Ausgang deklariert
DATADDR2 |= (1<<0)|(1<<1); // Datenport wird als Ausgang deklariert
CTRLDDR |= (1<<RW)|(1<<RS)|(1<<E); // Kommandoport wird als Ausgang deklariert
if(modus == 'c'){
// Charaktermodus
lcd_send(0x00, 0x30); // Mode Control
lcd_send(0x01, 0x75); // Set Character Pitch
lcd_send(0x02, 0x27); // Set Number of Characters
lcd_send(0x03, 0x80); // Set Number of Time Divisions
lcd_send(0x04, 0x07); // Set Cursor Position
}
else{
// Grafikmodus
lcd_send(0x00, 0x32); // Mode Control
lcd_send(0x01, 0x07); // number of bits of 1-byte display data to be displayed
lcd_send(0x02, 0x1d); // number of horizontal bytes
lcd_send(0x03, 0x80); // Set Number of Time Divisions
}
lcd_send(0x08, 0x00); // Set Display Start Low Order Address
lcd_send(0x09, 0x00); // Set Display Start High Order Address
lcd_clear(modus);
}
void lcd_clear(unsigned char modus){
// Löscht das Display
lcd_gotoxy(modus, 0, 0); // Cursor an den Anfang setzen
if(modus == 'c'){
// Charaktermodus
for(uint16_t i=0; i<640; i++) // Alle Chars durchlaufen und löschen
lcd_send(0x0c, 0x20);
}
else{
// Grafikmodus
for(uint16_t i=0; i<3840; i++) // Alle Bytes durchlaufen und löschen
lcd_send(0x0c, 0x00);
}
lcd_gotoxy(modus, 0, 0); // Cursor an den Anfang setzen
}
void lcd_gotoxy(unsigned char modus, uint8_t x, uint8_t y){
// Setzt den Cursor an eine bestimmte Position
uint16_t adress;
if(modus == 'c'){
// Charaktermodus
adress = (y * 40) + x;
}
else{
// Grafikmodus
adress = (y * 30) + x;
}
lcd_send(0x0a, (uint8_t)(adress)); // Set Cursor Address (Low Order)
lcd_send(0x0b, (uint8_t)(adress >> 8)); // Set Cursor Address (High Order)
}
void lcd_setdot(uint8_t x, uint8_t y){
// Setzt ein Pixel an einer bestimmten Position
lcd_gotoxy('g', (x >> 3), y);
lcd_send(0x0f, (x & 0x07));
}
void lcd_cleardot(uint8_t x, uint8_t y){
// Löscht ein Pixel an einer bestimmten Position
lcd_gotoxy('g', (x >> 3), y);
lcd_send(0x0e, (x & 0x07));
}
void lcd_putc(char c){
static char line=0;
if((c == 'ä') | ( c == 'Ä' ) ){
lcd_send(0x0c,0xE1);
}
else if((c == 'ü') | ( c == 'Ü' ) ){
lcd_send(0x0c,0xF5);
}
else if((c == 'ö') | ( c == 'Ö' ) ){
lcd_send(0x0c,0xEF);
}
else if((c == '\n') | ( c == '\r' )){
line++;
if(line==16) line=0;
lcd_gotoxy('c',0,line);
}
else lcd_send(0x0c,c);
}
void lcd_puts(char *string){
uint8_t i=0;
char c = string[0];
while(c != 0) {
lcd_putc(c);
c = string[++i];
}
}
char swapbits(char c){
char swap=0;
for(char bit=0;bit<8;bit++) if(c&(1<<bit)) swap|=(1<<(7-bit));
return swap;
}
void lcd_picture(char* byte){
for(short counter=0;counter<3840;counter++) {
lcd_send(0x0c,swapbits(pgm_read_byte(byte)));
byte++;
}
}
void glcd_puts(unsigned short x, unsigned short y, char *string){
uint8_t i=0;
char c = string[0];
unsigned short xpos=x, ypos=y;
while(c != 0) {
glcd_putc(xpos,ypos,c);
xpos+=6;
if(c=='\n'){
xpos=x;
ypos+=8;
}
c = string[++i];
}
}
void glcd_putc(unsigned short x, unsigned short y, char character) {
unsigned char fontIndex, i, j;
/* The 5x7 character set starts at the '!' character (ASCII index
* number 33) so we subtract 32 from the ASCII character to find the
* index in the 5x7 font table. */
fontIndex = character-32;
/* If the index is out of bounds, bail out */
if (fontIndex > 94)
return;
for (i = 0; i < FONT_WIDTH; i++) {
for (j = 0; j < FONT_HEIGHT; j++) {
/* Check if the bit/pixel is set, paint accoringly to
* the screen */
if (pgm_read_byte(&Font5x7[FONT_WIDTH*fontIndex+i] ) & (1<<j))
lcd_setdot(x, y+j);
else
lcd_cleardot(x, y+j);
}
/* Move the LCD cursor through the font width as well */
x++;
}
}
danke schonmal
ich habe ein glcd an meinem mega32 hängen, das bis vorhin noch super lief. ein port war für die daten zuständig, einer als CTRL port. jetzt brauchte ich am Datenport (PORTC) die SDA und SCL leitung. also habe ich statt PC0&PC1 PB0&PB1 mit dem datenport des lcd verlötet, weil die noch frei waren. dann hab ich das programm umgeschrieben, bis ich dachte, so müsste es funktionieren. die lötverbindungen sind einwandfrei, aber es tut sich nix. ich glaube ich habe einen einfachen fehler bei der bitmanipulation in diesen zeilen gemacht, ich komm aber nich drauf was es ist.
statt
DATAPORT=command;
steht jetzt
DATAPORT &=(1<<0)|(1<<1);
DATAPORT |= command&(~((1<<0)|(1<<1)));
DATAPORT2 &=~((1<<0)|(1<<1));
DATAPORT2 |= command&((1<<0)|(1<<1));
wo ist der denkfehler, tut mir etwas leid wenn die frage total dumm ist aber ich hab nen brett vorm kopf.
hier der komplette code:
#define DATAPORT PORTC
#define DATADDR DDRC
#define DATAPIN PINC
#define DATAPORT2 PORTB
#define DATADDR2 DDRB
#define DATAPIN2 PINB
#define CTRLPORT PORTB
#define CTRLDDR DDRB
#define RS 2
#define RW 3
#define E 4
#define lcd_busy _delay_us(2)
void lcd_enable(void){
// Erzeugt eine fallende Flanke am Enable-Pin
CTRLPORT |= (1<<E);
lcd_busy;
CTRLPORT &= ~(1<<E);
lcd_busy;
}
void lcd_writecommand(uint8_t command) {
// Kommandobyte -> HD61830
lcd_busy;
CTRLPORT &= ~(1<<RW); // R/W auf logisch 0 -> W
CTRLPORT |= (1<<RS); // RS auf logisch 1 -> aktiv
DATAPORT &=(1<<0)|(1<<1);
DATAPORT |= command&(~((1<<0)|(1<<1))); // übergebenes Kommandobyte wird ausgegeben
DATAPORT2 &=~((1<<0)|(1<<1));
DATAPORT2 |= command&((1<<0)|(1<<1)); // übergebenes Kommandobyte wird ausgegeben
lcd_enable();
}
void lcd_writedata(uint8_t data) {
// Datenbyte -> HD61830
lcd_busy;
CTRLPORT &= ~(1<<RW); // R/W auf logisch 0 -> W
CTRLPORT &= ~(1<<RS); // RS auf logisch 0 -> inaktiv
DATAPORT &=(1<<0)|(1<<1);
DATAPORT |= data&(~((1<<0)|(1<<1))); // übergebenes Kommandobyte wird ausgegeben
DATAPORT2 &=~((1<<0)|(1<<1));
DATAPORT2 |= data&((1<<0)|(1<<1)); // übergebenes Kommandobyte wird ausgegeben
lcd_enable();
}
void lcd_send(uint8_t command, uint8_t data) {
// Kombination aus Kommando- und Datenbyte
lcd_writecommand(command);
lcd_writedata(data);
}
void lcd_init(unsigned char modus){
// Initialisiert das Display
DATADDR |= ~((1<<0)|(1<<1)); // Datenport wird als Ausgang deklariert
DATADDR2 |= (1<<0)|(1<<1); // Datenport wird als Ausgang deklariert
CTRLDDR |= (1<<RW)|(1<<RS)|(1<<E); // Kommandoport wird als Ausgang deklariert
if(modus == 'c'){
// Charaktermodus
lcd_send(0x00, 0x30); // Mode Control
lcd_send(0x01, 0x75); // Set Character Pitch
lcd_send(0x02, 0x27); // Set Number of Characters
lcd_send(0x03, 0x80); // Set Number of Time Divisions
lcd_send(0x04, 0x07); // Set Cursor Position
}
else{
// Grafikmodus
lcd_send(0x00, 0x32); // Mode Control
lcd_send(0x01, 0x07); // number of bits of 1-byte display data to be displayed
lcd_send(0x02, 0x1d); // number of horizontal bytes
lcd_send(0x03, 0x80); // Set Number of Time Divisions
}
lcd_send(0x08, 0x00); // Set Display Start Low Order Address
lcd_send(0x09, 0x00); // Set Display Start High Order Address
lcd_clear(modus);
}
void lcd_clear(unsigned char modus){
// Löscht das Display
lcd_gotoxy(modus, 0, 0); // Cursor an den Anfang setzen
if(modus == 'c'){
// Charaktermodus
for(uint16_t i=0; i<640; i++) // Alle Chars durchlaufen und löschen
lcd_send(0x0c, 0x20);
}
else{
// Grafikmodus
for(uint16_t i=0; i<3840; i++) // Alle Bytes durchlaufen und löschen
lcd_send(0x0c, 0x00);
}
lcd_gotoxy(modus, 0, 0); // Cursor an den Anfang setzen
}
void lcd_gotoxy(unsigned char modus, uint8_t x, uint8_t y){
// Setzt den Cursor an eine bestimmte Position
uint16_t adress;
if(modus == 'c'){
// Charaktermodus
adress = (y * 40) + x;
}
else{
// Grafikmodus
adress = (y * 30) + x;
}
lcd_send(0x0a, (uint8_t)(adress)); // Set Cursor Address (Low Order)
lcd_send(0x0b, (uint8_t)(adress >> 8)); // Set Cursor Address (High Order)
}
void lcd_setdot(uint8_t x, uint8_t y){
// Setzt ein Pixel an einer bestimmten Position
lcd_gotoxy('g', (x >> 3), y);
lcd_send(0x0f, (x & 0x07));
}
void lcd_cleardot(uint8_t x, uint8_t y){
// Löscht ein Pixel an einer bestimmten Position
lcd_gotoxy('g', (x >> 3), y);
lcd_send(0x0e, (x & 0x07));
}
void lcd_putc(char c){
static char line=0;
if((c == 'ä') | ( c == 'Ä' ) ){
lcd_send(0x0c,0xE1);
}
else if((c == 'ü') | ( c == 'Ü' ) ){
lcd_send(0x0c,0xF5);
}
else if((c == 'ö') | ( c == 'Ö' ) ){
lcd_send(0x0c,0xEF);
}
else if((c == '\n') | ( c == '\r' )){
line++;
if(line==16) line=0;
lcd_gotoxy('c',0,line);
}
else lcd_send(0x0c,c);
}
void lcd_puts(char *string){
uint8_t i=0;
char c = string[0];
while(c != 0) {
lcd_putc(c);
c = string[++i];
}
}
char swapbits(char c){
char swap=0;
for(char bit=0;bit<8;bit++) if(c&(1<<bit)) swap|=(1<<(7-bit));
return swap;
}
void lcd_picture(char* byte){
for(short counter=0;counter<3840;counter++) {
lcd_send(0x0c,swapbits(pgm_read_byte(byte)));
byte++;
}
}
void glcd_puts(unsigned short x, unsigned short y, char *string){
uint8_t i=0;
char c = string[0];
unsigned short xpos=x, ypos=y;
while(c != 0) {
glcd_putc(xpos,ypos,c);
xpos+=6;
if(c=='\n'){
xpos=x;
ypos+=8;
}
c = string[++i];
}
}
void glcd_putc(unsigned short x, unsigned short y, char character) {
unsigned char fontIndex, i, j;
/* The 5x7 character set starts at the '!' character (ASCII index
* number 33) so we subtract 32 from the ASCII character to find the
* index in the 5x7 font table. */
fontIndex = character-32;
/* If the index is out of bounds, bail out */
if (fontIndex > 94)
return;
for (i = 0; i < FONT_WIDTH; i++) {
for (j = 0; j < FONT_HEIGHT; j++) {
/* Check if the bit/pixel is set, paint accoringly to
* the screen */
if (pgm_read_byte(&Font5x7[FONT_WIDTH*fontIndex+i] ) & (1<<j))
lcd_setdot(x, y+j);
else
lcd_cleardot(x, y+j);
}
/* Move the LCD cursor through the font width as well */
x++;
}
}
danke schonmal