You are on page 1of 10

Bascom and AVR, RS-232.

1 of 10

http://www.qsl.net/pa3ckr/bascom%20and%20avr/rs232/index.html

Bascom and AVR, RS-232.


RS-232
RS-232 is nowadays a 'mature' communication standard. It is surprising that a standard, defined in the early sixties, is
still widely used today. Formally however, the name RS-232 does not apply to a standard. An American organisation,
now known as the Electronic Industries Association, proposed a way to communicate between large mainframe
computers and peripheral equipment such as terminals. The proposal was called a Recommended Standard and 232
was not more than a identifying number. Much later this became an official standard, EIA-232. In 1991, the latest
version, EIA-232E was published. However, the name RS-232 is still widely used and so shall I in these pages.
RS-232 is a serial communication protocol. It sends information as bit after bit and has two signal levels:
- a voltage between -3 and -25 Volts is a logic one (1)
- a voltage between +3 and +25 Volts is a logic zero (0)

As the picture above shows, the voltage level between -3 and +3 Volts is undefined. In practice this is not so. Most
often, any voltage level above 2.5 Volts is seen as a logic zero, anything below as a logic one.
The electrical specification of RS-232 is quite robust, all outputs must be able to sustain a full short-circuit and all
inputs must have a schmitt-trigger action. This makes a full-standard RS232 port on a PC much less vulnerable than a
TTL-level parallel port.
RS-232 is an a-synchronous protocol, meaning that no separate clock is transmitted with the data. Both sides must
know the communication speed (we use the term baud-rate) beforehand. In the original version of RS-232, a
maximum speed of 20.000 bits per second was defined. Now, speeds up to 1 Mbit/s are used.
RS-232 defines a complete hardware handshaking system using several wiring pins. We use only the most important
three:
- RxD : receive data, pin number 2
- TxD : transmit data, pin number 3
- Ground, pin number 5
These pin numbers refer to a standard male DB9 connecter on your PC or laptop.
UART
UART means Universal Asynchronous Receiver Transmitter. It is the hardware end on both sides of an RS-232
communication link. In the PC or any other computer it is a chip on the motherboard under control of the CPU. In
the AVR controller it is a small area on the chip die dedicated to this function. In the AT90S2313 the UART is
connected to pin 2 (RxD) and 3 (TxD). As these pins also function as general purpose I/O PortD.0 and PortD.1,
you'll have to sacrifice some I/O if you need the UART. A UART takes care of sending and receiving bits. When
receiving, it determines when to sample the RxD pin to determine if a zero or one is received. When a complete byte
has been received it can interrupt the controller to have this byte read from the UART input buffer. When
transmitting, the UART reads a byte from the transmit buffer and sends the corresponding bits with the timing

2010/06/22 06:56 .

Bascom and AVR, RS-232.

2 of 10

http://www.qsl.net/pa3ckr/bascom%20and%20avr/rs232/index.html

appropriate for the RS-232 speed selected. If the transmit buffer is empty the UART can interrupt the controller to
send more bytes to the buffer if there are any.
A UART does not do the level shifting needed to go from the AVR's logic level of 0 and +5 V to the RS-232 range of
+3/+25 and -3/-25 Volts. This function is performed by chips like the ubiquitous MAX232 level converter:

A level converter generates the voltages necessary to comply with the RS-232 levels. It also inverts the logic levels!
The MAX232 uses internal switching converters and voltage doublers to generate levels of approximately -9 and
+9Volts. These voltages lie neatly within the required range.
Max232 pin-compatible converters are available from all mainstream chip manufacturers. Be sure to check the
datasheet though, most often the capacitor values used vary between 100nF and 10uF:

I built a Max232 (I used a National Semiconductor DS14C232CM, which is pin-compatible) on a very small piece of

2010/06/22 06:56 .

Bascom and AVR, RS-232.

3 of 10

http://www.qsl.net/pa3ckr/bascom%20and%20avr/rs232/index.html

PCB and used short stiff wires to insert this board into my breadboard:

Barely visible at the top is a 10k potentiometer I use to tap the -9V supply off pin 6. I use this whenever I need a
negative contrast voltage for i.e. a graphics display.
Simple Max
You do not always need a Max232 converter chip. Often the following simple two-transistor converter works as well:

This is of course not a level converter, only an inverter. It works by the grace of tolerant UARTS in PC's and laptops.
The voltage on pin 3 of the AT90S2313 is inverted by the left transistor. TxD pin 2 of the DB9 connector will have a
voltage level between 0 and app. +5 Volts. Pin 3 of the DB9 connector will see voltage levels between -9 and +9

2010/06/22 06:56 .

Bascom and AVR, RS-232.

4 of 10

http://www.qsl.net/pa3ckr/bascom%20and%20avr/rs232/index.html

Volts. The diode on the base of the right transistor limits the -9 Volts to app. -0.7 Volts. A level of +9 Volts will make
the transistor conduct, resulting in the RxD pin 3 of the AT90S2313 going from +5 to app. 0 Volts.
Simpler yet
If you only want to transmit data from the controller to a PC you can skip the right transistor.
Note: this simple schematic violates the RS-232 standard. It works in most cases, but make sure you test
communications especially when using high speeds.
From AT90S2313 to the PC
A simple schematic with AT90S2313, an LCD and the Max232 would look like this:

RS-232 speed
The RS-232 baud-rate (old term for communication speed, check your telecommunications history book or go to
Wikipedia) is determined by your setting of this speed but also by the AVR clock speed. Not all clock speeds will
result in a 'neat' baud-rate. In Bascom, you can check this in the Options/Compiler/Communications window:

2010/06/22 06:56 .

Bascom and AVR, RS-232.

5 of 10

http://www.qsl.net/pa3ckr/bascom%20and%20avr/rs232/index.html

The important field in this window is Error. It shows the deviation of the AVR internal baud-rate from the one you
selected from the Baudrate list. For a clock speed of 4MHz and a baud-rate of 9600, the error is small, you will not
notice any communication errors. But for higher baud-rates the Error increases rapidly:

This kind of error will surely result in garbled communication.


Clock speeds that are a multiple of the chosen baud-rate result in a zero error. For example, suppose we would want
to communicate between the AVR and a PC with a baud-rate of 115.200. A nice clock speed would be
11.059,200MHz, because 11.059.200 / 115.200 = 96:

2010/06/22 06:56 .

Bascom and AVR, RS-232.

6 of 10

http://www.qsl.net/pa3ckr/bascom%20and%20avr/rs232/index.html

Another nice crystal frequency is 3.686,400MHz instead of 4MHz. I checked my junkbox and found the following
crystals by dividing the crystal frequency by 115.200 for an integer result:
1.843.200
3.686,400
5.068,800
5.529,600
11.059.200
12.902,400
14.745,600
etcetera.
So, next time you go to a ham-fest or a swap-meet, you better bring your pocket calculator along!
Writing to and reading from an RS-232 port
First specify your RS-232 baud-rate in Options/Compiler/Communication, or use a keyword in your Bascom
program:
$Baud = 9600

Writing from the AVR to the RS-232 port is as simple as using the Print command:
Dim Name as String * 12
Dim Age as Integer
Name = "John"
Age = 36
Print "Name: " ; Name ; " Age: " ; Age

will print "Name: John Age: 36" to the RS-232 port.


The Print command may contain a mix of string constants and variables, all separated by a ";".
Reading from the RS-232:
Input "Name: " , Name

Again, the Input command can contain a mix of string constants and variables.
Note that Input uses a "," as separator, where Lcd and Print need a ";"!
A complete program for testing RS-232 communication from the AT90S2313 to the PC may look like this:
rs-232-test.bas
$regfile = "2313def.dat"
$crystal = 4000000
$baud = 9600

2010/06/22 06:56 .

Bascom and AVR, RS-232.

7 of 10

http://www.qsl.net/pa3ckr/bascom%20and%20avr/rs232/index.html

Config Pind.6 = Output


Dim Firstnumber As Integer
Dim Secondnumber As Integer
Dim Sum As Integer
Do
Set Portd.6
Firstnumber = 0
Secondnumber = 0
Input "Enter first number : " , Firstnumber
Input "Enter second number: " , Secondnumber
Sum = Firstnumber + Secondnumber
Print "Sum: " ; Sum
Reset Portd.6
Waitms 100
Loop
End

Compile and send the program to the AT90S2313. Then open the Bascom terminal emulator: Tools/Terminal
emulator. This is a small program to act as a 'terminal', a device allowing you to type characters which are sent to the
PC RS-232 port, then through the Max232 to the AT90S2313. When the AT90S2313 returns characters, the Max232
sends them to the PC's RS-232 port and they will be displayed in the terminal emulator window.
Before doing this, you will have to tell the terminal emulator that you want to use 9600 baud and the PC's COM1
RS-232 port. Open the Terminal/Settings menu:

Reset the AT90S2313, the program asks you for two numbers and returns the sum:

2010/06/22 06:56 .

Bascom and AVR, RS-232.

8 of 10

http://www.qsl.net/pa3ckr/bascom%20and%20avr/rs232/index.html

Did you notice that everything you typed after the "Enter..." prompt was echoed back to the terminal emulator? This
is a function that Bascom performs automatically. Sometimes this echo function is not useful, for example if you use
another PC program to send characters to the AT90S2313 and it cannot handle the echoed characters. Then switch
off the echo function:
Echo Off

Variants of the Input command are Inputhex and Inputbin:


Dim Code as Byte
Inputhex "Type two-character hex-code: " , Code

allows you to type hex-codes, for example "A9" for the decimal value 169.
Note that Inputhex does not check if input is only the characters 0-9 and A-F. It will however limit the number of
characters interpreted to two.
Inputbin is useful if you have a PC program that sends data that cannot be represented as ASCII code. If you want to
send a 16-bit binary value:
Dim Tuneval as Word
Inputbin Tuneval

will read two bytes from the RS-232 port and place them in the Tuneval variable. The number of bytes read is
determined by the variable type used. Note that you must always start sending the least significant byte and end with
the most significant byte from the value to send.
Let us assume that the value of Tuneword in the PC is 12.320 decimal. That is 0011.0000.0010.0000 binary and
30.20 hexadecimal. (interpunction added for readability)
Test this with:
Dim Tuneval as Word
Do
Print "Enter bin-code: "
Inputbin Tuneval
Loop
End

Then in the terminal emulator type first a space (ASCII code 20hex), then a 0 (ASCII code 30hex).
Inputbin has an output equivalent: Printbin. It is a pity there is no Printhex.

2010/06/22 06:56 .

Bascom and AVR, RS-232.

9 of 10

http://www.qsl.net/pa3ckr/bascom%20and%20avr/rs232/index.html

Reading one character at the time


Sometimes you only want to know if there is an input character available at the RS-232 port. Then use the Inkey
command:
Dim Testchar as Byte
Testchar = 0
While Testchar = 0
Testchar = Inkey
Wend

This piece of code will stay in the While loop as long as there is no character available. You could add a counter or
timer to provide for a time-out function. Or, maybe better:
Dim Testchar as Byte
Do
Loop until Inkey <> 0

Another possibility is the Waitkey and Ischarwaiting commands:


Dim Wtchar as Byte
Wtchar = Waitkey

will wait until a character is available. Problem is that no time-out is possible here so your program may get stuck
here!
Or:
Do
Loop until Ischarwaiting = 1

will loop until a character is available, it can then be read with Input or Inkey. The Do Loop offers the possibility of a
time-out function.
Software UART
The AT90S2313 and most other AVR controllers has a hardware UART on pins 2 and 3. Sometimes you have to use
these pins for another purpose. Bascom has a software UART function that uses extra program space, but you may
specify which pins to use for RxD and TxD. The pins to use are specified in the Open command:
Open "Comb.0: 9600 , 8 , n , 1" for Input As #1
Open "Comb.1: 9600 , 8 , n , 1" for Output as #2

uses pin 0 of PortB as receiver (RxD) and pin 1 of PortB as transmitter (TxD). Both are set to a baud-rate of 9600,
use 8 databits per character, do not use a parity bit and use one stopbit. In Bascom every reference to #1 will be used
for RxD and #2 for TxD:
software-rs232.bas
$regfile = "2313def.dat"
$crystal = 4000000
Config Pind.6 = Output
Dim Tstr As String * 4
Dim Num As Word
'open channel for output
Open "comb.1:9600,8,n,1" For Output As #1
Open "comb.0:9600,8,n,1" For Input As #2
Do
Set Portd.6
Waitms 100
Reset Portd.6
Print #1 , "text: "
Input #2 , Tstr
Print #1 , Tstr
Print #1 , "number: "
Input #2 , Num

2010/06/22 06:56 .

Bascom and AVR, RS-232.

10 of 10

http://www.qsl.net/pa3ckr/bascom%20and%20avr/rs232/index.html

Print #1 , Num
Loop
End

Note that the software UART does not echo characters. Also different from the hardware UART implementation is
that after every prompt a linefeed/carriage return is used.
The software UART can be used with the Print, Input, Inputhex, Inkey, Waitkey and Ischarwaiting commands. Note
the syntax used in Inkey, Waitkey and Ischarwaiting:
Var = Inkey(#2)
Var = Waitkey(#2)
Var = Ischarwaiting(#2)

A software UART channel can be opened, but also closed :


Close #1
Close #2

so that after the close the i/o pins can be used for another purpose.
TOC

2010/06/22 06:56 .

You might also like