#include #include #include #include #include #include #include #include #include const unsigned INT = 5; const unsigned RECEIVE = 0; const unsigned TRANSMIT = 0; const unsigned L_DIVISOR = 0; const unsigned U_DIVISOR = 1; const unsigned INT_ENB = 1; const unsigned INT_ID = 2; const unsigned LINE_CTRL = 3; const unsigned MODEM_CTRL = 4; const unsigned LINE_STAT = 5; const unsigned MODEM_STAT = 6; unsigned int Address = 0x300; void initCommCard(unsigned baudRate, unsigned baseAddr); void writePod(unsigned baseAddr, char message[255]); void readPod(unsigned baseAddr, char message[255]); static void near dummy (void) {} // returns negation of contents of on-board 8253 counter static unsigned near readtimer (void) { asm pushf asm cli asm mov al,0h asm out 43h,al dummy(); asm in al,40h asm mov bl,al dummy(); asm in al,40h asm mov bh,al asm not bx asm popf return( _BX ); } // computer independent delay used for timout purposes. void comdelay( unsigned timer_ticks ) { unsigned long stop; unsigned cur, prev; stop = (prev = readtimer()) + (timer_ticks); while ((cur = readtimer()) < stop) { if (cur < prev) { if (stop < 0x10000L) break; stop -= 0x10000L; } prev = cur; } } void initCommCard(unsigned baseAddr, unsigned baudRate) { unsigned divisor; // Oscillator frequency is 1.8432MHz, or 1,843,200 Hz // The divisor is calculated by dividing the frequency by 16, then dividing // again by the baudrate, or --- divisor = (f / 16) / baudrate // 1,843,200 / 16 is 115200, so - divisor = 115200 / baudRate; // tell card, we are about to set options outp(baseAddr + LINE_CTRL, 0x80); // assign 16 bit AX register to our divisor, so we can load the // card with the low and high bytes of the divisor. _AX = divisor; outp(baseAddr + L_DIVISOR, _AL); outp(baseAddr + U_DIVISOR, _AH); // set the card the 7 bits of data, even parity and 1 stop bit outp(baseAddr + LINE_CTRL, 0x1A); outp(baseAddr + MODEM_CTRL, 0x00); // clear the receive buffer delay(50); inp(baseAddr + RECEIVE); delay(50); inp(baseAddr + RECEIVE); } void writePod(unsigned baseAddr, char message[255]) { unsigned char x, times; // get length of the string to send x = strlen(message); // set the card into transmit mode outp(baseAddr + MODEM_CTRL, 0x0F); for (times = 0; times < x; times++) { // wait until the card is ready to transmit a character while ((inp(baseAddr+LINE_STAT) & 0x20) == 0); // transmit the character outp(baseAddr+TRANSMIT, message[times]); } // wait until the character is transmitted while ((inp(baseAddr+LINE_STAT) & 0x20) == 0); // transmit a Carriage Return outp(baseAddr+TRANSMIT, 0x0D); // wait until CR is transmitted while ((inp(baseAddr+LINE_STAT) & 0x20) == 0); // wait for the card to come back while ((inp(baseAddr+LINE_STAT) & 0x40) == 0); // place the card into receive mode outp(baseAddr+MODEM_CTRL, 0x0D); } void readPod(unsigned baseAddr, char message[255]) { unsigned char x = 255, ch; char retstring[255] = ""; unsigned int timeout; do { // character location in string is incremented x++; // timeout initialized timeout = 400; do { // decrement our timeout counter timeout--; // wait for 200 counter ticks comdelay(200); // wait until the card sees a character or until our counter has // timed out. } while ((timeout) && ((inp(baseAddr+LINE_STAT) & 0x01) == 0x00)); // if it has not timed out, store the character if (timeout != 0x00) retstring[x] = inp(baseAddr + RECEIVE); // otherwise, return with an error message else { strcpy(message, "??ERROR!"); return; } // repeat for fifty characters } while ((retstring[x] != 0x0D) && (x-1 != 80)); // null terminate the return string retstring[x] = 0x00; // copy it to the string pointer strcpy(message, retstring); // and clear the receive buffers delay(50); inp(baseAddr + RECEIVE); delay(50); inp(baseAddr + RECEIVE); } unsigned AskForBaseAddress(unsigned int OldOne) { char msg[7]; int NewOne = 0, Success = 0, Dummy; int AddrInputPosX, AddrInputPosY; puts("\nPlease enter the Base Address for your card (in hex)"); printf("or press ENTER for %X.\n>", OldOne); AddrInputPosX = wherex(); AddrInputPosY = wherey(); do { gotoxy(AddrInputPosX, AddrInputPosY); clreol(); msg[0] = 5; msg[1] = 0; cgets(msg); sscanf(msg + 2, "%x", &NewOne); Success = 1; Dummy = NewOne; if (msg[1] == 0) { gotoxy(AddrInputPosX, AddrInputPosY); printf("%X", OldOne); Success = 1; Dummy = OldOne; } } while(!Success); return (Dummy); } /* end of AskForBaseAddress */ //calibration routine float cal(int data) { static int once=1; static float CALscale=0.0L; static int CALoffset; char MSG[256]="\0"; int tempscale=0; if (once){ writePod(Address, "CAL?"); readPod(Address,MSG); if ( (strlen(MSG)==9) && (MSG[4]==',') ) { //msg is prob. xxxx,xxxx sscanf(MSG,"%i",&tempscale); sscanf(&MSG[5],"%4x",&CALoffset); //convert twos-complement into int. CALscale=(tempscale== 0.0 )? 1.0 :tempscale/1000.0; once=0; }else { //some error occurred making it impossible to retrieve cal data. //use default data, and inform user. clrscr(); textcolor(RED); puts("LOAD CALIBRATION DATA FAILED DURING INIT"); puts("USING scale=1.0 offset=0"); puts("Please Re-run sample to try again."); textcolor(LIGHTGRAY); } } return ((data * CALscale) + CALoffset); //cal value=(scale)*oldval+offset //Y = mX+b }//end cal void printCurrentPointList(void) { int Loop = 0; char MyStr[255]; clrscr(); puts(""); puts("The current point list configuration for channels 0-7 is :"); for (Loop = 0; Loop < 8; Loop++) { sprintf(MyStr, "PL0%X?", Loop); // read the point configuration writePod(Address, MyStr); // using the PLnn? command readPod(Address, MyStr); printf(" %s", MyStr); } puts(""); puts(""); } void changePointList(void) { int Loop = 0; char MyStr[255]; puts(""); puts("Changing point list to acquire all even channels, then all odd . . ."); for (Loop = 0; Loop < 4; Loop++) { // even sprintf(MyStr, "PL0%c=10%c0", Loop+48,(Loop*2)+48); writePod(Address, MyStr); // change the point list printf("%s, ", MyStr); // PLnn=xxxx readPod(Address, MyStr); //odd sprintf(MyStr, "PL0%c=10%c0", Loop+4+48,(Loop*2)+1+48); writePod(Address, MyStr); // change the point list printf("%s, ", MyStr); // PLnn=xxxx readPod(Address, MyStr); } puts(""); puts("Press ENTER to proceed . . ."); getch(); } void displayData(void) { char Done = 0; char MyStr[255], tempStr[255]; int Loop = 0, Start = 0; int Value = 0; clrscr(); puts("The data being read from the pod is displayed below."); puts("Channels are as shown, the pod is actually acquiring"); puts("the data in this order."); puts(""); puts("Press a key to finish the program . . ."); while (!kbhit()) { writePod(Address, "AC00-07,0008"); // Acquire points 0 through 7 Done = 0; while (!Done) { writePod(Address, "R"); // attempt to read data readPod(Address, MyStr); Done = ((MyStr[0] != 0) && (MyStr[0] != 7)); // if !done, keep trying } for (Loop = 0; Loop < 8; Loop++) { Start = (Loop * 7) + 2; strncpy(tempStr, &MyStr[Start], 4); // copy four characters sscanf(tempStr, "%X", &Value); // convert to numbers gotoxy(15, (Loop * 2) + 9); if (Loop <= 3) // and print printf("Channel %.2hu: % 3.3f", Loop*2, ((10.0/4096) * (cal(Value)))); else printf("Channel %.2hu: % 3.3f", ((Loop-4)*2)+1, ((10.0/4096)*(cal((int)Value)))); } } } void main(void) { clrscr(); puts("RAD128 Sample Program"); puts(""); puts("This program will show you how to display and configure the"); puts("point list to acquire data. First, the even channels"); puts("are displayed, then the odds."); puts(""); puts("The card must be configured as follows:"); puts(" RAD128 is set at address 00"); puts(" Communications is at 9600 bps"); puts(" Base address of RS485 card is configureable"); puts(""); puts("Press ENTER to continue . . ."); getch(); Address = AskForBaseAddress(Address); initCommCard(Address, 9600); printCurrentPointList(); changePointList(); displayData(); clrscr(); puts("Exiting Sample 1 . . ."); }