Hi Leute,
derzeit hänge ich mal wieder an einem nervigen kleinen Problemchen... Ich versuche mir ne Lib für mein LCD-Board (LCD 204B LED) aufzubauen, vermutlich für den Kontroller KS0073 (Das LCD war Teil eines Lern-Experimentier-Boards und ich habe keine gute Dokumentation, bei der ich mir 100% sicher bin, dass sie passt). Eigentlich funktioniert auch alles gut, bis auf das Auslesen des Speichers. Dies brauche ich eigentlich nur um das Busy Flag auszulesen. Wenn ich auf die BF Abfrage verzichte und stattdessen eine kleine Wartezeit einbauen funktioniert auch alles einwandfrei. Aber ich möchte umbedingt den Fehler finden, alles andere befriedigt mich nicht.

Jaaa, betrieben wird das LCD im 4-Bit Modus, die unteren Datenleitungen (DB0-DB3) habe ich Offen gelassen, da das LCD wohl interne Pull-Up's verwendet. Ansonsten ist alles direkt mit möglichst kurzen Leitungen auf meinem Experimentierboard mit einem ATmega 8 angeschlossen.

Also das Problem vermute ich in dieser Funktion
Code:
void lcd_busy(void)
{    uint8_t rep;
    
    P_DD_DDR &= (~(0x0F << DD));        //Data-Port as Input
    SET_DD(0x00);                        //No internal Pull-Up's!
    
    RS_0;                                //Instruction Register
    RW_1;                                //Read-Mode
    _delay_us( t_W_RS_RW );
    
    do
    {    
        #ifdef _4_bit_mode_
                
                EN_1;
                _delay_us( t_H_EN );                //Wait for LCD: 5us
                        
                rep = ( (P_DD_IN >> DD) << 4 );        //Read high nibble
                EN_0;
                _delay_us( t_L_EN );                //Wait for LCD: 5us
                        
                EN_1;
                _delay_us( t_H_EN );
                
                rep |= ( (P_DD_IN >> DD) & 0x0F);    //Read low nibble
                EN_0;
                _delay_us( t_L_EN );
                                
        #else
                EN_1;
                _delay_us( t_H_EN);
                
                rep = P_DD_IN;
                EN_0;
                _delay_us( t_L_EN );
                
        #endif
                
    }while( 0x80 & rep );                    //Check Busy Flag
    
    RW_0;
}
Die Konstanten habe ich hier nochmal einzeln
Code:
#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>
#include "uart.h"

/////////////////////////////////////////////////////////////////Mode////////////////////////////////////////////
#define _4_bit_mode_

/////////////////////////////////////////////////////////////////Port Constants//////////////////////////////////
#define RS                 7
#define P_RS            PORTD
#define P_RS_DDR        DDRD

#define RW                0
#define P_RW            PORTB
#define P_RW_DDR        DDRB

#define EN                 6
#define P_EN            PORTD
#define P_EN_DDR        DDRD

#define DD                 2
#define P_DD            PORTD
#define P_DD_IN            PIND
#define P_DD_DDR        DDRD

/////////////////////////////////////////////////////////////////Time delays/////////////////////////////////////////////

///us
#define t_H_EN 5
#define t_L_EN 5
#define t_W_RS_RW 1
///ms
#define t_Init_1 100
#define t_Init_2 5
        
/////////////////////////////////////////////////////////////////Commands for Bus/////////////////////////////////////////
#define RS_1        P_RS |=  _BV(RS)
#define RS_0        P_RS &= ~_BV(RS)

#define RW_1        P_RW |=  _BV(RW)
#define RW_0        P_RW &= ~_BV(RW)

#define EN_1        P_EN |=  _BV(EN)
#define EN_0        P_EN &= ~_BV(EN)

/////////////////////////////////////////////////////////////////Commands and Addresses///////////////////////////////////
#define CLEAR_SCREEN    0x01
#define RETURN_HOME     0x02
#define ENTRY_MODE        0x04
    #define ID            0x02
    #define S            0x01
#define DISPLAY_CON        0x08
    #define D            0x04
    #define C            0x02
    #define B            0x01
#define SHIFTING        0x10
    #define SC            0x08
    #define RL            0x04
#define FUNCTION_SET    0x20
    #define DL            0x10
    #define N            0x08
    #define F            0x04
#define CG_ADD_SET        0x40
#define DD_ADD_SET         0x80
    #define Line_1         0x00
    #define Line_2         0x40
    #define Line_3         0x14
    #define Line_4         0x54

#ifdef _4_bit_mode_
    #define SET_DD(x)        P_DD &= ~(0x0F << DD);\
                            P_DD |= ((x) << DD)                        
#else
    #define SET_DD(x)        P_DD = (x)
#endif
Und Sicherheitshalber hier nochmal die ganze Lib, an der ich jetzt arbeite
Code:
/////////////////////////////////////////////////////////////////Display Functions////////////////////////////////////////
void delay_ms(uint16_t ms)
{
    for(uint16_t t = 0; t <= ms; t++)    _delay_ms(1);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Set_P_DD( uint8_t c)
{    
    EN_1;
        
    #ifdef _4_bit_mode_
            SET_DD( c >> 4 );        //Put high Nibble on Pin's
            _delay_us( t_H_EN );
        
            EN_0;                    //LCD reads
            _delay_us(t_L_EN);
        
            EN_1;
            SET_DD( 0x0F & c );        //Put low nibble on Pin's
    #else
            P_DD = c;
    #endif
    
    _delay_us( t_H_EN );
    
    EN_0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lcd_busy(void)
{    uint8_t rep;
    
    P_DD_DDR &= (~(0x0F << DD));        //Data-Port as Input
    SET_DD(0x00);                        //No internal Pull-Up's!
    
    RS_0;                                //Instruction Register
    RW_1;                                //Read-Mode
    _delay_us( t_W_RS_RW );
    
    do
    {    
        #ifdef _4_bit_mode_
                
                EN_1;
                _delay_us( t_H_EN );                //Wait for LCD: 5us
                        
                rep = ( (P_DD_IN >> DD) << 4 );        //Read high nibble
                EN_0;
                _delay_us( t_L_EN );                //Wait for LCD: 5us
                        
                EN_1;
                _delay_us( t_H_EN );
                
                rep |= ( (P_DD_IN >> DD) & 0x0F);    //Read low nibble
                EN_0;
                _delay_us( t_L_EN );
                                
        #else
                EN_1;
                _delay_us( t_H_EN);
                
                rep = P_DD_IN;
                EN_0;
                _delay_us( t_L_EN );
                
        #endif
                
    }while( 0x80 & rep );                    //Check Busy Flag
    
    RW_0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lcd_cmd( uint8_t cmd )
{    
    delay_ms(1);                            //eigentlich lcd_busy();
    
    RS_0;
    RW_0;
    _delay_us(t_W_RS_RW);
    
    Set_P_DD( cmd );
        
    RS_1;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lcd_put( uint8_t dd )
{        
    delay_ms(1);                            //eigentlich lcd_busy();

    Set_P_DD( dd );    
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lcd_init( void )
{    uint8_t i;
    
    P_RS_DDR |= (1 << RS);                    //as Output
    P_RW_DDR |= (1 << RW);
    P_EN_DDR |= (1 << EN);
    
    #ifdef _4_bit_mode_
                P_DD_DDR |= (0x0F << DD);    //as Output
    #else
                P_DD_DDR = 0xFF;
    #endif
        
    RS_0;
    RW_0;
    
    delay_ms(t_Init_1);
    
    #ifdef _4_bit_mode_
                SET_DD( (FUNCTION_SET + DL) >> 4 );
    #else    
                SET_DD( FUNCTION_SET + DL );
    #endif
    
    for( i=0; i<=2; i++)                    //3x Function setting
    {    
        EN_1;
        _delay_us( t_H_EN );
        EN_0;
        _delay_us( t_L_EN );
        delay_ms(t_Init_2);
    }
        
    lcd_cmd( FUNCTION_SET + N );            //2/4 line display
    lcd_cmd( DISPLAY_CON + D + C + B );        //Display:ON, Cursor:ON, Blink: ON
    lcd_cmd( ENTRY_MODE + ID );                //Increment Cursor
    lcd_cmd( CLEAR_SCREEN );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lcd_write( const char *dd )
{
    while( *dd != '\0' )    lcd_put( *dd++ );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lcd_pos( uint8_t x, uint8_t y )
{
    uint8_t add;
    
    switch (y)
    {    case 1:        add = DD_ADD_SET + Line_1 + x;
                    break;
        case 2:        add = DD_ADD_SET + Line_2 + x;
                    break;
        case 3:        add = DD_ADD_SET + Line_3 + x;
                    break;
        case 4:        add = DD_ADD_SET + Line_4 + x;
                    break;
        default:    return;
    }
    
    lcd_cmd( add );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lcd_put_bin( uint8_t c )
{
    for(uint8_t j=0x80; j>= 0x01; j>>=1 )
    {    
        if( j == 0x08 )        lcd_put( 0x7C );
        if( c & j )            lcd_put( 0xFF );
        else                lcd_put( 0x20 );
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lcd_CG ( uint8_t add, uint8_t *c)
{
    add |= CG_ADD_SET;
    
    lcd_cmd( add );
    
    for (uint8_t i = 0; i<=7; i++)        lcd_cmd( c[i] );
    
}
So ich bin für jeden Tipp und jede Anregung sehr dankbar. Außerdem würde mich es mal interessieren wie Ihr die Lesbarkeit des Codes findet.

Mit freundlichen Grüßen Crowdy