Download:
/* In the following C language code, 1- wire I/O is accomplished using the serial port of an IBM PC or compatible. The serial port must be capable of a 115,200 bps data rate. Setup must be called before any of the touch functions to verify the existence of the specified com port and initialize it. -------------------------------------------------------------------- The setup function makes sure that the com port number passed to it is from 1 to 4 and has a valid address associated with it. */ #include <assert.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <dos.h> #include <malloc.h> typedef unsigned char uchar; typedef unsigned int uint; typedef unsigned long ulong; static uchar com_port; /* 0x2F8 = COM2 */ static char *TouchMemStatus[5] = { " 0 no presence detect", " 1 presence pulse no alarm OK", " 2 alarm followed by presence", " 3 short circuit to ground", " 4 no com port found" }; #define FL 0 #define TR 1 uchar Setup (uchar CmPt) { uint far *ptr = (uint far *) 0x00400000; uint SPA; com_port = CmPt; /* check to see if it is a valid com port number and address */ SPA = *(ptr + CmPt - 1); /* get the address */ if (CmPt < 1 || CmPt > 4 || !SPA) return FL; /* serial port initialization */ outportb (SPA + 3, 0x83); /* set DLAB */ outportb (SPA, 0x01); /* bit rate is 115200 */ outportb (SPA + 1, 0x00); outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */ outportb (SPA + 1, 0x00); /* no interrupts */ outportb (SPA + 4, 0x03); /* RTS and DTR on */ printf("COM port #%d at 0x%0x\n", com_port, SPA); return TR; } /*------------------------------------------------------------------------ * Do a reset on the 1 wire port and return * 0 no presence detect * 1 presence pulse no alarm * 2 alarm followed by presence * 3 short circuit to ground * 4 no com port found * * The global variable 'com_port' must be set to the com port that the * DS9097 COM Port Adapter is attached to before calling this routine. * */ uchar TouchReset (void) { uint SPA, F, X, Y, tmp, trst = 0; uint far *ptr = (uint far *) 0x00400000; ulong far *sysclk = (ulong far *) 0x0040006c; ulong M; /* get the serial port address */ SPA = *(ptr + com_port - 1); /* return if there is no address */ if (!SPA) return 4; /* serial port initialization */ outportb (SPA + 3, 0x83); /* set DLAB */ outportb (SPA, 0x01); /* bit rate is 115200 */ outportb (SPA + 1, 0x00); outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */ outportb (SPA + 1, 0x00); /* no interrupts */ outportb (SPA + 4, 0x03); /* RTS and DTR on */ /* Initialize the time limit */ M = *sysclk + 1; /* loop to clear the buffers */ do { tmp = inportb (SPA + 5) & 0x60; } while (tmp != 0x60); /* flush input */ while (inportb (SPA + 5) & 0x1) X = inportb (SPA); outportb (SPA + 3, 0x83); /* set DLAB */ outportb (SPA + 1, 0x00); /* baud rate is 10473 */ outportb (SPA, 0x0B); outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */ outportb (SPA, 0xF0); /* send the reset pulse */ /* wait until character back or timeout */ do { Y = inportb (SPA + 5); F = Y & 0x1; } while (!F && (*sysclk <= M)); if (F) X = inportb (SPA); else return 3; if (X != 0xF0) /* if more bits back than sent then there */ { /* is a device if framing error or break */ trst = TR; if ((Y & 0x18) != 0) { trst = 2; /* loop to clear the buffers */ do { tmp = inportb (SPA + 5) & 0x60; } while (tmp != 0x60); /* wait until character back or timeout */ do { Y = inportb (SPA + 5); F = Y & 0x1; } while (!F && (*sysclk <= M)); if (F) X = inportb (SPA); else return 3; } } outportb (SPA + 3, 0x83); /* set DLAB */ outportb (SPA, 0x01); /* bit rate is 115200 */ outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */ return trst; } /*------------------------------------------------------------------------ * This is the 1- Wire routine 'TouchByte', sometimes called 'DataByte'. * It transmits 8 bits onto the 1- Wire data line and receives 8 bits * concurrently. The global variable 'com_port' must be set to the * com port that the serial brick is attached to before calling this * routine. This com port must also be set to 115200 baud, 8 dta, 1 stp, * and no parity. This routine returns the uchar 8 bit value received. * If it times out waiting for a character then 0xFF is returned. */ uchar TouchByte (uchar outch) { uchar inch = 0, sendbit, Mask = 1; uint SPA; uint far *ptr = (uint far *) 0x00400000; ulong far *sysclk = (ulong far *) 0x0040006c; ulong M; /* get the serial port address */ SPA = *(ptr + com_port - 1); /* Initialize the time limit */ M = *sysclk + 2; /* wait to TBE and TSRE */ do { } while ((inportb (SPA + 5) & 0x60) != 0x60); /* flush input */ while ((inportb (SPA + 5) & 0x1)) inportb (SPA); /* get first bit ready to go out */ sendbit = (outch & 0x1) ? 0xFF : 0x00; /* loop to send and receive 8 bits */ do { outportb (SPA, sendbit); /* send out the bit */ /* get next bit ready to go out */ Mask <<= 1; sendbit = (outch & Mask) ? 0xFF : 0x00; /* shift input char over ready for next bit */ inch >>= 1; /* loop to look for the incoming bit */ for (;;) { /* return if out of time */ if (*sysclk > M) return 0xFF; if (inportb (SPA + 5) & 0x01) { inch |= ((inportb (SPA) & 0x01) ? 0x80 : 0x00); break; } } } while (Mask); return inch; /* return the input char */ } static unsigned char **rom_table; static int sensors; static int read_time; static int read_config(void) { char buf[80]; int i; FILE *f = fopen("digitemp.cfg", "r"); if (f == NULL) { perror("digitemp.cfg"); return -1; } while (!feof(f)) { fgets(buf, 80, f); if (strncmp (buf, "SENSORS", 7) == 0) { sscanf(buf+7, "%d", &sensors); printf("%d sensors in table\n", sensors); rom_table = (unsigned char **) malloc(sensors*sizeof(unsigned char *)); for (i = 0; i < sensors; i++) rom_table[i] = (unsigned char *) malloc(8); continue; } if (strncmp (buf, "ROM", 3) == 0) { int num, rom[8]; sscanf(buf+3, "%d%d%d%d%d%d%d%d%d", &num, &rom[0], &rom[1], &rom[2], &rom[3], &rom[4], &rom[5], &rom[6], &rom[7]); for (i = 0; i < 8; i++) { rom_table[num][i] = (unsigned char)rom[i]; } continue; } if (strncmp (buf, "READ_TIME", 9) == 0) sscanf(buf+9, "%d", &read_time); } return 0; } static void dump(void) { int i; for (i = 0; i < sensors; i++) { int j; printf("%02X%02X%02X%02X%02X%02X%02X%02X\t", rom_table[i][0], rom_table[i][1], rom_table[i][2], rom_table[i][3], rom_table[i][4], rom_table[i][5], rom_table[i][6], rom_table[i][7]); TouchReset(); TouchByte(0x55); /* Match ROM */ for (j = 0; j < 8; j++) TouchByte(rom_table[i][j]); TouchByte(0xBE); /* Read scratchpad */ for (j = 0; j < 8; j++) printf("%02X ", (int)TouchByte(0xFF)); TouchReset(); printf("\n"); } printf("read_time = %d\n", read_time); } void write_E2(int device_num, unsigned char byte1, unsigned char byte2) { int i; TouchReset(); TouchByte(0x55); /* Match ROM */ for (i = 0; i < 8; i++) TouchByte(rom_table[device_num][i]); TouchByte(0x4E); /* Write scratchpad */ TouchByte(byte1); TouchByte(byte2); TouchReset(); TouchByte(0x55); /* Match ROM */ for (i = 0; i < 8; i++) TouchByte(rom_table[device_num][i]); TouchByte(0x48); /* copy scratchpad */ delay(20); TouchReset(); } unsigned char *read_temp(int device_num) { int i; static unsigned char scratchpad[9]; TouchReset(); TouchByte(0x55); /* Match ROM */ for (i = 0; i < 8; i++) TouchByte(rom_table[device_num][i]); TouchByte(0x44); /* Convert T */ delay(read_time); TouchReset(); TouchByte(0x55); /* Match ROM */ for (i = 0; i < 8; i++) TouchByte(rom_table[device_num][i]); TouchByte(0xBE); /* Convert T */ for (i = 0; i < 9; i++) scratchpad[i] = TouchByte(0xFF); TouchReset(); return scratchpad; } float temp(unsigned char *scratchpad) { short temp_read; float d; temp_read = scratchpad[0] & 0xFE | scratchpad[1] << 8; d = (float)(scratchpad[7] -scratchpad[6])/(float)scratchpad[7]; return (float)temp_read/2.0 - 0.25 + d + (float)(scratchpad[2] * 256 + scratchpad[3])/100.0; } int main() { uchar status; uint address; uchar data; uint single; uint portnum = 1; char filename[150]; FILE *fp; read_config(); Setup(portnum); /* COM port number */ status = TouchReset(); printf("TouchReset: %s\n", TouchMemStatus[status]); for (;;) { fflush(stdin); printf("1:Dump 2:Single 3:All 4:Clibrate 5:Clear calib. 6:Port num 7:Exit >>>"); switch(getchar()) { case '1': dump(); break; case '2': { int i; printf("Device number:"); scanf("%d", &i); printf("T = %.2f C\n", temp(read_temp(i))); } break; case '3': { int i; for(i = 0; i < sensors; i++) printf("T%d = %.2f C\n", i, temp(read_temp(i))); } break; case '4': { #ifdef OVERLALL_AVERAGING float *t, *diff, avg; int i, j, iterations; printf("Averaging iterations:"); scanf("%d", &iterations); t = (float *)malloc(sensors * sizeof(float)); diff = (float *)malloc(sensors * sizeof(float)); for (i = 0; i < sensors; i++) { t[i] = 0.0; diff[i] = 0.0; } for (j = 0; j < iterations; j++) { printf("[%d]", j); avg = 0.0; for (i = 0; i < sensors; i++) { t[i] = temp(read_temp(i)); avg += t[i]; } avg /= sensors; for (i = 0; i < sensors; i++) diff[i] += t[i] - avg; } for (i = 0; i < sensors; i++) { short d = - diff[i]/iterations*100.0; unsigned char th = d >> 8; unsigned char tl = d & 0x00FF; write_E2(i, th, tl); } free(t); free(diff); #else /* TRUE calibration */ float reference; int i; printf("Reference temperature:"); scanf("%f", &reference); for (i = 0; i < sensors; i++) { short d = 100*(reference - temp(read_temp(i))); unsigned char th = d >> 8; unsigned char tl = d & 0x00FF; write_E2(i, th, tl); } #endif } break; case '5': { int i; for (i = 0; i < sensors; i++) write_E2(i, 0, 0); } break; case '6': printf("COM port number (1,2):"); scanf("%d", &portnum); Setup(portnum); /* COM port number */ status = TouchReset(); printf("TouchReset: %s\n", TouchMemStatus[status]); break; case '7': return 0; default: printf("Input error\n"); } } }
/* In the following C language code, 1- wire I/O is accomplished using the serial port of an IBM PC or compatible. The serial port must be capable of a 115,200 bps data rate. Setup must be called before any of the touch functions to verify the existence of the specified com port and initialize it. -------------------------------------------------------------------- The setup function makes sure that the com port number passed to it is from 1 to 4 and has a valid address associated with it. */ #include <ctype.h> #include <stdio.h> #include <dos.h> typedef unsigned char uchar; typedef unsigned int uint; typedef unsigned long ulong; static uchar com_port; /* 0x2F8 = COM2 */ static char *TouchMemStatus[5] = { " 0 no presence detect", " 1 presence pulse no alarm", " 2 alarm followed by presence", " 3 short circuit to ground", " 4 no com port found" }; #define FL 0 #define TR 1 uchar Setup (uchar CmPt) { uint far *ptr = (uint far *) 0x00400000; uint SPA; com_port = CmPt; /* check to see if it is a valid com port number and address */ SPA = *(ptr + CmPt - 1); /* get the address */ if (CmPt < 1 || CmPt > 4 || !SPA) return FL; /* serial port initialization */ outportb (SPA + 3, 0x83); /* set DLAB */ outportb (SPA, 0x01); /* bit rate is 115200 */ outportb (SPA + 1, 0x00); outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */ outportb (SPA + 1, 0x00); /* no interrupts */ outportb (SPA + 4, 0x03); /* RTS and DTR on */ printf("COM port #%d at 0x%0x\n", com_port, SPA); return TR; } /*------------------------------------------------------------------------ * Do a reset on the 1 wire port and return * 0 no presence detect * 1 presence pulse no alarm * 2 alarm followed by presence * 3 short circuit to ground * 4 no com port found * * The global variable 'com_port' must be set to the com port that the * DS9097 COM Port Adapter is attached to before calling this routine. * */ uchar TouchReset (void) { uint SPA, F, X, Y, tmp, trst = 0; uint far *ptr = (uint far *) 0x00400000; ulong far *sysclk = (ulong far *) 0x0040006c; ulong M; /* get the serial port address */ SPA = *(ptr + com_port - 1); /* return if there is no address */ if (!SPA) return 4; /* serial port initialization */ outportb (SPA + 3, 0x83); /* set DLAB */ outportb (SPA, 0x01); /* bit rate is 115200 */ outportb (SPA + 1, 0x00); outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */ outportb (SPA + 1, 0x00); /* no interrupts */ outportb (SPA + 4, 0x03); /* RTS and DTR on */ /* Initialize the time limit */ M = *sysclk + 1; /* loop to clear the buffers */ do { tmp = inportb (SPA + 5) & 0x60; } while (tmp != 0x60); /* flush input */ while (inportb (SPA + 5) & 0x1) X = inportb (SPA); outportb (SPA + 3, 0x83); /* set DLAB */ outportb (SPA + 1, 0x00); /* baud rate is 10473 */ outportb (SPA, 0x0B); outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */ outportb (SPA, 0xF0); /* send the reset pulse */ /* wait until character back or timeout */ do { Y = inportb (SPA + 5); F = Y & 0x1; } while (!F && (*sysclk <= M)); if (F) X = inportb (SPA); else return 3; if (X != 0xF0) /* if more bits back than sent then there */ { /* is a device if framing error or break */ trst = TR; if ((Y & 0x18) != 0) { trst = 2; /* loop to clear the buffers */ do { tmp = inportb (SPA + 5) & 0x60; } while (tmp != 0x60); /* wait until character back or timeout */ do { Y = inportb (SPA + 5); F = Y & 0x1; } while (!F && (*sysclk <= M)); if (F) X = inportb (SPA); else return 3; } } outportb (SPA + 3, 0x83); /* set DLAB */ outportb (SPA, 0x01); /* bit rate is 115200 */ outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */ return trst; } /*------------------------------------------------------------------------ * This is the 1- Wire routine 'TouchByte', sometimes called 'DataByte'. * It transmits 8 bits onto the 1- Wire data line and receives 8 bits * concurrently. The global variable 'com_port' must be set to the * com port that the serial brick is attached to before calling this * routine. This com port must also be set to 115200 baud, 8 dta, 1 stp, * and no parity. This routine returns the uchar 8 bit value received. * If it times out waiting for a character then 0xFF is returned. */ uchar TouchByte (uchar outch) { uchar inch = 0, sendbit, Mask = 1; uint SPA; uint far *ptr = (uint far *) 0x00400000; ulong far *sysclk = (ulong far *) 0x0040006c; ulong M; /* get the serial port address */ SPA = *(ptr + com_port - 1); /* Initialize the time limit */ M = *sysclk + 2; /* wait to TBE and TSRE */ do { } while ((inportb (SPA + 5) & 0x60) != 0x60); /* flush input */ while ((inportb (SPA + 5) & 0x1)) inportb (SPA); /* get first bit ready to go out */ sendbit = (outch & 0x1) ? 0xFF : 0x00; /* loop to send and receive 8 bits */ do { outportb (SPA, sendbit); /* send out the bit */ /* get next bit ready to go out */ Mask <<= 1; sendbit = (outch & Mask) ? 0xFF : 0x00; /* shift input char over ready for next bit */ inch >>= 1; /* loop to look for the incoming bit */ for (;;) { /* return if out of time */ if (*sysclk > M) return 0xFF; if (inportb (SPA + 5) & 0x01) { inch |= ((inportb (SPA) & 0x01) ? 0x80 : 0x00); break; } } } while (Mask); return inch; /* return the input char */ } static uchar rom[8]; void ReadRom(void) { int i; uchar code; TouchReset(); TouchByte(0x33); for (i=0; i < 8; i++) rom[i] = TouchByte(0xFF); } #define DEVICE_ID (uchar)rom[0] #define SERIAL (unsigned long )(*((unsigned long *)(rom+1))) #define CRC (uchar)rom[7] uchar ReadMem(uint address) { TouchReset(); TouchByte(0xCC); TouchByte(0xF0); TouchByte(address & 0x00FF); TouchByte((address >> 8) & 0x00FF); return TouchByte(0xFF); } void DumpMemory(void) { uint address; TouchReset(); TouchByte(0xCC); TouchByte(0xF0); TouchByte(0x00); TouchByte(0x00); for (address = 0; address < 128; address++) { uchar asc[17]; asc[16] = '\0'; if(address % 16 == 0) printf("\n%04X ",address); printf("%02X ", (asc[address % 16] = TouchByte(0xFF))); if(address % 16 == 15) { int i; for (i = 0; i < 16; i++) if (!isalnum(asc[i])) asc[i] = '.'; printf("%16s",asc); } } printf("\n"); TouchReset(); } #define TB(x) printf("TouchByte(0x%02X)= 0x%02X\n", (x), TouchByte(x)) uchar WriteMem(uint address, uchar data) { uchar TA1, TA2, ES; TA1 = (uchar)address; TA2 = (uchar)(address >> 8); /* Write to scratchpad */ TouchReset(); TouchByte(0xCC); TouchByte(0x0F); TouchByte(TA1); TouchByte(TA2); TouchByte(data); /* Read from scratchpad */ TouchReset(); TouchByte(0xCC); TouchByte(0xAA); if ( TouchByte(0xFF) != TA1 ) printf("Error: Invalid LOW address return\n"); if ( TouchByte(0xFF) != TA2 ) printf("Error: Invalid HIGH address return\n"); if ( (ES = TouchByte(0xFF)) & 0x40) printf("Error: Overflow\n"); if ( TouchByte(0xFF) != data) printf("Invalid data returned\n"); /* COPY scratchpad */ TouchReset(); TouchByte(0xCC); TouchByte(0x55); TouchByte(TA1); TouchByte(TA2); TouchByte(ES); return 0; } int main() { uchar status; uint address; uchar data; uint single; uint portnum = 2; char filename[150]; FILE *fp; Setup(portnum); /* COM port number */ status = TouchReset(); printf("TouchReset: %s\n", TouchMemStatus[status]); ReadRom(); printf("Device ID: %d, Serial number: %08lX\, CRC: 0x%0X\n", DEVICE_ID, SERIAL, CRC); for (;;) { fflush(stdin); printf("1:Dump 2:Single 3:Polute 4:Load 5:Save mem. 6:Port num 7:Exit >>>"); switch(getchar()) { case '1': ReadRom(); printf("Device ID: %d, Serial number: %08lX\, CRC: 0x%0X\n", DEVICE_ID, SERIAL, CRC); DumpMemory(); break; case '2': printf("Address (hex):"); scanf("%x", &single); printf("Data (hex):"); scanf("%x", &data); printf("Writting : (%04x) <- %02x\n", single, data); WriteMem(single, data); break; case '3': printf("Data for polution (hex):"); scanf("%X", &data); for(address = 0 ; address < 128; address++) WriteMem(address, data); break; case '4': printf("Filename to read:"); scanf("%s", filename); fp = fopen(filename, "r"); if (fp == NULL) { perror(filename); break; } for (address = 0; address < 128; address++) { fscanf(fp, "%x", &data); printf("%02x%c", data, address % 16 == 15 ? '\n' : ' '); WriteMem(address, data); } fclose(fp); break; case '5': printf("Filename to write:"); scanf("%s", filename); fp = fopen(filename, "w"); if (fp == NULL) { perror(filename); break; } for (address = 0; address < 128; address++) { data = ReadMem(address); fprintf(fp, "%02x%c", data, address % 16 == 15 ? '\n' : ' '); } fclose(fp); break; case '6': printf("COM port number (1,2):"); scanf("%d", &portnum); Setup(portnum); /* COM port number */ status = TouchReset(); printf("TouchReset: %s\n", TouchMemStatus[status]); break; case '7': return 0; default: printf("Input error\n"); } } }