PDA

View Full Version : LCD freeze



harryweb
- 30th September 2009, 13:21
HI,

I'm using a 16f648A running at 4MHz. Using usart @ 9600Bds

When many data are received, sometimes the LCD freeze, sometimes not...
Any help ?


' **********************************
' * Programme de gestion de l'afficheur LCD *
' * relié à la carte de commande des *
' * des atténuateurs programmables. *
' * nom du programme: affmtouch.bas *
' * PIC16f628, marquage CI: 10C *
' **********************************

' définition des pins utilisées
'a.0 = LCD D4
'a.1 = LCD D5
'a.2 = LCD D6
'a.3 = LCD D7
'a.4 = LCD RS avec pullup
'b.1 = RX
'b.3 = LCD Enable
'b.4 = détection mode auto/manuel
'
' ***********************************************

CMCON = 7
DEFINE OSC 4
trisa = %00000000
trisb = %00010010
portb = 0


c1 var byte
d1 var byte
u1 var byte
c2 var byte
d2 var byte
u2 var byte
c3 var byte
d3 var byte
u3 var byte
c4 var byte
d4 var byte
u4 var byte
voie var byte
x var byte
name var bit ' mode rename
mode var bit ' 1 = automatique
da1 var byte ' digit 1 du nom de la premiere voie
da2 var byte
da3 var byte
da4 var byte
db1 var byte
db2 var byte
db3 var byte
db4 var byte
dc1 var byte
dc2 var byte
dc3 var byte
dc4 var byte
dd1 var byte
dd2 var byte
dd3 var byte
dd4 var byte
n1 var byte
n2 var byte
n3 var byte
n4 var byte
dgt var byte
dgt1 var byte
dgt2 var byte
dgt3 var byte
dgt4 var byte
GP VAR BYTE ' GP variable
BytesIn VAR BYTE[30] ' Up to 30 bytes
ByteCnt VAR BYTE ' Index pointer
OERR VAR RCSTA.1 ' Alias USART over-run bit
CREN VAR RCSTA.4 ' Alias USART continuous receive enable bit
RCIF VAR PIR1.5 ' Alias USART received character interrupt flag bit
pos var byte 'position du curseur LCD
val var byte

pause 10 '10 milli secondes de pause

c1 = 0
d1 = 0
u1 = 0
c2 = 0
d2 = 0
u2 = 0
c3 = 0
d3 = 0
u3 = 0
c4 = 0
d4 = 0
u4 = 0
x = 0
pos = 1

RCSTA = $90 ' Enable serial port & continuous receive
TXSTA = $24 ' Enable transmit, BRGH = 1
SPBRG = 25 ' 9600 Baud @ 4MHz, 0,16%


INTCON = 0 ' Disable interrupts
ByteCnt = 0

high portb.7

debut:
IF PORTB.4 = 1 THEN
LCDOUT $FE,2," mode: remote "
mode = 1
ELSE
LCDOUT $FE,2," mode: manual "
mode = 0
ENDIF
dgt1 = 32 'espace
dgt2 = 32
dgt3 = 32
dgt4 = 32
LCDOUT $FE,$94,"---------+---------"

Main:

IF mode = 0 AND PORTB.4 = 1 THEN 'si passage en mode auto
LCDOUT $FE,2," mode: remote "
mode = 1
ENDIF
IF mode = 1 AND PORTB.4 = 0 THEN 'si passage en mode manuel
LCDOUT $FE,2," mode: manual "
mode = 0
ENDIF

IF RCIF THEN ' If RCIF=1 there's a new character in RCREG
BytesIn[ByteCnt]=RCREG ' Yes. Then store character in array
IF BytesIn[ByteCnt]=10 THEN OutMsg ' LF (0A)
ByteCnt=ByteCnt+1 ' Increment element index pointer
ENDIF
IF !OERR THEN Main ' If NOT over-run, then re-cycle
CREN = 0 ' Yes. Over-run condition is present, so clear it
CREN = 1 ' Re-enable & clear over-run condition
goto main

OutMsg:
IF BytesIn[0] = 82 THEN rename '(R) passage en mode rename

IF BytesIn[0] = 65 THEN ' (A) rx normal de la comatt

for x = 13 to 28
IF BytesIn[x] < 48 or BytesIn[x] > 90 then 'ASCII valide (nom des voies)?
gosub reset
goto Main
endif
next x

for x = 1 to 12
IF BytesIn[x] < 48 or BytesIn[x] > 57 then 'ASCII valide (chiffres seuls)?
gosub reset
goto Main
endif
next x

c1 = BytesIn[1]
d1 = BytesIn[2]
u1 = BytesIn[3]
c2 = BytesIn[4]
d2 = BytesIn[5]
u2 = BytesIn[6]
c3 = BytesIn[7]
d3 = BytesIn[8]
u3 = BytesIn[9]
c4 = BytesIn[10]
d4 = BytesIn[11]
u4 = BytesIn[12]
da1 = BytesIn[13]
da2 = BytesIn[14]
da3 = Bytesin[15]
da4 = BytesIn[16]
db1 = BytesIn[17]
db2 = BytesIn[18]
db3 = Bytesin[19]
db4 = BytesIn[20]
dc1 = BytesIn[21]
dc2 = BytesIn[22]
dc3 = Bytesin[23]
dc4 = BytesIn[24]
dd1 = BytesIn[25]
dd2 = BytesIn[26]
dd3 = Bytesin[27]
dd4 = BytesIn[28]

IF c1 = 48 THEN
c1 = 32
ENDIF
IF c2 = 48 THEN
c2 = 32
ENDIF
IF c3 = 48 THEN
c3 = 32
ENDIF
IF c4 = 48 THEN
c4 = 32
ENDIF

LCDOUT $FE,$C0,c2,d2,".",u2," ",db1,db2,db3,db4,"| ",dd1,dd2,dd3,dd4," ",c4,d4,".",u4
LCDOUT $FE,$D4,c1,d1,".",u1," ",da1,da2,da3,da4,"| ",dc1,dc2,dc3,dc4," ",c3,d3,".",u3
GOsub reset
goto main
endif

gosub reset
goto Main

reset:
FOR GP=0 TO ByteCnt ' Clear array bytes 0 to ByteCnt
BytesIn[GP]=0
NEXT GP
ByteCnt=0 ' Reset index pointer back to first element
WHILE RCIF ' Trash any left over characters in RCREG buffer
GP=RCREG ' after EOM is received
WEND
RETURN


rename:
LCDOUT $FE,1," Rename "
select case BytesIn[1]
case 48
n1 = da1 : n2 = da2 : n3 = da3 : n4 = da4
case 49
n1 = db1 : n2 = db2 : n3 = db3 : n4 = db4
case 50
n1 = dc1 : n2 = dc2 : n3 = dc3 : n4 = dc4
case 51
n1 = dd1 : n2 = dd2 : n3 = dd3 : n4 = dd4
case else
gosub reset
goto main
end select

lcdout n1,n2,n3,n4
LCDOUT $FE,$C0," Press: Max to enter"
lcdout $FE,$94," Min to Exit"
gosub reset

'attente que la comatt envoie le "V" de validation ou "Go" exit
loop1:
IF RCIF THEN ' If RCIF=1 there's a new character in RCREG
BytesIn[ByteCnt]=RCREG ' Yes. Then store character in array
IF BytesIn[ByteCnt]=10 THEN outloop1 ' LF (0A)
ByteCnt=ByteCnt+1 ' Increment element index pointer
ENDIF
IF !OERR THEN loop1 ' If NOT over-run, then re-cycle
CREN = 0 ' Yes. Over-run condition is present, so clear it
CREN = 1 ' Re-enable & clear over-run condition
goto loop1

outloop1:
IF BytesIn[0] = 71 then '(G) sortie de ce mode
GOSUB reset
GOTO debut
endif

IF BytesIn[0] = 86 then '(V) affichage des lettres alphabet
gosub reset
dgt = 0
endif


alpha: dgt = dgt + 1
LCDOUT $FE,1," select +/- Then Max"
LCDOUT $FE,$C0," 0123456789ABCDEFGHI"
LCDOUT $FE,$94,"JKLMNOPQRSTUVWXYZ"
lcdout $FE,$D4,dgt1,dgt2,dgt3,dgt4
lcdout $FE,$C0
lcdout $FE,$0F
if dgt = 5 then
lcdout $FE,$0C
goto debut
endif

loop2:
IF RCIF THEN ' If RCIF=1 there's a new character in RCREG
BytesIn[ByteCnt]=RCREG ' Yes. Then store character in array
IF BytesIn[ByteCnt]=10 THEN outloop2 ' LF (0A)
ByteCnt=ByteCnt+1 ' Increment element index pointer
ENDIF
IF !OERR THEN loop2 ' If NOT over-run, then re-cycle
CREN = 0 ' Yes. Over-run condition is present, so clear it
CREN = 1 ' Re-enable & clear over-run condition
goto loop2

outloop2:
IF BytesIn[0] = 43 then '+
pos = pos + 1
IF pos = 21 then
lcdout $FE,$94
gosub reset
goto loop2
else
lcdout $FE,$14
gosub reset
goto loop2
endif
endif

If BytesIn[0] = 45 then '-
pos = pos - 1
if pos = 20 then
lcdout $FE,$C0
for x = 1 to 19
lcdout $FE,$14
next x
gosub reset
goto loop2
else
lcdout $FE,$10
gosub reset
goto loop2
endif
endif


if dgt = 1 then
dgt1 = BytesIn[0]
endif
if dgt = 2 then
dgt2 = BytesIn[0]
endif
if dgt = 3 then
dgt3 = BytesIn[0]
endif
if dgt = 4 then
dgt4 = BytesIn[0]
endif
pos = 1
gosub reset
goto alpha

' **************************************************

harryweb
- 1st October 2009, 14:27
HI

I think there are too much datas on the RX... and loop + lcd display takes too much time to execute...

May be using another resonator 8MHz vs 4MHz ?

I don't know how to optimize the code...
Any help ?

mackrackit
- 1st October 2009, 16:43
I have been looking at you code some and do not see where the problem is.

Can you point to the routine where the problem starts?

Other than that you may try adding a
PAUSE 50
between the LCDOUT commands and Play with these values


' Set command delay time in us
DEFINE LCD_COMMANDUS 2000
' Set data delay time in us
DEFINE LCD_DATAUS 50

harryweb
- 5th October 2009, 08:01
I have tried so much things....
The only one that works, a new osc 8MHz Vs 4MHz !!!

PS: Thank You Dave !