/***************************************************/ /* Single-Wire Sensors Interface Directly To A PC */ /* By: Darvinder Singh Oberoi and Harinder Dhingra */ /***************************************************/ #include #include #include #include #pragma inline #define TIMER_FREQUENCY 1193181.7 /* Counter2's operating frequency */ #define PRINTER_PORT 0x378 /* Base Address of Printer Port */ #define READ_PORT PRINTER_PORT + 1 /* Input Pulse Port */ #define Resolution 7 /* ~54.9 ms limit Check Resolution Counts */ #define Delay_Count 4 /* Counting Delays due to iteration and checks*/ /* Resolution and Delay_Count values can be changed to get the most precise reading */ /* Resolution variable is required for checking the new and old reading boundary conditions */ /* Delay variable takes care of delays due to iteration cycles, useful for error correction at small pulse width signal */ /* Both these values should be set to minimum */ /* Minimum input pulse width is approx. 0.023 ms */ float averagedata( unsigned data[20], unsigned data_size ); /* Average of data samples */ void screen_display( ); /* Initial Set Up Screen */ main( ) /* Program Starts Here */ { char ch; unsigned count[20],i,prev_count,elapsed_count ; float pulse_width, overflow; screen_display(); asm mov al, 0b4h /* Set Counter2 mode to 2 */ asm out 043h,al /* 8254's control Port address i.e. 43h */ /*---- Start the read Cycle Here ----*/ for( ;ch != 'q'; ) /* Endless Loop until 'Q' is pressed */ { i=0; for (;;) { asm mov dx, READ_PORT /* Set the input signal port */ asm mov al, 0ffh asm out 042h, al /* Load the initial count in two cycles */ asm out 042h, al /* Counter2 Port address i.e. 42h */ prev_count = 65535; /* Initialization */ overflow = 0.0; /* Check for the first rising edge - i.e. first transition from 0 to 1 */ /* Input Signal is at pin no:13 */ reading_1: asm in ax, dx asm and ax, 10h asm jnz reading_1 reading_0: asm in ax, dx asm and ax, 10h asm jz reading_0 /* Enable Counter2 */ asm mov al, 01h /* Set enable bit */ asm out 061h, al /* Check for High level input signal */ still_reading_1: asm in al, 042h /* Read the contents of counter2*/ asm mov bl, al asm in al, 042h asm mov bh, al asm mov elapsed_count, bx /* Check if pulse width is greater than multiples of ~54.9 mS */ /* If pulse is greater, then increment the overflow flag */ if( ( prev_count <= Resolution) && (elapsed_count >= (65536 - Resolution) ) ) ++overflow; prev_count = elapsed_count; asm in ax, dx asm and ax, 10h asm jnz still_reading_1 count[ i ] = elapsed_count; /* Store data in array */ /* Disable the counter as soon as 1-to-0 transistion is detected */ asm mov al, 0h /* Reset the enable bit to 0 */ asm out 061h, al /* Disable counter */ /* If pulse width is less than 1 mS */ if ( elapsed_count >= 64343 && overflow == 0 ) { ++i; if ( i > 19 ) break; } else /* Pulse width greater than 1mS */ { i = 1; break; } } /* Start Calculations, get the average data */ pulse_width = (overflow * 65536.0+(float)(0xffff - averagedata(count,i-1)+Delay_Count)) * 1000 /TIMER_FREQUENCY ; gotoxy( 35,11 ); printf("%3.5f ", pulse_width); gotoxy( 35,11 ); delay( 20 ); /* Dummy Delay */ if( kbhit( ) ) /* Check for Quit keys */ ch = getch( ); if( ch == 'q' || ch == 'Q' ) ch ='q'; } textcolor( LIGHTGRAY ); /* Restore screen attributes */ clrscr( ); } /*--- End of the MAIN Program ---*/ /* Arrange the data in ascending order and select 10 middle entries */ float averagedata( unsigned data[ ], unsigned data_size ) { float total_sum = 0; unsigned temp; int ii,j; /* Arrange data in ascending order */ if ( data_size > 1 ) { for( ii=0; ii <= data_size; ii++ ) { for( j=0; j <= data_size - 1; j++ ) { if( data[ j ] <= data[ j + 1 ] ) { temp = data[ j ]; data[ j ]= data[ j + 1 ]; data[ j + 1 ] = temp; } } } /* Get 10 middle values and find the average */ for( ii=5; ii <= 14; ii++ ) total_sum = total_sum + (float) data[ ii ]; total_sum /= 10.0; return total_sum; } else return data[ 0 ]; } /* Initial screen setup */ void screen_display( ) { clrscr( ); textcolor( YELLOW ); gotoxy( 25, 2 ); cprintf("Pulse Width Measurement"); gotoxy( 5, 11 ); textcolor( YELLOW ); gotoxy( 30, 10 ); cprintf( "Pulse Width (ms)" ); gotoxy( 20, 22 ); cprintf( "< Press Q/q key to Quit the Program > " ); }