07/11/200 4 www.eej.ulster.ac.uk/~ian/modules/COM347J1/COM347J1_Lab5.p pt LAB5/1/43 COM347J1 Networks and Data Communications Ian McCrum Room 5D03B Tel: 90 366364 voice mail on 6 th ring Email: [email protected]Web site: http://www.eej.ulst.ac.uk Lab 5: The RS485 experiment, (based on the work of Pat Sweeney) This version Modified 07/11/04
43
Embed
07/11/2004 ian/modules/COM347J1/COM347J1_Lab5.ppt LAB5/1/43 COM347J1 Networks and Data Communications Ian McCrumRoom 5D03B Tel: 90.
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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.
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 */
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 */
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 ***/
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 */
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 ***/
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
/************ 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 ***/
The RS485-RX.C Status functionvoid 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;}
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)
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