The example below illustrates various methods of setting up analog input sample timing. There are two primary parameters needed to setup timing: time between frames, and time between samples (i.e. ADC-burst timing).
One must call the STX104_AI_Time_Settling_Minimum() function to determine the minimum timing possible between samples or the intra-sample timing or minimum ADC-burst timing.
The functions within the examples below will compute and configure the proper analog input timing registers based on firmware revision level. If only 8254 timers are used, then resolution is fixed to 1uSec. In the case of using the Analog Input Frame Timer and the Analog Input Burst Timer, resolution is improved to 25 nanoseconds.
When using the triggering subystem, to synchronize analog input sampling to the trigger-start event, set the SAIFTTS bit in the Analog Input General Configuration Register. If the SAIFTTS='0', then the analog sampling will begin
#define STX104_INTRA_SAMPLE_TIMING 5000 /* nanoseconds */ #define STX104_TIME_RESOLUTION 25 /* nanoseconds */ /*################################################################################## * ANALOG INPUT TIMING FUNCTIONS */ /***************************************************************** / ANALOG INPUT MINIMUM SETTLING TIME */ static unsigned long STX104_AI_Time_Settling_Minimum( float ai_capacitance_pf, float ai_resistance_ohms ) { unsigned long settle_time_ns; //settle_time = ai_resistance_ohms * ai_capacitance_pf * pow10(-12) * 16 * ln(2) * pow10(9) settle_time_ns = (unsigned long) ( ai_resistance_ohms * ai_capacitance_pf * pow10(-3) * 16 * log(2) ); return( settle_time_ns ); } /***************************************************************** / ANALOG INPUT 8254 TIMING */ static void STX104_AI_Timing_8254_Set( int board, long time_interval_ns ) { long high_count; long low_count; unsigned int octet; STX104_Set_Bank( board, 0 ); /* assumes 10MHz clock (i.e. no 1MHz jumper) */ low_count = 10L; /* 1 microsecond intervals */ high_count = time_interval_ns / 1000; while ( high_count > 65536L ) { high_count = high_count >> 1; low_count = low_count << 1; } while ( high_count < 2L ) { high_count = high_count << 1; low_count = low_count >> 1; } /* set counter/timer 2 */ outportb( stx104_base_address[board] + STX104_CT_CONFIGURATION, 0xB4 ); octet = ((unsigned int) high_count) & 0x00FF; outp( stx104_base_address[board] + STX104_CT2_DATA, octet ); octet = ((unsigned int) high_count) >> 8; outp( stx104_base_address[board] + STX104_CT2_DATA, octet ); /* set counter/timer 1 */ outportb( stx104_base_address[board] + STX104_CT_CONFIGURATION, 0x74 ); octet = ((unsigned int) low_count) & 0x00FF; outp( stx104_base_address[board] + STX104_CT1_DATA, octet ); octet = ((unsigned int) low_count) >> 8; outp( stx104_base_address[board] + STX104_CT1_DATA, octet ); } /***************************************************************** / ANALOG INPUT GENERAL TIMING */ static void STX104_AI_Timing_Set( int board, unsigned long ai_time_frame_ns, unsigned long ai_time_intra_sample_ns ) { unsigned int adc_burst_channel_count; switch ( stx104_revision[board] ) { case STX104_REVISION_080214: STX104_Set_Bank( board, 1 ); STX104_Write_Indexed_Data_Byte( board, STX104_BURST_FUNCTION_ENABLE_INDEXED, 0x40 ); STX104_Write_Indexed_Data_Byte( board, STX104_BURST_MODE_ENABLE_INDEXED, 0x40 ); STX104_Write_Indexed_Data_Byte( board, STX104_CONVERSION_DISABLE_INDEXED, 0x00 ); adc_burst_channel_count = (unsigned char)( 0x0F & ( stx104_ai_channel_last[board] - stx104_ai_channel_first[board] ) ); adc_burst_channel_count = adc_burst_channel_count << 4; outp( stx104_base_address[board] + STX104_PACER_CLOCK_CONTROL, adc_burst_channel_count ); /* the following registers require the number of 25nSec intervals to achieve the selected timing */ STX104_Write_Indexed_Data_Dword( board, STX104_ANALOG_INPUT_FRAME_TIMER, ( ai_time_frame_ns/STX104_TIME_RESOLUTION ) ); STX104_Write_Indexed_Data_Dword( board, STX104_ANALOG_INPUT_BURST_TIMER, ( (ai_time_intra_sample_ns - STX104_INTRA_SAMPLE_TIMING) / STX104_TIME_RESOLUTION ) ); break; default: if ( ai_time_intra_sample_ns > STX104_INTRA_SAMPLE_TIMING /*nS*/ ) { /* cannot use adc-burst mode */ STX104_AI_Timing_8254_Set( board, ai_time_intra_sample_ns ); outp( stx104_base_address[board] + STX104_BURST_FUNCTION, 0x00 ); outp( stx104_base_address[board] + STX104_BURST_MODE_ENABLE, 0x00 ); outp( stx104_base_address[board] + STX104_CONVERSION_DISABLE, 0x00 ); } else { /* utilize adc-burst mode */ STX104_AI_Timing_8254_Set( board, ai_time_frame_ns ); outp( stx104_base_address[board] + STX104_BURST_FUNCTION, 0x40 ); outp( stx104_base_address[board] + STX104_BURST_MODE_ENABLE, 0x40 ); outp( stx104_base_address[board] + STX104_CONVERSION_DISABLE, 0x00 ); adc_burst_channel_count = (unsigned char)( 0x0F & ( stx104_ai_channel_last[board] - stx104_ai_channel_first[board] ) ); adc_burst_channel_count = adc_burst_channel_count << 4; outp( stx104_base_address[board] + STX104_PACER_CLOCK_CONTROL, adc_burst_channel_count ); } } }
|
Copyright © 1997-2008 by Apex Embedded Systems. All rights reserved. Updated on Wednesday, April 02, 2008.
|
|
What do you think about this topic? Send feedback!
|