I wish to use com3 to communcate with a device. The device I want to talk to implements an RS232 interface using a MAX232A. I am a bit confuses as to whether I should use inverted or non-inverted logic to configure Com3. The communications will be 9600 baud, 8 data bits, No parity and 1 stop bit. I wish to transmit on pin PC6 and receive on PC5.
I must admit that I am confused by how to prepare Com3. What routines need be called to get this going?
Any enlightenment will be appreciated.
Vic
Using Com3
Using Com3
Vic Fraenckel
KC2GUI
windswaytoo ATSIGN gmail DOT com
KC2GUI
windswaytoo ATSIGN gmail DOT com
First, a little background information. The RS232 standard calls for a logic 1 (also called "mark") to be transmitted as a level between -3 and -15 volts and a logic 0 (also called "space") as a level between +3 and +15 volts. A level converter like the MAX232(A) performs both inversion and level conversion. A +5 volt input on the TTL side yields a negative voltage on the RS232 side and a zero volt input on the TTL side generates a positive voltage on the RS232 side.
Since the device that you're connecting will be generating and expecting RS232 voltage levels, you need to add circuitry between the ZX and the device to perform the level conversion. A MAX232 is probably the easiest way to do this. Appendix C of the ZBasic Reference manual shows several alternatives to performing the level conversion.
Once you have the level converter in place, you'll want to select non-inverting mode for Com3.
Some devices have serial interfaces that don't conform to the RS232 standard but still work in most cases. The Com1 channel on the ZX-24 is an example of this. A mark is transmitted as zero volts and a space is transmitted as +5 volts. If you wanted to connect two ZX-24s using Com1 on one and Com3 on the other, you'd need to select inverting mode.
It is also possible to using inverting mode and a few resistors and diodes to connect to a device with a conforming RS232 interface. This should only be done if the connection is short (a few feet or so). To implement this interface, you need clipping diodes and a limiting resistor on the input to the ZX and a limiting resistor on the output from the ZX. Again, this is not recommended (because doing it incorrectly can damage the ZX) but it should work.
Since the device that you're connecting will be generating and expecting RS232 voltage levels, you need to add circuitry between the ZX and the device to perform the level conversion. A MAX232 is probably the easiest way to do this. Appendix C of the ZBasic Reference manual shows several alternatives to performing the level conversion.
Once you have the level converter in place, you'll want to select non-inverting mode for Com3.
Some devices have serial interfaces that don't conform to the RS232 standard but still work in most cases. The Com1 channel on the ZX-24 is an example of this. A mark is transmitted as zero volts and a space is transmitted as +5 volts. If you wanted to connect two ZX-24s using Com1 on one and Com3 on the other, you'd need to select inverting mode.
It is also possible to using inverting mode and a few resistors and diodes to connect to a device with a conforming RS232 interface. This should only be done if the connection is short (a few feet or so). To implement this interface, you need clipping diodes and a limiting resistor on the input to the ZX and a limiting resistor on the output from the ZX. Again, this is not recommended (because doing it incorrectly can damage the ZX) but it should work.
- Don Kinzer
I neglected to answer the second part of your question.
To set up Com3 you have to prepare two queues, define the Com3 configuration and then open the port. Here is a code fragment that shows how it might be done.
You may need to adjust the queue size. It may make sense in your application to have one queue larger than the other. It may also make sense to completely eliminate one of them if you will only be sending data or only receiving data.
If you want to use Com4, Com5 or Com6 you must first invoke ComChannels() to specify the overall parameters. This is required because the same software is used internally for all 4 software UARTs and it needs to know, before any of the channels are opened, the maximum number of channels that will be used and the maximum baud that will be used. Com3 is handled as a special case (for compatibility reasons) so this special setup is not required if you only use Com3. Looked at another way, the firmware is pre-configured for 1 software UART with a maximum baud of 19200 and if you want a different configuration you need to use ComChannels() to specify what you want.
To set up Com3 you have to prepare two queues, define the Com3 configuration and then open the port. Here is a code fragment that shows how it might be done.
Code: Select all
Const rxPin as Byte = 20
Const txPin as Byte = 19
Const qsize as Byte = 40
Dim oq3(1 to qsize) as Byte
Dim iq3(1 to qsize) as Byte
Call OpenQueue(iq3, SizeOf(iq3))
Call OpenQueue(oq3, SizeOf(oq3))
Call DefineCom(3, rxPin, txPin, &H08)
Call OpenCom(3, 9600, iq3, oq3)
If you want to use Com4, Com5 or Com6 you must first invoke ComChannels() to specify the overall parameters. This is required because the same software is used internally for all 4 software UARTs and it needs to know, before any of the channels are opened, the maximum number of channels that will be used and the maximum baud that will be used. Com3 is handled as a special case (for compatibility reasons) so this special setup is not required if you only use Com3. Looked at another way, the firmware is pre-configured for 1 software UART with a maximum baud of 19200 and if you want a different configuration you need to use ComChannels() to specify what you want.
- Don Kinzer
Just a clarification question:
The docs say ComChannels has no effect on coms are already open... but I'm not clear which ports this is referring to: all of them, even ones to be opened in the future, or just ones that are already open (is it a compile-level statement, or runtime-level, etc.)
If I go from 3 ports to 2, for example, by closing a port, it may be benificial to redefine ComChannels for higher maximum baudrates. For this, _all_ coms must first be closed, right?
Or can ComChannels statement affect only the next port that is opened, just not those already in place? This still fits with the documentation's description, I believe.
The docs say ComChannels has no effect on coms are already open... but I'm not clear which ports this is referring to: all of them, even ones to be opened in the future, or just ones that are already open (is it a compile-level statement, or runtime-level, etc.)
If I go from 3 ports to 2, for example, by closing a port, it may be benificial to redefine ComChannels for higher maximum baudrates. For this, _all_ coms must first be closed, right?
Or can ComChannels statement affect only the next port that is opened, just not those already in place? This still fits with the documentation's description, I believe.
Just to clarify, it says that invoking ComChannels() has no effect if any of Com3 to Com6 is open. This means that if you want to change the number of available (software-based) channels or change the maximum speed, you can only do so when none if those channels is open.The docs say ComChannels has no effect on coms are already open.
The reason that this is so is because both the number of channels and the maximum speed affect the way that the timing is generated. The timing and sequencing cannot be changed when a channel is open because it would corrupt any character that was in the process of being transmitted or received.
- Don Kinzer
Hi,
Great chat and very clear how to define, set and open the serial communication using rxPin and txPin as rx and tx, etc.
But I have a basic question, sorry I'm a beginner:
Which command is used to send and receive serial communication using this open port?
Example: how to code a simple program to send and ASCII character to txPin and how to read a string from the rxPin?
Any help will be very much appreciated.
Great chat and very clear how to define, set and open the serial communication using rxPin and txPin as rx and tx, etc.
But I have a basic question, sorry I'm a beginner:
Which command is used to send and receive serial communication using this open port?
Example: how to code a simple program to send and ASCII character to txPin and how to read a string from the rxPin?
Any help will be very much appreciated.
The serial channels in ZBasic are all buffered; the transmit and receive queues that you specify when a channel is opened are used for the transmit and receive buffers. Consequently, you don't send and receive characters directly to and from the channel's rx and tx pins. Rather, you put characters to be transmitted into the channel's transmit queue and you read the received characters from the channel's receive queue. Although this design may seem complicated, it has the significant advantage that data transmission and reception can be done in the background.jorsam wrote:Which command is used to send and receive serial communication using this open port?
Here is a simple example program showing how to set up a serial channel and then send a character and a string of characters to a serial channel's output queue.jorsam wrote:Example: how to code a simple program to send and ASCII character to txPin and how to read a string from the rxPin?
Code: Select all
Const txPin as Byte = 5
Const rxPin as Byte = 6
Const CR as Byte = &H0d
Const LF as Byte = &H0a
Dim iq(1 to 25) as Byte
Dim oq(1 to 40) as Byte
Sub Main()
' initialize the queues
Call OpenQueue(iq)
Call OpenQueue(oq)
' define the characteristics of the serial channel
Call DefineCom(3, rxPin, txPin, &H08)
' open the serial channel
Call OpenCom(3, 9600, iq, oq)
' send a carriage return and line feed as individual bytes
Call PutQueueByte(oq, CR)
Call PutQueueByte(oq, LF)
' send a string with a CRLF
Call PutQueueStr(oq, "Hello, world!" & Chr(CR) & Chr(LF))
End Sub
Code: Select all
Sub Main()
' initialize the queues
Call OpenQueue(iq)
Call OpenQueue(oq)
' define the characteristics of the serial channel
Call DefineCom(3, rxPin, txPin, &H08)
' open the serial channel
Call OpenCom(3, 9600, iq, oq)
' send a carriage return and line feed as individual bytes
Call PutQueueByte(oq, CR)
Call PutQueueByte(oq, LF)
' send a string with a CRLF
Call PutQueueStr(oq, "Hello, world!" & Chr(CR) & Chr(LF))
' echo all received characters to the debug console
Do
If (StatusQueue(iq)) Then
Dim c as Byte
Call GetQueue(iq, c, 1)
If (c = CR) Then
Debug.Print
ElseIf (c <> LF) Then
Debug.Print Chr(c);
End If
End If
Loop
End Sub
Code: Select all
' echo all received characters to the debug console
Do
If (StatusQueue(iq)) Then
Dim str as String
Dim strLen as Integer, idx as Integer
str = GetQueueStr(iq)
strLen = Len(str)
For idx = 1 to strLen
Dim c as Byte
c = Asc(str, idx)
If (c = CR) Then
Debug.Print
ElseIf (c <> LF) Then
Debug.Print Chr(c);
End If
Next idx
End If
Loop
- Don Kinzer