PDA

View Full Version : Strange Variable Issue ...



gunayburak
- 24th July 2015, 14:49
Hello everyone ..

I'm having a very very interesting problem with my code ... I'm trying to understand the basics of a Enhanced Asynchronous communication but in the code there is a line that drives me crazy ...




'************************************************* ***************
'* Name : EUSARTRX.BAS *
'* Author : [BURAK GÜNAY] *
'* Notice : Copyright (c) 2015 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 7/22/2015 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
#header
errorlevel -303 ; suppress Program word too large
#ENDHEADER


#config
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF
#ENDCONFIG


'define OSC 4
DEFINE OSC 16
'define OSC 32


'------------- LCD DEFINES ------------------------
DEFINE LCD_DREG PORTB 'LCD data port
DEFINE LCD_DBIT 4 'LCD data starting bit 0 or 4


DEFINE LCD_RSREG PORTA 'LCD register select port
DEFINE LCD_RSBIT 7 'LCD register select bit


DEFINE LCD_RWREG PORTA ' LCD read/write port
DEFINE LCD_RWBIT 5 ' LCD read/write pin bit


DEFINE LCD_EREG PORTA 'LCD enable port
DEFINE LCD_EBIT 6 'LCD enable bit


DEFINE LCD_BITS 4 'LCD bus size 4 or 8
DEFINE LCD_LINES 2 'Number lines on LCD
'------------- LCD DEFINES ------------------------


'================================================= ==============================
'OSCCON=%01101010 'OSC is @ 4 MHZ
OSCCON=%11111000
'OSCCON=%11110000 'OSC is @ 32 MHZ (PLLEN MUST BE ENABLED)


PORTA=%00000000 : PORTB=%00000000
TRISA=%00000000 : TRISB=%00000010

ANSELA=%00000 : ANSELB=%00000000
'ADCON0=%00000001 : ADCON1=%11100000
OPTION_REG.7=0 : WPUB=%11111111


RCSTA = $90 ' Enable serial port & continuous receive
TXSTA = $24 ' Enable transmit, BRGH = 1
SPBRG = 160 ' 9600 Baud @ 16MHz, -0.08%
SPBRGH = 1
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator


T1CON=%00100000 ' 1:4 prescaler
'================================================= ==============================
X VAR WORD
DAT VAR WORD
GP VAR byte ' GP variable
BytesIn VAR byte[2] ' Up to 2 bytes
ByteCnt VAR byte ' Indicates number of bytes in buffer
'EOM CON "~" ' EOM = "End Of Message" marker
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
ByteCnt = 0 ' Zero counter
TMR1ON VAR T1CON.0 : TMR1ON=0 : TMR1=0


LED VAR PORTA.1
'================================================= ==============================


LCDOUT $FE,1
PAUSE 500
LCDOUT $FE,$80," READY "
PAUSE 1000
LCDOUT $FE,1


MAIN:


IF OERR=1 THEN
CREN = 0 ' Over-run so disable receive
CREN = 1 ' Re-enable & clear OERR "over-run" flag
ENDIF


IF RCIF=1 THEN ' If RCIF=1 there's a new character in RCREG
TMR1ON=1
BytesIn[ByteCnt]=RCREG ' Yes. Store new char in array
' IF BytesIn[ByteCnt]=EOM THEN Out ' End of message?
ByteCnt=ByteCnt+1 ' No. Increment array index pointer
TMR1ON=0
IF ByteCnt >=2 THEN Out ' Test for software buffer over-run
ENDIF


IF OERR=1 THEN
CREN = 0 ' Over-run so disable receive
CREN = 1 ' Re-enable & clear OERR "over-run" flag
ENDIF


GOTO MAIN


Out:
TMR1ON=1'---
DAT.LOWBYTE=BYTESIN[0]
DAT.HIGHBYTE=BYTESIN[1]
x=dat
FOR GP=0 to ByteCnt ' Clear array bytes 0 to ByteCnt
BytesIn[GP]=0
NEXT
ByteCnt=0 ' Reset index pointer back to first element


WHILE RCIF=1 ' Trash anything received after the EOM marker
GP=RCREG ' by reading RCREG until RCIF is cleared.
WEND
tmr1on=0'---


LCDOUT $FE,$80,"Num : ",DEC5 x
LCDOUT $FE,$C0,"Delay: ",DEC5 TMR1," uS"


TMR1=0


GOTO MAIN






If I try to view the variable "DAT" directly it always shows zero ... But If I first add a line "x=dat" just as in the code and try to display the "x" it displays the number ?

A way more strange thing is ;

if I change the codelines and try to view both x and dat only x is displayed dat remains zero .. (THE CODE CHANGE IS BELOW)



LCDOUT $FE,$80,"Num : ",DEC5 x
LCDOUT $FE,$C0,"Num : ",DEC5 DAT


How can it happen ? There is something I skip or ignore to see ?

Thanks in advance ..

gunayburak
- 24th July 2015, 20:30
I think the problem is using array variables ... By creating proper byte variables everything works as I expect ...

richard
- 25th July 2015, 02:16
if ByteCnt=2 how many times will it run through this for/next loop ?



FOR GP=0 to ByteCnt ' Clear array bytes 0 to ByteCnt
BytesIn[GP]=0
NEXT



when you set BytesIn[2] to 0 what var do you think will get clobbered


its not a Strange Variable Issue ... its a write to an out of bounds array index

gunayburak
- 25th July 2015, 13:54
if ByteCnt=2 how many times will it run through this for/next loop ?



FOR GP=0 to ByteCnt ' Clear array bytes 0 to ByteCnt
BytesIn[GP]=0
NEXT



when you set BytesIn[2] to 0 what var do you think will get clobbered


its not a Strange Variable Issue ... its a write to an out of bounds array index

Hmm I've changed the line as follows



FOR GP=0 to ByteCnt-1 ' Clear array bytes 0 to ByteCnt
BytesIn[GP]=0
NEXT


And it works as expected ... Thank you for your answer Richard ..

Now can you explain what happens when it tries to clear a nonexisting variable ? It clobbers my DAT variable next as it should not , yet somehow it does .. ?

I think there is something happening on the background that is out of my knowledge ..

richard
- 25th July 2015, 14:13
from the manual

A single Array Variable can be visualized as a list of values. The variable name is
how you access the list, and a number –or index– is used to point to any single
value within the list.
The index value is enclosed in brackets and appended after the array variable's
name.
myarray[index] = 0
The index can be a literal number, a variable, or an expression.
For the following examples, an array named "stored" is used:
stored VAR WORD[8] 'Create an array named "stored"
with 8 elements.
Note that the 8 elements in our array are numbered 0 through 7. There is no
element-8. This is very important, because PBP doesn't place a limit at the end of
the array. If you write "stored[8]", PBP won't generate an error and you will be
accessing memory outside of the array. (The end of the array is stored[7] and there
is no stored[8].) This could have disastrous results and be very difficult to debug.
The elements of "stored" can be written individually:
stored[0] = 1260
stored[1] = 2500
Or, you might want to write values with a loop. You could read PORTB once per
second and save 8 readings:
FOR index = 0 TO 7 'Loop 8 times
stored[index] = PORTB 'Save value of PORTB
PAUSE 1000 'Wait a second
NEXT index 'Loop again


this is not just a pbp issue most 8 bit micro languages have the same limitation on array bounds checking ie . none at all

gunayburak
- 26th July 2015, 12:51
Thank you Richard , for the amazing explanations ... Good to know and keep such knowledges for the pic that is working on the background of my brain ..