I recently installed the latest full update of GCBASIC. Since then, the same programs compiled w/ the updated version do not function correctly. Specifically, a program with several subroutines that print integrers and strings to a VFD display is not displaying data correctly. My gut feel it is something related to changes in the subroutines or the serial communication. I am not using the SerOut commands, rather I write to the txreg and use interrupts. If any one has any ideas of the root cause that would be wonderful. Snippets of code below:
Thanks, Mark D.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The gcbasic version that works is:
version 0.9 10/2/2007
CODE*********************************************
set baudctl.brg16 off ' off for 8 bit baud generator, on for 16 bit
set spbrg.brg5 on ' Set spbrg to 51 for 9600 baud
set spbrg.brg4 on
set spbrg.brg3 off
set spbrg.brg2 off
set spbrg.brg1 on
set spbrg.brg0 on
set txsta.brgh on ' High speed baud
set txsta.sync off ' asynchronous comm
set txsta.txen on ' enables transmission
set PIE1.RCIE on ' enable interrupt on receive
set rcsta.cren on ' enables receiver circuitry of eusart
set rcsta.spen on ' enables eusart & configs rx & tx pin as input
set anselh.ans11 off ' if pin is analog i/o clear ANSEL bit
' send Integer (convert to ascii hex code for display)
sub SenInt (IntToSen as word) #NR
bolPlace = 0
tempPlace = 0
if IntToSen >= 1000 then
tempPlace = IntToSen/1000
SenHex(tempPlace + 48)
bolPlace = 1
IntTosen = IntToSen - tempPlace*1000
end if
if IntToSen >= 100 or bolPlace = 1 then
tempPlace = IntToSen/100
SenHex(tempPlace + 48)
bolPlace = 1
IntTosen = IntToSen - tempPlace*100
end if
if IntToSen >= 10 or bolPlace = 1 then
tempPlace = IntToSen/10
SenHex(tempPlace + 48)
bolPlace = 1
IntTosen = IntToSen - tempPlace*10
end if
SenHex(IntToSen + 48)
end sub
' Send string
sub SenString (substring$) #NR
'length = len(substring$)
length = substring(0)
for cloop = 1 to length
wait until txsta.trmt on 'wait until UART buffer is clear to send next byte
wait until sbusy off 'wait until VFD is clear to receive new byte
txreg = substring(cloop)
next
end Sub
' Sub to send bytes to VFD
sub SenHex (char) #NR
wait until txsta.trmt on 'wait until UART buffer is clear to send next byte
wait until sbusy off 'wait until VFD is clear to receive new byte
txreg = char
end Sub
sub NewLine ' Add ne line to display
SenHex(0x0A)
SenHex(0x0D)
end sub
sub RevDisp (disp) #NR ' Reverse display print 1 = reverse, 0 = normal
SenHex(0x1F)
SenHex(0x72)
SenHex(disp)
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
A quick look at the generated code didn't reveal any obvious problems. What's not working, the serial characters not being produced properly?
There is one thing that could cause some trouble. Going on the code in the tracker, you have a comment that the internal osc isn't accurate enough, but the
#config HS_OSC
line is commented out. I changed the default config settings in the latest update, so GCBASIC will now automatically use the internal oscillator if possible, rather than always using HS. Please try uncommenting the config line and let me know if it helps!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I was answering your question about serial characters and I realized that strings appear to be sent correctly everytime via "SenString" while "SenInt", "Newline", and "RevDisp" never work. These all have "SenHex" as a nested subroutine to transmit data while "SenString" does not.
Do we have a nested subroutine issue here?
Thanks for responding to my issue,
Mark D.
PS… How were you able to find my comment about the internal oscillator and the config? Did I attach a file?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Well spotted with the subroutines not working! There was a bug in GCBASIC, it was not generating the correct memory bank selection code at the start of the SenHex subroutine. I've uploaded a new update, which should fix this and can be downloaded from .
Also, there is an issue in the SenInt sub. Some time ago, I altered the way that GCBASIC deals with word variable calculations. The 10/2/2007 release will use 16 bit operations for an entire calculation if the result is stored in a word variable. However, the newer versions will only use 16 bit operations if one or more of the input values is a word value. This would be causing problems in this line:
IntTosen = IntToSen - tempPlace*100
Byte operations will be used for the multiplication. If tempPlace is 3 or higher, then the multiplication will overflow, and instead of giving 300, the multiplication will give 44. One workaround is to tell GCBASIC to treat 100 as a word:
IntTosen = IntToSen - tempPlace*100
The other option (which I recommend) is to not use the multiply at all, but instead to get the remainder from the division. After a division, the SysCalcTempX variable will always contain the remainder (it's a natural by-product of the divide algorithm). Have a look at the new Print (word) sub in lcd.h, or the HSerPrint (word) sub in usart.h for an example of how to use this.
I saw your post in the tracker, which you did attach the full program to.
I recently installed the latest full update of GCBASIC. Since then, the same programs compiled w/ the updated version do not function correctly. Specifically, a program with several subroutines that print integrers and strings to a VFD display is not displaying data correctly. My gut feel it is something related to changes in the subroutines or the serial communication. I am not using the SerOut commands, rather I write to the txreg and use interrupts. If any one has any ideas of the root cause that would be wonderful. Snippets of code below:
Thanks, Mark D.
The gcbasic version that works is:
version 0.9 10/2/2007
CODE*********************************************
set baudctl.brg16 off ' off for 8 bit baud generator, on for 16 bit
set spbrg.brg5 on ' Set spbrg to 51 for 9600 baud
set spbrg.brg4 on
set spbrg.brg3 off
set spbrg.brg2 off
set spbrg.brg1 on
set spbrg.brg0 on
set txsta.brgh on ' High speed baud
set txsta.sync off ' asynchronous comm
set txsta.txen on ' enables transmission
set PIE1.RCIE on ' enable interrupt on receive
set rcsta.cren on ' enables receiver circuitry of eusart
set rcsta.spen on ' enables eusart & configs rx & tx pin as input
set anselh.ans11 off ' if pin is analog i/o clear ANSEL bit
'************************* Subroutines ***********************
' send Integer (convert to ascii hex code for display)
sub SenInt (IntToSen as word) #NR
bolPlace = 0
tempPlace = 0
if IntToSen >= 1000 then
tempPlace = IntToSen/1000
SenHex(tempPlace + 48)
bolPlace = 1
IntTosen = IntToSen - tempPlace*1000
end if
if IntToSen >= 100 or bolPlace = 1 then
tempPlace = IntToSen/100
SenHex(tempPlace + 48)
bolPlace = 1
IntTosen = IntToSen - tempPlace*100
end if
if IntToSen >= 10 or bolPlace = 1 then
tempPlace = IntToSen/10
SenHex(tempPlace + 48)
bolPlace = 1
IntTosen = IntToSen - tempPlace*10
end if
SenHex(IntToSen + 48)
end sub
' Send string
sub SenString (substring$) #NR
'length = len(substring$)
length = substring(0)
for cloop = 1 to length
wait until txsta.trmt on 'wait until UART buffer is clear to send next byte
wait until sbusy off 'wait until VFD is clear to receive new byte
txreg = substring(cloop)
next
end Sub
' Sub to send bytes to VFD
sub SenHex (char) #NR
wait until txsta.trmt on 'wait until UART buffer is clear to send next byte
wait until sbusy off 'wait until VFD is clear to receive new byte
txreg = char
end Sub
sub NewLine ' Add ne line to display
SenHex(0x0A)
SenHex(0x0D)
end sub
sub RevDisp (disp) #NR ' Reverse display print 1 = reverse, 0 = normal
SenHex(0x1F)
SenHex(0x72)
SenHex(disp)
end sub
A quick look at the generated code didn't reveal any obvious problems. What's not working, the serial characters not being produced properly?
There is one thing that could cause some trouble. Going on the code in the tracker, you have a comment that the internal osc isn't accurate enough, but the
#config HS_OSC
line is commented out. I changed the default config settings in the latest update, so GCBASIC will now automatically use the internal oscillator if possible, rather than always using HS. Please try uncommenting the config line and let me know if it helps!
I was answering your question about serial characters and I realized that strings appear to be sent correctly everytime via "SenString" while "SenInt", "Newline", and "RevDisp" never work. These all have "SenHex" as a nested subroutine to transmit data while "SenString" does not.
Do we have a nested subroutine issue here?
Thanks for responding to my issue,
Mark D.
PS… How were you able to find my comment about the internal oscillator and the config? Did I attach a file?
Well spotted with the subroutines not working! There was a bug in GCBASIC, it was not generating the correct memory bank selection code at the start of the SenHex subroutine. I've uploaded a new update, which should fix this and can be downloaded from .
Also, there is an issue in the SenInt sub. Some time ago, I altered the way that GCBASIC deals with word variable calculations. The 10/2/2007 release will use 16 bit operations for an entire calculation if the result is stored in a word variable. However, the newer versions will only use 16 bit operations if one or more of the input values is a word value. This would be causing problems in this line:
IntTosen = IntToSen - tempPlace*100
Byte operations will be used for the multiplication. If tempPlace is 3 or higher, then the multiplication will overflow, and instead of giving 300, the multiplication will give 44. One workaround is to tell GCBASIC to treat 100 as a word:
IntTosen = IntToSen - tempPlace*100
The other option (which I recommend) is to not use the multiply at all, but instead to get the remainder from the division. After a division, the SysCalcTempX variable will always contain the remainder (it's a natural by-product of the divide algorithm). Have a look at the new Print (word) sub in lcd.h, or the HSerPrint (word) sub in usart.h for an example of how to use this.
I saw your post in the tracker, which you did attach the full program to.
: http://gcbasic.sourceforge.net/update.html
Money on the fix. Works like a champ.
Thanks for excellent product and excellent support!
Mark D.