440 likes | 577 Vues
COM347J1 Networks and Data Communications. Lab 5: The RS485 experiment, (based on the work of Pat Sweeney). Ian McCrum Room 5D03B Tel: 90 366364 voice mail on 6 th ring Email: IJ.McCrum@Ulster.ac.uk Web site: http://www.eej.ulst.ac.uk. This version Modified 07/11/04.
E N D
COM347J1Networks and Data Communications Lab 5: The RS485 experiment, (based on the work of Pat Sweeney) Ian McCrum Room 5D03B Tel: 90 366364 voice mail on 6th ring Email: IJ.McCrum@Ulster.ac.uk Web site: http://www.eej.ulst.ac.uk This version Modified 07/11/04 www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
The RS485 Experiment Objectives: Do the following… • Interpret a simple circuit diagram and understand its function • Create, using a protoboard the simple circuit and demonstrate its successful operation • Observe and understand C software, and modify it to achieve a desired outcome. • Design and implement a simple protocol • Work in groups of 2 and 6 (not optional!) www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
Experiment details • Form into pairs, one protoboard to each pair • Look at the next slide to get an idea of the task • Step through the slides for information about the items to be used • Then see how the circuit works (roughly) by looking at the slides that annotate the circuit • Carry out the experiment by building on the protoboard • Copy the C code in RS485.c and modify to your own protocol requirements. • Ask for help if you are unsure www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
The Software part … • A free C compiler with integrated development environment (IDE) I.e an Editor with compiler hot keys is available at http://bdn.borland.com/article/images/20841/tc201.zip (1.1MBytes) or use the one already installed on your PC if one exists. • Or find one by googling for “free C compilers” or visit http://www.thefreecountry.com/compilers/cpp.shtml • You will use the simple RS485-TX.exe and RS485-RX.exe programs to generate output from the PC serial port, into your circuit and observe, first the LEDs flashing and then the transfer of data from a transmitter to a receiver. • The key to understanding the programs is to realise that the PC has a simple serial chip that does all the conversions to serial for you. It is not necessary to fully understand the chip, just the bare essentials. There is lots of background information on the serial port at http://www.beyondlogic.org/serial/serial.htm • The 9 pins on the back of the PC outputs RS232 ( +/- 12 volts) but our circuit converts +/-12V to 0 to +5volts and then to the required voltages for RS485. There is data on the RS485 interface available on the web. Try http://www.hw.cz/english/docs/rs485/rs485.html for data on RS485 or its earlier simpler version RS422. www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
RS485-TX.C • Start the C compiler IDE or editor and load the file RS485-TX.C, review its comments and add the comments below. Then compile it /* This program sends out AAAAAAAA using the serial port*/ /* P.J. Sweeney Jan 1989 , */ /* modified Nov 1992 */ /* and again Apr 1994 */ /* yet again Oct 1999 */ /* and then modified by Ian McCrum 07/11/04 */ #include <dos.h> #include <stdio.h> www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
Examine and guess the meaning of the files /* The following defines the names of the ports of the serial chip in the PC, known as the 8250, modern PCs have an improved version of the chip but it is compatible. Note that the base address has been chosen to be the address of $03F8 ( this is usually COM1: Note the #define instruction causes a simple text replacement to take place, with arithmetic if needed, so the lines below just make the code more readable */ #define BASE_PORT 0x03F8 #define DATAOUT BASE_PORT #define DATAIN BASE_PORT #define DIVISORL BASE_PORT #define DIVISORH BASE_PORT + 1 #define INT_ENABLE BASE_PORT + 1 #define INT_IDENT BASE_PORT + 2 #define LINE_CTL BASE_PORT + 3 #define MODEM_CTL BASE_PORT + 4 #define STATUS BASE_PORT + 5 #define MODEM_STAT BASE_PORT + 6 www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
Now for actual code /* these are the functions which are called by the main function */ void status (void); /* check state of the chip, wait until ok */ void initialiseport (long baud); /* sets up various RS232 parameters */ /* such as baud rate and format */ /* also allows manual control of RTS */ /* Now comes the "main" function, this will get executed first */ main() { /* continue with the main body of code */ www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
main() { long baud = 2; /* declares a variable and initialises it to 2 */ unsigned char stuff=0x0aa; /* another variable, only usable inside main*/ int port; /* unless we pass them to functions */ initialiseport (baud); /* call the function, pass it the value 2 */ while (1 == 1) { /* which really means loop forever */ status(); /* only returns if status ok */ port=DATAOUT; /* give the variable the value of DATAOUT */ /* I.e set port to the hex number 3F8 */ outportb(port,stuff); /* this is a function built in to Borland’s compiler */ printf(“U"); /* it sends 0xaa ( or whatever) to the I/o address 03F8 */ } /* the end of the while, just loop back up to the brace above */ } /* the end of main, this line is never reached because we loop forever */ www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
void status(void) /* to output data, the chip has to be ready for it, */ /* read up on what bit 6 of the STATUS register does (0x3FD) at www.beyondlogic.com - it says when bit 6 is set, the transmitter holding and shift registers are empty, no serial conversions are taking place so there should be no activity on the transmit data line */ { /* we AND status with 01000000, this forces most bits to zero apart */ /* from bit 6, so if bit 6 of STATUS is one then the test fails, and we exit the loop */ while (( inportb(STATUS) & 0x40 ) = = 0) /* stay while that bit is zero */ { /* do nothing until bit 6 is set, then exit */ } return; /* return statements are sometimes optional in C, but it is good style to keep them */ } /*** end of function status ***/ www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
void initialiseport (long baud) /* This function sets up the port on serial card of IBM Pc the baud rate you send to the function ... be careful about precision !! */ { char bit_7 = 0x80; /* bit seven set in 8 bit word */ /* 0x04 5bits +1.5 stop bits */ /* 0x03 8bits 1 stop N */ char modes = 0x03; /* sets the mode of the 8250 */ long baud_divisor; /* it had better be 32 bits, this is what a “long” usually is */ outportb (LINE_CTL , bit_7); /* allows baud to be set */ baud_divisor = 1843200L / (16 * baud); /* a trailing L means use a 32 bit number*/ /* the lines below use some special features of C, the & for “ANDing” you have already met. It will force all but the lower 8 bits to zero when used with 0xFF below. Also the >> shift operator will move the upper 8 bits down to the lower 8 bits, an 8 bit right shift. Not every high level language has shift operators, they are very handy for manipulating bytes */ outportb (DIVISORL , baud_divisor & 0x00FF ); /* only LSByte sent */ outportb (DIVISORH , baud_divisor >> 8 ); /* only MSByte sent */ outportb (LINE_CTL , modes ); outportb (MODEM_CTL , 0x01 ); /* ready to TX rts=0 */ /* and with rs232 dtr high*/ return; } /*** end of function initialiseport ***/ www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
Now for RS485-RX.c • To receive characters the program has to know when a new character arrives • Luckily the serial chip has a bit in one of its STATUS registers that will tell us that a stop bit (and the preceding data bits have just been received) • Check www.beyondlogic.org/serial/serial.htm ,it says Bit 0 of the STATUS register (LSR) shows data ready, which means that a byte has been received by the UART and is at the receiver buffer ready to be read. • So, we continually check this bit, and when it tells us there is fresh data, we then go and read the data from the DATAIN register. • This process will clear the flag and “arm” the system, ready to receive the next character. • What follows now is a partial copy of RS485-RX.C with extra comments • Add the comments and check you know or can half-guess what is going on www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
/************ most of file is same as RS485-TX.C ***********/ main() { long baud = 2; unsigned char stuff; int port; initialiseport (baud); while (1 = = 1) { status(); /* this version of status is for reception */ /* it only returns if there is a character to receive */ port=DATAOUT; /* used to hold the address of DATAIN */ stuff = inportb(port); /* we collect the 8 bits of data into the variable */ printf("%02XH ",stuff); /* and then we print it, the actual format we */ /* display is determined by the %02X */ } /* end of while, never reached */ } /*** end of function main ***/ www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
The RS485-RX.C Status function void status(void) /* for inputting data */ { /* Bit zero if the STATUS register will goto a 1 when fresh data arrives quote from www.beyondlogic.org/serial/serial.htm is */ Bit 0 set shows data ready, which means that a byte has been received by the UART and is at the receiver buffer ready to be read. the logical AND with 00000001 forces all bits except bit zero to o if bit zero of STATUS is still at 0 then this = = 0 and we stay in the while /* while (( inportb(STATUS) & 0x01 ) = = 0) /* means than bit 0 is zero */ { /* Do nothing here, until the while test is false, when bit 0 is set } /* end of while */ /* end up here once the while test fails, now the receive buffer needs read */ return; } www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
Running the code • Connect your board to COM1: of your PC (9 pin) • Run the “baud rate of 1.exe” executable and observer the LEDs. • Run the “baud rate of 1200.exe” • Link to a neighbours machine and try running RS485-TX.exe and RS485-RX.exe • Recompile the code to send different characters • Link three machines together (see slide 41) and observe what happens when two machines run RS485-TX.EXE and one machine runs RS485-RX.EXE at the same time. • Devise a system to pass letters from one machine to another. • Devise a system to pass a complete file of data from one machine to another, in a variety of combinations (see slide 42) www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
Simple Communications Protocol • The requirement is to transfer a file from one machine, where three are interconnected, to another. An early version will allow a human to synchronise the three machines so no collision is possible. • A later version might adopt a more sophisticated protocol, listen before transmit or only transmit when PC 1 says so, • Upon reception the file need only be displayed upon the screen. • You should note what appears on the screen if a collision happens. • A better protocol would add functions to enable and disable the transmitters, using control of RTS, (hint Bit 1 of the Modem Control Register (MODEM_CTL), place a zero there to place the circuit in transmit mode and a one to put it in receive mode ( transmitter disabled) BUT ensure you leave bit zero at 1, bit zero is the DTR output and is used to power our circuit! • Use MODEM_CTL & 0x FD to force bit one low and • Use MODEM_CTL | 0x02 to force it high, | is a “OR” bitwise operator www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
C Code fragment for reading files FILE *in; FILE *out; in=fopen(”filein.txt","r"); out=fopen(”fileout.txt","w"); while ((ch_read=fgetc(in)) != EOF) { /* do something in here */ ch_write=ch_read; fprintf(out,"%c”,ch_write); } www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt
Modem Control register Don’t care what their values are RTS output place 0 in here so that the circuit is in transmit mode, 1 in here so that circuit is in receive mode DTR output place 1 in here so that the RS232 signal is at +10 volts for chip supply www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.ppt