RS232 Software TX has one BIG letal bug.
The sleep, idle, no signal state of an RS232 TX line is ON / 1 / Vdd
The Start Bit is a 0
The Stop Bit is a 1
GCBASIC RS232 Software is all wrong on these
This can be solved by changing two lines in rs232.h
line 157 : start bit SerTxLow ' instead of SerTxHigh
line 184 : stop bit SerTxHigh ' instead of SerTxLow
With these two changes, my PC receives correctly my PIC16F628A with it's internal 4MHz clock up to 4800 baud, on an USB RS232 TTL using prolific It must be the same on RX side ???? …
see also messages in Great Cow Graphical Forum
I am proud of me :-)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
And here is the RX fix
In gcbasic/include/lowlevel/rs232.h modify the followinglines
line 200
Wait Until SerQuickSample = False ' instead of Wait Until = TRUE
line 202
If SerQuickSample = True Then Exit Sub ' instead of If SerQuickSample = False Then Exit Sub
line 238 to 243
must be uncommented :-)
line 243
Wait Until SerQuickSample = True ' instead of Wait Until SerQuickSample = FALSE
With these changes, PIC16F628A with it's internal 4MHz clock receives my PC up to 2400 baud, on an USB RS232 TTL using prolific
other things :
There must be an error in Delays as someone told me in an other forum here, when the 4MHz INT OSC of the PIC in replaced by a 20 MHz cristal, the maximum baud rate received by the PC does not change. I don't understand how the time delay is computed ????
On the Sub SerSend side shouldn't there be an IntOff/IntOn too ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Oops ! With a 20 MHz cristal ext osc, tha maximum TX speed is 19200 baud and the maximum RX speed is 4800 baud with the PC ! Using the corrected rs232.h
Why 4800 only for RX ???
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
' ==============================================================' TEST CODE' PIC16F628A RX/TX, Hardware/Software RS232, OSC INT/EXT' Two Speed fast/Slow for RS232 Software on jumper, need reset' RX/TX on Jumper need reset' Test Materials :' Windows, INT OSC/20MHz EXT OSC, PIC on Prolific-USB-Serial-Com, GCBASIC 0.9' RS232 to USB TTL interface, no MAX232 required' Erdemal March 1st, 2013' ==============================================================' input PortA.0 (10k pulled up) sets RX/TX mode RX if ON = no Jumper,' TX if OFF = Jumper to Vss' input PortA.1 (10k pulled up) sets High/Low baud rate only for RS232 Software ' Low Baud Rate = ON = no jumper, high Baud rate = Off = Jumper to Vss'' TX mode on PortB.2 alternativly sends 50 then 100 every 200 ms' Led on TX to Vdd via 4.8K (to see data flow)' -------' RX mode on PortB.1' -------' output PortB.4 ON >> LED GREEN ON In RX mode ON when 100 is received' output PortB.5 ON >> LED RED ON In RX mode ON when neither' 50 nor 100 is received (= RX error)' Output PortB.6 ON >> LED YELLOW ON In RX Mode ON when 50 is received' (50 and 100 choosen for no good/bad reason)' RX OK when flashing Green/Yellow, if RX error LedRed is on' --------------------------------------------------------------' ISSUE' - In GCBASIC RS232 software with PIC transmitting to PC, RX data is always Halve the TXed value.' It looks like the 8th bit is not sent or the first bit is the last start bit ??????????' When two PIC communicate together with GCBASIC RS232 software, it works up to 4800 bauds' - partly solved, still a Delay error' https://sourceforge.net/projects/gcbasic/forums/forum/596084/topic/6877271/index/page/1' --------------------------------------------------------------' With GCBASIC RS232 Hardware communication with a computer it works perfectly' - up to 19200 bauds with 16F628A 4MHz Osc Int +-1.5%' - with a 20 MHz EXT OSC quartz 57600 baud obtained' ==============================================================#DefineOscQuartz' not sure these works in gcbasic#DefineSerialHardware' if not, comment the lines' ==============================================================#IfNDefOscQuartz' ++++++++++++++++++++++++++++++++++++++++++++#chip16F628A,4#EndIf' +++++++++++++++++++++++++++++++++++++++++++++++++++++++'#IfDefOscQuartz' +++++++++++++++++++++++++++++++++++++++++++++#Chip16F628A,20#EndIf' +++++++++++++++++++++++++++++++++++++++++++++++++++++++' --------------#configMCLR_OFF' ==============================================================' - Jumpers - No Jumper : RX and 4800 bds' -----------#DefinebtnRXTXPortA.0' On RX , Off/0v = TX = jumper placed#Definebtn4896PortA.1' On 4800 , Off/0v = 9600 = jumper placed'DirbtnRXTXinDirbtn4896in' ==============================================================#IfDefSerialHardware' ++++++++++++++++++++++++++++++++++++++++#DefineUSART_BAUD_RATE9600#EndIf' +++++++++++++++++++++++++++++++++++++++++++++++++++++++' ==============================================================#IfnDefSerialHardware' +++++++++++++++++++++++++++++++++++++++' - Init TX -#defineSendAHighSetPORTB.2ON' MUST LINES#defineSendALowSetPORTB.2OFF' MUST LINES'DirPORTB.2Out' ---------------------------' - Init RX -#defineRecAHighPORTB.1ON' MUST LINES#defineRecALowPORTB.1OFF' MUST LINES'DirPORTB.1In#EndIF' ++++++++++++++++++++++++++++++++++++++++++++++++++++++'#defineLedGreenPORTB.4#defineLedRedPORTB.5#defineLedYellowPORTB.6'DirPORTB.4OutDirPORTB.5OutDirPORTB.6Out'' ==============================================================' ---- Select RX or TX ----' --------------------------SelectCasebtnRXTXCaseOffGotoDataTransmitterCaseOnGotoDataReceiverCaseElseEndSelect' ==============================================================' ---- Transmitter ---- ' ---------------------DataTransmitter:'#IfnDefSerialHardwareIfbtn4896=OnThenInitSer1,r9600,1+WaitForStart,8,1,none,normalElseInitSer1,r19200,1+WaitForStart,8,1,none,normalEndIf#EndIf'Do' just flash yellow green for OK and RED for junksIfTemp=100ThenTemp=50ElseTemp=100EndIf#IfnDefSerialHardware' +++++++++++++++++++++++++++++++++++SerSend1,Temp' TX remains OFF after transfer#EndIf' +++++++++++++++++++++++++++++++++++++++++++++++++++#IfDefSerialHardwareHSerSendTemp' TX remains ON after transfer#EndIfWait2010msLoop'' ==============================================================' ---- Receiver ----' ------------------DataReceiver:'setLedGreenoffsetLedRedoffsetLedYellowoff'#IfnDefSerialHardwareIfbtn4896=OnThenInitSer1,r9600,129,8,1,none,normalElseInitSer1,r19200,129,8,1,none,normalEndIf#EndIf'Do' just flash yellow (RX=50) green(RX=100) and RED for junks (RX Else)#IfnDefSerialHardware' ++++++++++++++++++++++++++++++++++++SerReceive1,Temp#EndIf' +++++++++++++++++++++++++++++++++++++++++++++++++++++#IfDefSerialHardware' ++++++++++++++++++++++++++++++++++++++HserReceiveTemp#EndIf' +++++++++++++++++++++++++++++++++++++++++++++++++++++SelectCaseTempCase50SetLedYellowOnSetLedGreenOffSetLedRedOffCase100SetLedGreenOnSetLedYellowOffSetLedRedOffCaseElseSetLedRedonSetLedYellowOffSetLedGreenOffEndSelectLoop' =============================================================='
FREEBASIC RS232 RX CODE
' =========================================================
' FREEBASIC RS232 TX TEST CODE
' targetted on gcbasic rs232 with PIC controller
' Erdemal March 2, 2013
' =========================================================
'
#include once "windows.bi"
'
Dim As Integer iCom, iFile
Dim sCom As String
iFile = FreeFile
'
sCom = "COM6:19200,N,8,1,cs0,ds0,cd0,rs" ' Change ComX and Speed here
' Open Com sCom As iFile
iCom = Open Com (sCom, As iFile)
If iCom = 0 Then
Print "OPEN COM OK Returns 0"
Else
MessageBox (0, "ERROR OPEN COM FAILED, I CLOSE", "GCBASIC RS232 RX TEST", 0)
End
End If
'
Dim As Byte J, K
Dim N As integer
J = 100
K = 50
For N = 0 To 10
Sleep 200
Print #ifile, Chr(J); ' ; no CR sent
Sleep 200
Print #ifile, Chr(K); ' ; no CR sent
Next N
'
Print
Print " **** FINISHED ****"
'
Close iFile
Sleep
' =========================================================
' =========================================================
' FREEBASIC RS232 RX TEST CODE
' targetted on gcbasic rs232 with PIC controller
' Erdemal March 2, 2013
' =========================================================
'
#include once "windows.bi"
'
Dim As Integer iCom, iFile, iCount = 0
Dim sCom As String
iFile = FreeFile
'
sCom = "COM6:9600,N,8,1,cs0,ds0,cd0,rs" ' Change ComX and Speed here
' Open Com sCom As iFile
iCom = Open Com (sCom, As iFile)
If iCom = 0 Then
Print "OPEN COM OK Returns 0"
Else
MessageBox (0, "ERROR OPEN COM FAILED, I CLOSE", "GCBASIC RS232 RX TEST", 0)
End
End If
'
Dim bData As uByte
'
bData = 0
Messagebox (0, "CLOSE TO START RS232 RX", "Jack", 0)
'
iCount = 0
Get #iFile, , bData
While icount < 20
If bData <> 0 Then
Print bData
iCount = iCount + 1
End If
bdata = 0
Sleep 10
Get #iFile, , bData
Wend
'
Print
Print " **** FINISHED ****"
'
Close iFile
Sleep'
Great SourceForge deserves better forums :-)
Erdemal
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
RS232 is normally inverted… IOW… so lines 157 and 184 are correct. Same with the data it's also supposed to be inverted.
As far as the baud speed, I'm not sure about how GCB compiler does it because I was using a PIC that wasn't fully supported. So I had to roll my own in-line assembly bit-banging the serial routines. On a PIC16F54 I was able to get 57,600 baud running at 20MHz
I don't know whose source is the good one ?
- the PIC Rs232 Hardware works as my source
- the gcbasic RS232 Software samples don't work in my real world
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have looked into this issue. My results. I have tested and this now makes sense to me....
See the revised rs232.h, see below (I cannot attach!!). This is adapted as per @Erdy great insights.
I have wrapped these with a #define to ensure I can choose whether I want to communicate with a PC or an IC.
General Rules...
For a PC. I am using the new define statement and 'normal'. Therefore, I use '#define RS232ForPC' and a command similar to InitSer 1, r4800, 1+WaitForStart , 8, 1, none, normal
For an IC. Do add the define statement and use 'invert'. Therefore, I would simply use 'a command similar to InitSer 1, r4800, 1+WaitForStart , 8, 1, none, invert
This was a great post that looks like it has fixed a bug.
I've had issues with RS232 to PC communication that I couldn't figure out and this appears to fix it (though I still have to fully test it on my setup).
So will this be part of a future GCB update if this fixes an issue?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I got the same problem of Erdy (using TX/RX from software serial) after many test I made the modification on RS232.H suggested from Erdy/Anobium in this thread and now it work properly.
I should made another modification on RS232.H because the first char received was always corrupped.
this is the other fix on the RS232.H (by Anobyum) that i made for eliminate first corrupped received char
This is the test code (it does't work with the original RS232.H ... please you test also)
#chip 16F876A,20
#config OSC=HS
#define RS232ForPC <------------
#define SerInPort PORTC.4
#define SerOutPort PORTC.5
#define SendAHigh Set SerOutPort On
#define SendALow Set SerOutPort off
#define RecAHigh SerInPort on
#define RecALow SerInPort off
Dir SerOutPort Out
Dir SerInPort In
'doesn't work more than baud 9600
InitSer 1, r9600, 1+WaitForStart, 8, 1, None, normal
inizio:
SerReceive (1, Temp)
sersend (1, Temp)
goto inizio
I am compiling with synwrite 6.1.140 & Great Cow BASIC (0.9 22/9/2013)
the USB serial cable is Prolific
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
http://fr.wikipedia.org/wiki/UART (in french, the english version is different and less clear)
RS232 Software TX has one BIG letal bug.
The sleep, idle, no signal state of an RS232 TX line is ON / 1 / Vdd
The Start Bit is a 0
The Stop Bit is a 1
GCBASIC RS232 Software is all wrong on these
This can be solved by changing two lines in rs232.h
line 157 : start bit SerTxLow ' instead of SerTxHigh
line 184 : stop bit SerTxHigh ' instead of SerTxLow
With these two changes, my PC receives correctly my PIC16F628A with it's internal 4MHz clock up to 4800 baud, on an USB RS232 TTL using prolific It must be the same on RX side ???? …
see also messages in Great Cow Graphical Forum
I am proud of me :-)
And here is the RX fix
In gcbasic/include/lowlevel/rs232.h modify the followinglines
line 200
Wait Until SerQuickSample = False ' instead of Wait Until = TRUE
line 202
If SerQuickSample = True Then Exit Sub ' instead of If SerQuickSample = False Then Exit Sub
line 238 to 243
must be uncommented :-)
line 243
Wait Until SerQuickSample = True ' instead of Wait Until SerQuickSample = FALSE
With these changes, PIC16F628A with it's internal 4MHz clock receives my PC up to 2400 baud, on an USB RS232 TTL using prolific
other things :
There must be an error in Delays as someone told me in an other forum here, when the 4MHz INT OSC of the PIC in replaced by a 20 MHz cristal, the maximum baud rate received by the PC does not change. I don't understand how the time delay is computed ????
On the Sub SerSend side shouldn't there be an IntOff/IntOn too ?
Oops ! With a 20 MHz cristal ext osc, tha maximum TX speed is 19200 baud and the maximum RX speed is 4800 baud with the PC ! Using the corrected rs232.h
Why 4800 only for RX ???
Codes
gcbasic RX/TX Hard/Soft RS232 INT OSC/EXT OSC FAST/SLOW Soft RS232 Code
FREEBASIC RS232 RX CODE
Great SourceForge deserves better forums :-)
Erdemal
RS232 is normally inverted… IOW… so lines 157 and 184 are correct. Same with the data it's also supposed to be inverted.
As far as the baud speed, I'm not sure about how GCB compiler does it because I was using a PIC that wasn't fully supported. So I had to roll my own in-line assembly bit-banging the serial routines. On a PIC16F54 I was able to get 57,600 baud running at 20MHz
Reference:
http://en.wikipedia.org/wiki/File:Rs232_oscilloscope_trace.svg
I don't know whose source is the good one ?
- the PIC Rs232 Hardware works as my source
- the gcbasic RS232 Software samples don't work in my real world
I have looked into this issue. My results. I have tested and this now makes sense to me....
See the revised rs232.h, see below (I cannot attach!!). This is adapted as per @Erdy great insights.
I have wrapped these with a #define to ensure I can choose whether I want to communicate with a PC or an IC.
General Rules...
For a PC. I am using the new define statement and 'normal'. Therefore, I use '#define RS232ForPC' and a command similar to InitSer 1, r4800, 1+WaitForStart , 8, 1, none, normal
For an IC. Do add the define statement and use 'invert'. Therefore, I would simply use 'a command similar to InitSer 1, r4800, 1+WaitForStart , 8, 1, none, invert
RS232.H
' Serial/RS232 routines for Great Cow BASIC
' Copyright (C) 2006 Hugh Considine
' This library is free software; you can redistribute it and/or
' modify it under the terms of the GNU Lesser General Public
' License as published by the Free Software Foundation; either
' version 2.1 of the License, or (at your option) any later version.
' This library is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
' Lesser General Public License for more details.
' You should have received a copy of the GNU Lesser General Public
' License along with this library; if not, write to the Free Software
' Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
'***********
'IMPORTANT:
'THIS FILE IS ESSENTIAL FOR SOME OF THE COMMANDS IN GCBASIC. DO NOT ALTER THIS FILE
'UNLESS YOU KNOW WHAT YOU ARE DOING. CHANGING THIS FILE COULD RENDER SOME GCBASIC
'COMMANDS UNUSABLE!
'***********
'Usage of Sys232Temp
'Bit Use
'0 Dummy receive source
'1 Receive buffer
'I/O command defines
'Note: These all default to dummy ports and MUST BE CHANGED PRIOR TO USE
'#define SendALow nop
'#define SendAHigh nop
'#define RecALow Sys232Temp.0 OFF
'#define RecAHigh Sys232Temp.0 ON
'#define SendBLow nop
'#define SendBHigh nop
'#define RecBLow Sys232Temp.0 OFF
'#define RecBHigh Sys232Temp.0 ON
'#define SendCLow nop
'#define SendCHigh nop
'#define RecCLow Sys232Temp.0 OFF
'#define RecCHigh Sys232Temp.0 ON
'Assign values to key words
'Parity
#define none 0
#define odd 1
#define even 2
'Signal Inversion
#define normal 0
#define invert 1
'Start Bit settings
#define WaitForStart 128
'Bit rate delays
'Moved to stdbasic.h
'r* is us delay/52 for 1 bit
'Calculate delay lengths
#script
If PIC Then
'20 MHz PIC, 7 us taken off - 35 instructions
SerThirdDelay19200 = int(17 - 4 / ChipMHz * 35)
SerThirdDelay9600 = int(35 - 4 / ChipMHz * 35)
SerThirdDelay4800 = int(69 - 4 / ChipMHz * 35)
SerThirdDelay2400 = int(139 - 4 / ChipMHz * 35)
SerThirdDelay1200 = int(278 - 4 / ChipMHz * 35)
SerThirdDelay600 = int(555 - 4 / ChipMHz * 35)
SerThirdDelay300 = int(1111 - 4 / ChipMHz * 35)
#endscript
'Serial receive buffer
#define SerRxData Sys232Temp.1
sub InitSer(In Ser_Select, In Ser_Rate, In Ser_Start, In Ser_Data, In Ser_Stop, In Ser_Parity, In Ser_Invert)
'This sub sets configuration of the serial routines
'Sample usage for communication with Lego RCX:
'InitSer(1,r2400,1,8,1,odd,invert)
end sub
Sub SerSend(In Ser_Select, In Ser_Byte)
end sub
Sub SerReceive(In Ser_Select, Out Ser_Byte)
end sub
sub SerPrint (In Ser_Select, PrintData As String)
'PrintLen = LEN(PrintData$)
PrintLen = PrintData(0)
end sub
sub SerPrint (In Ser_Select, In SerPrintVal)
end sub
Sub SerPrint (In Ser_Select, In SerPrintVal As Word)
Dim SysCalcTempX As Word
End Sub
'Note: When calling this sub, set Ser_Select and Ser_Rate, and read carry bit
sub SerRxBit
'Clear bit counters
RxHighCount = 0
end sub
Macro SerTxHigh
#ifdef SendAHigh
if Ser_Select = 1 THEN SendAHigh
#endif
#ifdef SendBHigh
if Ser_Select = 2 THEN SendBHigh
#ENDIF
#ifdef SendCHigh
if Ser_Select = 3 THEN SendCHigh
#ENDIF
SerBitDelay
End Macro
Macro SerTxLow
#ifdef SendALow
if Ser_Select = 1 THEN SendALow
#endif
#ifdef SendBLow
if Ser_Select = 2 THEN SendBLow
#ENDIF
#ifdef SendCLow
if Ser_Select = 3 THEN SendCLow
#ENDIF
SerBitDelay
End Macro
function SerQuickSample
SerQuickSample = FALSE
end function
sub SerCfgLoad(Ser_Select) #NR
Ser_Select_Old = Ser_Select
#ifdef OneOf(SendAHigh, RecAHigh)
if Ser_Select = 1 THEN
Ser_Rate = Ser_Rate_A
Ser_Start = Ser_Start_A
Ser_Data = Ser_Data_A
Ser_Stop = Ser_Stop_A
Ser_Parity = Ser_Parity_A
Ser_Invert = Ser_Invert_A
end if
#endif
#ifdef OneOf(SendBHigh, RecBHigh)
if Ser_Select = 2 THEN
Ser_Rate = Ser_Rate_B
Ser_Start = Ser_Start_B
Ser_Data = Ser_Data_B
Ser_Stop = Ser_Stop_B
Ser_Parity = Ser_Parity_B
Ser_Invert = Ser_Invert_B
end if
#ENDIF
#ifdef OneOf(SendCHigh, RecCHigh)
if Ser_Select = 3 THEN
Ser_Rate = Ser_Rate_C
Ser_Start = Ser_Start_C
Ser_Data = Ser_Data_C
Ser_Stop = Ser_Stop_C
Ser_Parity = Ser_Parity_C
Ser_Invert = Ser_Invert_C
end if
#ENDIF
end sub
sub SerBitDelay
'Predefined rates (more accurate)
'All delays have 10 us taken off to allow processing time
if Ser_Rate = 1 then Wait SerFullDelay19200 us: exit sub '19200 (52 us)
if Ser_Rate = 2 then Wait SerFullDelay9600 us: exit sub '9600 (104 us)
if Ser_Rate = 4 then Wait SerFullDelay4800 us: exit sub '4800 (208 us)
if Ser_Rate = 8 then Wait SerFullDelay2400 us: exit sub '2400 (417 us)
if Ser_Rate = 16 then Wait SerFullDelay1200 us: exit sub '1200 (833 us)
if Ser_Rate = 32 then Wait SerFullDelay600 us: exit sub '600 (1666 us)
if Ser_Rate = 64 then Wait SerFullDelay300 us: exit sub '300 (3333 us)
end sub
sub SerThirdBitDelay
'Predefined rates (more accurate)
if Ser_Rate = 1 then Wait SerThirdDelay19200 us: exit sub '19200 (17 us)
if Ser_Rate = 2 then Wait SerThirdDelay9600 us: exit sub '9600 (35 us)
if Ser_Rate = 4 then Wait SerThirdDelay4800 us: exit sub '4800 (69 us)
if Ser_Rate = 8 then Wait SerThirdDelay2400 us: exit sub '2400 (139 us)
if Ser_Rate = 16 then Wait SerThirdDelay1200 us: exit sub '1200 (278 us)
if Ser_Rate = 32 then Wait SerThirdDelay600 us: exit sub '600 (555 us)
if Ser_Rate = 64 then Wait SerThirdDelay300 us: exit sub '300 (1111 us)
end sub
This was a great post that looks like it has fixed a bug.
I've had issues with RS232 to PC communication that I couldn't figure out and this appears to fix it (though I still have to fully test it on my setup).
So will this be part of a future GCB update if this fixes an issue?
In reality... it is not needed. As you can do everything with the standard code base.
With this patch I do not have to keep changing my code to much. I do and have got really confused with setting bits ON and OFF etc.
At least with this method... I 'define' the PC as my terminal device and then just change to 'normal'. It sort of makes sense to me.
:-)
I got the same problem of Erdy (using TX/RX from software serial) after many test I made the modification on RS232.H suggested from Erdy/Anobium in this thread and now it work properly.
I should made another modification on RS232.H because the first char received was always corrupped.
this is the other fix on the RS232.H (by Anobyum) that i made for eliminate first corrupped received char
This is the test code (it does't work with the original RS232.H ... please you test also)
I am compiling with synwrite 6.1.140 & Great Cow BASIC (0.9 22/9/2013)
the USB serial cable is Prolific