9.0. Test Program

 
    9.1. User Manual
    9.2. How is RS232 Communication Achieved?
 

 
Test.exe is a MS DOS based application designed to test the digital hardware (using RS232), it has many features and has a user-friendly interface, allow some of the test procedures are low-level designed for use by an engineer and not the average person.  Full source code is found in appendix 2.
 
Note allow this is a DOS program it will run under Windows, even though Windows NT/2000/XP do not allow direct access to the hardware (e.g. RS232), it will simulate the operation of the RS232 UART allowing DOS based programs to access the serial port as long as another program is not already using the required port.
 

 
9.1. User Manual
 
Main menu, user has 9 options (just hit the key corresponding to the required function): -
PC-Based Oscilloscope Test Program
----------------------------------
 
RX Terminal               -- hit 1
TX Terminal               -- hit 2
Manual RTU frame with CRC -- hit 3
Manual RTU frame no CRC   -- hit 4
Simulated Random Noise    -- hit 5
Loop-back test            -- hit 6
Change Baud Rate          -- hit 7
About                     -- hit 8
Quit                      -- hit Q
 
 
[1] RX Terminal
 
RX Terminal
-----------
Waiting for message (press a key to stop)
 
Simple RX Terminal, basically every character that is received from COM 1, is printed on the screen using the ASICII format. Note some non-alphanumerical characters have special functions, e.g. Backspace, Bell, etc… If [anykey] is pressed the program returns to the main menu.
 
This function can be used to test the PICs RS232 (transmit mode) and all of the hardware involved, e.g. PIC UART, MAX232 and cable. It can also be used to help debug the PIC software, e.g. printf() (CCS code) can be used to display variable information in order to try and workout what is happening.
 
 
[2] TX Terminal
 
TX Terminal
-----------
Type your message hit [ENTER] to transmit: -
 
Simple TX terminal, the user types in a message and then hits the [ENTER] key to transmitted the message through RS232. Note after transmission the ‘RX Terminal’ function is automatically called, so that any replay can be received.
 
This function can be used to test the PICs RS232 (receive mode) and all of the hardware involved, e.g. PIC UART, MAX232 and cable. Since ‘RX terminal’ is called automatically after transmission, it is possible to fully test RS232 communications, e.g. setup the PIC so that it transmits every character it receives. If the received message is the same as the transmitted message clearly RS232 communications is working.
 
[3] Manual RTU frame with CRC
 
Manual RTU frame with added CRC
-------------------------------
Enter RTU_frame in byte's enter 'DF' when finished
RTU_frame[0] (e.g 01) = 01
RTU_frame[1] (e.g 01) = 02
RTU_frame[2] (e.g 01) = df
Calculated CRC (Hex):     81E1
Total Frame Length (Dec): 4
 
Sending RTU Frame (HEX): -
1 2 81 E1
 
Finished Sending RTU Frame
 
User manually enters a frame of data in hexadecimal, once 0xDF is entered the program assumes that the frame is complete and calculates the 16-bit CRC which is added to the end of the frame. The whole frame is then transmitted through RS232.
 
This function can be used to generate test ‘storage mode’ frames when testing the scope program and test ‘control protocol’ frames for manually controlling the PIC.
 
 
[4] Manual RTU frame no CRC
 
Manual RTU frame no CRC
-------------------------
Enter RTU_frame in byte's enter 'DF' when finished
RTU_frame[0] (e.g 01) = 1
RTU_frame[1] (e.g 01) = 2
RTU_frame[2] (e.g 01) = df
Total Frame Length (Dec): 2
 
Sending RTU Frame (HEX): -
1 2
 
Finished Sending RTU Frame
 
User manually enters a frame of data in hexadecimal, once 0xDF is entered the program assumes that the frame is complete and transmits the frame. This function can be used to generate test ‘real-time’ frames.
 
 
[5] Simulated Random Noise
 
Simulated Random Noise
-----------------------
No delay between bytes                   -- Hit 1
Random delay (0 to 100ms) between bytes  -- hit 2
User sets delay in milliseconds          -- hit 3
Cancel - Return to Main Menu             -- hit 4
 
This function simulates random noise; there are three formats to choose from. The first transmits random bytes through RS232 continuously with no delay between the bytes. The second has a random delay between bytes and the third has a user configurable delay between the bytes.  
 
This function is used to test the reliability of both the scope.exe program and the PIC embedded software. For example simulated noise is sent to the scope.exe program for a couple of hours, during this time the program must not crash and when the random noise has been removed the program must continue to operate normally.
[6] Loop-Back Test
 
  Test Started: 11:02:23
  -----------------------------------
  Testing            .... 100% - FAIL
  * Test 1 - FAIL
  * Test 2 - FAIL
  * Test 3 - FAIL
  -----------------------------------
  Test Finished: 11:02:25
 
Three tests are carried out: -
 
Test 1: Data 0 à 255 à 0 is transmitted with a 16-bit CRC and compared with the received block (514 bytes).
Test 2: Random data from 0 to 255 is transmitted with a 16-bit CRC and compared with the received block (514 bytes).
Test 3:  Random data 0x00 or 0xFF is transmitted with a 16-bit CRC and compared with the received block (514 bytes).
 
This function can test the PC serial port by connecting pin2 and pin3 together (RX & TX), or PIC software can be written to fully test communications by transmitting every character it receives. If this test is successfully, it is certain that communications between the PC and the PIC is extremely good as this test requires an extremely good clean connection (will fail if one character has been corrupted).
 
 
[7] Change Baud Rate
 
  Baud Rate (Current = 009600 bps)
------------------------------------
       115200 bps -- bit 1
        57600 bps -- hit 2
        38400 bps -- hit 3
        19200 bps -- hit 4
        14400 bps -- hit 5
         9600 bps -- hit 6
         4800 bps -- hit 7
         2400 bps -- hit 8
         1200 bps -- hit 9
      No Change   -- hit 0
 
User can change the baud rate by hitting the appropriate key.
 
 
[8] About
 
-----------------------------------------
| Final Year Project EEE516J4           |
| University of Ulster                  |
| BEng (hons) Electronic Systems        |
|                                       |
| Date:         22/02/2002              |
| Revision:     1.05                    |
| By:           Colin K McCord          |
-----------------------------------------
 
Information about the program and the author.
 
 

 
9.2. How is RS232 Communications Achieved?
 
Setup UART constants and RS232 buffer: -
#define COM 0x3f8       /* COM1=0x3f8, COM2=0x2f8  */
#define RBR 0           /* Receive Buffer Register */
#define THR 0           /* Transmit Holding Reg.   */
#define DLL 0           /* Divisor Latch LSB       */
#define DLM 1           /* Divisor Latch MSB       */
#define IER 1           /* Interrupt Enable Reg.   */
#define IIR 2           /* Interrupt ID Register   */
#define FCR 2
#define AFR 2
#define LCR 3           /* Line Control Register   */
#define MCR 4           /* Modem Control Register  */
#define LSR 5           /* Line Status Register    */
#define MSR 6           /* Modem Status Register   */
#define SCR 7           /* The Scratch Register    */
#define I8259M 0x21
#define I8259  0x20     /* The address of the 8259 */
#define EOI    0x20     /* The end of int command  */
 
#define IRQ 4
#define SIZE 512         /* Buffer size       */
 
char buffer[SIZE];       /* Receiving buffer  */
char *i_get, *i_put;     /* Pointer to buffer */
unsigned int baud;       /* Baud Rate         */
 
Initialise UART (set speed, set data format, set ISR address etc…): -
int line,mask;                        /* Comm parameters        */
 
void interrupt(*old_handler)();
old_handler=getvect(IRQ+8);           /* Old ISR address        */
 
i_put=i_get=buffer;                   /* Pointer initialisation */
memset(buffer,0,SIZE);                /* Buffer initialisation  */
 
baud=0x0c;             /* 0x01 = 115200 bps
                          0x02 = 57600  bps
                          0x03 = 38400  bps
                          0x06 = 19200  bps
                          0x0c = 9600   bps */
 
line=0x03;     /* 8 bits, non parity, 1 stop */
 
/* initialisation */
outportb(COM+IER,0);
inportb(COM+LSR);
inportb(COM+MSR);
inportb(COM+IIR);
inportb(COM+RBR);
 
/* set speed */
outportb(COM+LCR, inportb(COM+LCR) | 0x80);
outportb(COM+DLM,baud>>8);
outportb(COM+DLL,baud&0xff);
outportb(COM+LCR,inportb(COM+LCR) & 0x7f);
 
/* set data format */
outportb(COM+LCR,line);
outportb(COM+MCR,0x0b);
outportb(COM+IER,0x01);
 
/* set ISR address */
disable();
setvect (IRQ+8,com_handler);
enable();
 
mask=inportb(I8259M);
mask &=~(1<<IRQ);
outportb(I8259M,mask);
 
Interrupt routine for storing incoming characters on the buffer: -
void interrupt com_handler()
{
        /* -------------------------------------------------------------
           | Function:       com_handler                               |
           | Description:    Interrupt's normal program operation when |
           |                 incoming character's are detected and     |
           |                 store's them on the buffer.               |
           | Input:          none                                      |
           | Output:         Incoming character's stored on buffer     |
           | Return:         none                                      |
           ------------------------------------------------------------- */
 
        *i_put++=inportb(COM+RBR);
        if(i_put==&buffer[SIZE]) i_put=buffer;
        outportb(I8259,EOI);
}
 
Transmitting a single character: -
void trans(int c)
{
        /* -------------------------------------------------------------
           | Function:       trans                                     |
           | Description:    Wait's until UART is ready and then       |
           |                 transmits a single character.             |
           | Input:          Character 'c'                             |
           | Output:         Transmit 'c' through COM port using RS232 |
           | Return:         none                                      |
           ------------------------------------------------------------- */
 
        while(!(inportb(COM+LSR) & 0x20));
        outportb(COM+THR,c);
}
 
Receiving a single character: -
int readchr (char *c)
{
        /* -------------------------------------------------------------
           | Function:       readchr                                   |
           | Description:    Check's if character has been received,   |
           |                 store's received character into 'c'       |
           | Input:          Address of character 'c'                  |
           | Output:         'c' now contains received character       |
           | Return:         0 when character is present else -1       |
           ------------------------------------------------------------- */
 
        if (i_get==i_put) return(-1);
        *c=*i_get++;
        if(i_get==&buffer[SIZE]) i_get=buffer;
        return (0);
}
 
Changing the baud rate after Initialisation: -
void baud_rate(void)
{
        /* -------------------------------------------------------------
           | Function:       baud_rate(void)                           |
           | Description:    User selects, baud rate via keyboard      |
           | Input:          keyboard                                  |
           | Output:         baud rate changed                         |
           | Return:         none                                      |
           ------------------------------------------------------------- */
 
        int rate;      /* Baud Rate */
 
        /* 0x01 = 115200 bps
           0x02 = 57600  bps
           0x03 = 38400  bps
           0x06 = 19200  bps
           0x08 = 14400  bps
           0x0c = 9600   bps */
        clrscr();
 
        rate = (115200 / baud);
        if(baud != 1)
               printf("  Baud Rate (Current = %.6u bps)",rate);
        else
               printf("  Baud Rate (Current = 115200 bps)");
        printf("\n------------------------------------");
        printf("\n       115200 bps -- bit 1");
        printf("\n        57600 bps -- hit 2");
        printf("\n        38400 bps -- hit 3");
        printf("\n        19200 bps -- hit 4");
        printf("\n        14400 bps -- hit 5");
        printf("\n         9600 bps -- hit 6");
        printf("\n         4800 bps -- hit 7");
        printf("\n         2400 bps -- hit 8");
        printf("\n         1200 bps -- hit 9");
        printf("\n      No Change   -- hit 0");
 
        switch(getch())
               {
                       case '1':
                                      baud = 0x01;
                                      break;
                       case '2':
                                      baud = 0x02;
                                      break;
                       case '3':
                                      baud = 0x03;
                                      break;
                       case '4':
                                      baud = 0x06;
                                      break;
 
                       case '5':
                                      baud = 0x08;
                                      break;
                       case '6':
                                      baud = 0x0c;
                                      break;
 
                       case '7':
                                      baud = 0x18;
                                      break;
 
                       case '8':
                                      baud = 0x30;
                                      break;
 
                       case '9':
                                      baud = 0x60;
                                      break;
 
 
                       default:
                                      clrscr();
                                      return;
 
 
               }
 
        /* set speed */
        outportb(COM+LCR, inportb(COM+LCR) | 0x80);
        outportb(COM+DLM,baud>>8);
        outportb(COM+DLL,baud&0xff);
        outportb(COM+LCR,inportb(COM+LCR) & 0x7f);
 
        rate = 115200 / baud;
        if(baud != 1) printf("\n\nBaud Rate Changed to %u bps",rate);
        else          printf("\n\nBaud Rate Changed to 115200 bps",rate);
        clrscr();
}
 
 
The source code is reasonable readably (lots of comments and partitioned into many functions), hence if the reader of this report wises to find out how any other aspect of the program works see appendix ### for the complete source code.
 

Final Year Project

Content Page

Colin's Home Page


This Web Page was last updated on Wednesday June 19, 2002


Home    About me    National Record Of Achievement    Hobbies / Interests   Guest Book    Contact Me    Links    Snooker   Amateur Radio    Site Map


© 2002 Designed by Colin K McCord


This website is best viewed by Microsoft Internet Explorer 6.0 at a resolution of 1024 x 768