odpojený LCD

V prográmkách na AVR ATmega16 používám displej (CodeVision kompilátor), ale teď jsem jednou nechtěně displej odpojil a nemohl jsem přijít na to, proč zařízeníčko neběží. dlouho mě nenapadlo mrknout na odpojený konektor k LCD. Zjistil jsem, že program vytuhne pred While někde po lcd inicializaci, čeká a čeká. Zařízení není v principu nutné k ovládání displej a to by znamenalo, že když se něco porouchá směrem od čipu k LCD, tak zařízení prostě vytuhne. Pomoci by mohl watchdog, ale program se po restartu dostane znova do stejného bodu a aplikace se zastaví. Jako knihovnu používám jejich standardní, dovolím si přiložit viz níže. Mělo by se něco upravit v driveru displeje nebo jak něčím snadno ošetřit hlavní zdroják?

[code]/* LCD driver routines

CodeVisionAVR C Compiler
© 1998-2007 Pavel Haiduc, HP InfoTech S.R.L.
*/

#asm
.equ __lcd_direction=__lcd_port-1
.equ __lcd_pin=__lcd_port-2
.equ __lcd_rs=0
.equ __lcd_rd=1
.equ __lcd_enable=2
.equ __lcd_busy_flag=7
#endasm

#pragma used+
static unsigned char _base_y[4]={0x80,0xc0};
unsigned char _lcd_x,_lcd_y,_lcd_maxx;
#pragma used-

static void _lcd_delay(void)
{
#asm
ldi r31,15
__lcd_delay0:
dec r31
brne __lcd_delay0
#endasm
}

void _lcd_ready(void)
{
#asm
in r26,__lcd_direction
andi r26,0xf ;set as input
out __lcd_direction,r26
sbi __lcd_port,__lcd_rd ;RD=1
cbi __lcd_port,__lcd_rs ;RS=0
__lcd_busy:
#endasm
_lcd_delay();
#asm
sbi __lcd_port,__lcd_enable ;EN=1
#endasm
_lcd_delay();
#asm
in r26,__lcd_pin
cbi __lcd_port,__lcd_enable ;EN=0
#endasm
_lcd_delay();
#asm
sbi __lcd_port,__lcd_enable ;EN=1
#endasm
_lcd_delay();
#asm
cbi __lcd_port,__lcd_enable ;EN=0
sbrc r26,__lcd_busy_flag
rjmp __lcd_busy
#endasm
}

static void _lcd_write_nibble(void)
{
#asm
andi r26,0xf0
or r26,r27
out __lcd_port,r26 ;write
sbi __lcd_port,__lcd_enable ;EN=1
#endasm
_lcd_delay();
#asm
cbi __lcd_port,__lcd_enable ;EN=0
#endasm
_lcd_delay();
}

void _lcd_write_data(unsigned char data)
{
#asm
cbi __lcd_port,__lcd_rd ;RD=0
in r26,__lcd_direction
ori r26,0xf0 | (1<<__lcd_rs) | (1<<__lcd_rd) | (1<<__lcd_enable) ;set as output
out __lcd_direction,r26
in r27,__lcd_port
andi r27,0xf
ld r26,y
#endasm
_lcd_write_nibble(); //RD=0, write MSN
#asm
ld r26,y
swap r26
#endasm
_lcd_write_nibble(); //write LSN
#asm
sbi __lcd_port,__lcd_rd ;RD=1
#endasm
}

/* write a byte to the LCD character generator or display RAM */
void lcd_write_byte(unsigned char addr, unsigned char data)
{
_lcd_ready();
_lcd_write_data(addr);
_lcd_ready();
#asm
sbi __lcd_port,__lcd_rs ;RS=1
#endasm
_lcd_write_data(data);
}

static void _lcd_read_nibble(void)
{
#asm
sbi __lcd_port,__lcd_enable ;EN=1
#endasm
_lcd_delay();
#asm
in r30,__lcd_pin ;read
cbi __lcd_port,__lcd_enable ;EN=0
#endasm
_lcd_delay();
#asm
andi r30,0xf0
#endasm
}

static unsigned char lcd_read_byte0(void)
{
_lcd_delay();
_lcd_read_nibble(); // read MSN
#asm
mov r26,r30
#endasm
_lcd_read_nibble(); // read LSN
#asm
cbi __lcd_port,__lcd_rd ;RD=0
swap r30
or r30,r26
#endasm
}

/* read a byte from the LCD character generator or display RAM */
unsigned char lcd_read_byte(unsigned char addr)
{
_lcd_ready();
_lcd_write_data(addr);
_lcd_ready();
#asm
in r26,__lcd_direction
andi r26,0xf ;set as input
out __lcd_direction,r26
sbi __lcd_port,__lcd_rs ;RS=1
#endasm
return lcd_read_byte0();
}

/* set the LCD display position x=0…39 y=0…3 */
void lcd_gotoxy(unsigned char x, unsigned char y)
{
_lcd_ready(); // RS=0
_lcd_write_data(_base_y[y]+x);
_lcd_x=x;
_lcd_y=y;
}

// clear the LCD
void lcd_clear(void)
{
_lcd_ready(); // RS=0
_lcd_write_data(2); // cursor home
_lcd_ready();
_lcd_write_data(0xc); // cursor off
_lcd_ready();
_lcd_write_data(1); // clear
_lcd_x=_lcd_y=0;
}

void lcd_putchar(char c)
{
#asm
push r30
push r31
ld r26,y
set
cpi r26,10
breq __lcd_putchar1
clt
#endasm
++_lcd_x;
if (_lcd_x>_lcd_maxx)
{
#asm("__lcd_putchar1:")
++_lcd_y;
lcd_gotoxy(0,_lcd_y);
#asm(“brts __lcd_putchar0”)
};
#asm
rcall __lcd_ready
sbi __lcd_port,__lcd_rs ;RS=1
ld r26,y
st -y,r26
rcall __lcd_write_data
__lcd_putchar0:
pop r31
pop r30
#endasm
}

// write the string str located in SRAM to the LCD
void lcd_puts(char *str)
{
char k;
while (k=*str++) lcd_putchar(k);
}

// write the string str located in FLASH to the LCD
void lcd_putsf(char flash *str)
{
char k;
while (k=*str++) lcd_putchar(k);
}

static void _long_delay(void)
{
#asm
clr r26
clr r27
__long_delay0:
sbiw r26,1 ;2 cycles
brne __long_delay0 ;2 cycles
#endasm
}

static void _lcd_init_write(unsigned char data)
{
#asm
cbi __lcd_port,__lcd_rd ;RD=0
in r26,__lcd_direction
ori r26,0xf7 ;set as output
out __lcd_direction,r26
in r27,__lcd_port
andi r27,0xf
ld r26,y
#endasm
_lcd_write_nibble(); //RD=0, write MSN
#asm
sbi __lcd_port,__lcd_rd ;RD=1
#endasm
}

// initialize the LCD controller
unsigned char lcd_init(unsigned char lcd_columns)
{
#asm
cbi __lcd_port,__lcd_enable ;EN=0
cbi __lcd_port,__lcd_rs ;RS=0
#endasm
_lcd_maxx=lcd_columns;
_base_y[2]=lcd_columns+0x80;
_base_y[3]=lcd_columns+0xc0;
_long_delay();
_lcd_init_write(0x30);
_long_delay();
_lcd_init_write(0x30);
_long_delay();
_lcd_init_write(0x30);
_long_delay();
_lcd_init_write(0x20);
_long_delay();
_lcd_write_data(0x28);
_long_delay();
_lcd_write_data(4);
_long_delay();
_lcd_write_data(0x85);
_long_delay();
#asm
in r26,__lcd_direction
andi r26,0xf ;set as input
out __lcd_direction,r26
sbi __lcd_port,__lcd_rd ;RD=1
#endasm
if (lcd_read_byte0()!=5) return 0;
_lcd_ready();
_lcd_write_data(6);
lcd_clear();
return 1;
}[/code]

AHOJ,Pouzivam taky (CodeVision kompilátor),ale nemam s nim takove problemy.Mne beha displej uplne v pohode,i kdyz ho na chvili odpojim. To spis budes mit chybku nekde ve zdrojaku.

Já už jsem měl displej zadrátovaný, RW a RS nepropojené s procesorem, RW uzemněné. Aby to chodilo, upravil jsem funkci _lcd_ready() takto

[code]void del_5ms(void) //
{ //
#asm //
ldi R22, $65 ;; přidáno
WGLOOP0: ldi R23, $A4 ;;
WGLOOP1: dec R23 ;;
brne WGLOOP1 ;;
dec R22 ;;
brne WGLOOP0 ;;
#endasm
}

void _lcd_ready(void)
{
#asm
in r26,__lcd_direction
andi r26,0xf ;set as input
out __lcd_direction,r26
; sbi __lcd_port,__lcd_rd ;RD=1
cbi __lcd_port,__lcd_rs ;RS=0
__lcd_busy:
; rcall __lcd_delay
; sbi __lcd_port,__lcd_enable ;EN=1
; rcall __lcd_delay
; sbic __lcd_pin,__lcd_busy_flag
; rjmp __lcd_busy
; cbi __lcd_port,__lcd_enable ;EN=0
#endasm
del_5ms(); ////////////////////////
}
[/code]

Zapomněl jsem napsat:
Neupravená funkce čeká na odpověď z LCD-RW, takže když je displej odpojený, čeká stále.
Upravená funkce na odpověď nečeká.