⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 par4ch.c

📁 基于PC104的24位数据采集器的完整源码
💻 C
📖 第 1 页 / 共 4 页
字号:

        _sleep( ms );

        return( 0 );
}
#elif defined( SROS_MSDOS )
SRLOCAL int OsSleep( int ms, int hardwait ) {

        struct _timeb timebuffer;
        unsigned short endms;
        time_t endsec;

        // Sleep for specifed number of milliseconds.
        // Returns 0 for success, -1 for error.
        
        if ( ms <= 0 )
                return( 0 );

        // No sleep function is available for MSDOS, so just
        // return.  Unless the user has requested that they
        // really want to wait, even if it means spinning in
        // a loop wasting CPU cycles.
        
        if ( hardwait ) {
                
                _ftime( &timebuffer );
                endsec = timebuffer.time;
                endms  = timebuffer.millitm + ms;
                
                while (endms > 1000) {
                        endms  -= 1000;
                        endsec += 1;
                        }
                
                while (timebuffer.time < endsec)
                        _ftime( &timebuffer );
                
                while ( (timebuffer.time == endsec) &&
                        (timebuffer.millitm < endms) )
                        _ftime( &timebuffer );
                }

                
//                ms *= 1000; // Convert ms to us
//                while ( ms-- )
//                        _asm {  mov  dx,0x379  // Read from status port
//                                in   al,dx     // takes about 1 microsecond
//                                }

        return( 0 );
}
#endif // SROS_WIN95 or SROS_MSDOS for sleep function difference


#define OsCommit _commit




#elif defined( SROS_LINUX )

SRLOCAL DEVHANDLE OsDriverOpen( char *PortName ) {
        
        DEVHANDLE Par4chHandle;
        char      DeviceNameBuffer[256];

        sprintf( DeviceNameBuffer, "/dev/%s", PortName );
        
        Par4chHandle = open( DeviceNameBuffer, O_RDWR );
        
        if (Par4chHandle < 0)
                Par4chHandle = BAD_DEVHANDLE;
        
        return( Par4chHandle );
}

SRLOCAL int OsDriverClose( DEVHANDLE Par4chHandle ) {
        if ( close( Par4chHandle ) < 0 )
                return( 0 );
        else
                return( 1 );
}

SRLOCAL int OsDriverRead(
                          DEVHANDLE      Par4chHandle,
                          void          *pValues,
                          unsigned long  BytesToRead,
                          unsigned long *pBytesRead
                         ) {
        long readreturn;

        readreturn = read( Par4chHandle, pValues, BytesToRead );
        
        if (readreturn < 0) {
                *pBytesRead = 0;
                return( 0 );
                }
        else {
                *pBytesRead = readreturn;
                return( 1 );
                }
}

SRLOCAL int OsDriverIoctl(
                           DEVHANDLE      Par4chHandle,
                           unsigned long  IoCtlCode,
                           void          *pValueIn,
                           unsigned long  InSize,
                           void          *pValueOut,
                           unsigned long  OutSize,
                           unsigned long *pBytesReturned
                          ) {
        int code, i;
        char *pVI, *pVO;

        // The ioctl function just takes one buffer.  On the way in,
        // it contains the input data and on the way out, it contains
        // the output data.  So, make sure we are using the largest of
        // the two and that it contains the input data.  The size of the
        // data must be the size defined for that IO control code in
        // par4chkd.h.

        if (InSize >= OutSize)
                code = ioctl(Par4chHandle, IoCtlCode,(unsigned long)pValueIn);
        else {
                pVI = (char*)pValueIn;
                pVO = (char*)pValueOut;
                for ( i = 0 ; i < InSize ; i++ )
                        *pVO++ = *pVI++;
                
                code = ioctl(Par4chHandle, IoCtlCode,(unsigned long)pValueOut);
                }

        *pBytesReturned = OutSize;
        
        if (code < 0)
                return( 0 );
        else
                return( 1 );
        
}

SRLOCAL long OsGetLastError( void ) {

        return( (long)(-errno) );
}

SRLOCAL int OsSetNonBlock( int value ) {

        // Set non-blocking mode for keyboard reads
        //   value = 0 blocks reads until a character is ready
        //   value = 1 allow reads to return immediately
        //   returns -1 for failure, 0 for success

        int oldflags, result;

        oldflags = fcntl( STDIN_FILENO, F_GETFL, 0 );

        if (oldflags == -1)
                return( -1 );

        if (value != 0)
                oldflags |= O_NONBLOCK;
        else
                oldflags &= ~O_NONBLOCK;

       result = fcntl( STDIN_FILENO, F_SETFL, oldflags );

       return( result );
}

SRLOCAL int OsGetKey( int wait ) {

        int c;

        // Get a ready keypress or wait until one is ready if requested.

        // Notes:
        //
        // This version assumes that non-blocking reads have been
        // enabled.  Otherwise, the first getchar will always wait until
        // a character is ready.
        //
        // Getchar requires an ENTER after the character before it will
        // start processing the character.


        c = getchar();
        while ( (c == EOF) && wait )
                c = getchar();

        return( c );
}

SRLOCAL void OsFlushPrint( void ) {
        
        fflush( STDIN_FILENO );
}

SRLOCAL int OsSleep( int ms, int hardwait ) {

        // Sleep for specifed number of milliseconds.
        // Returns 0 for success, -1 for error.

        struct timespec twait, tleft;
        
        if ( ms <= 0 )
                return( 0 );

        
        // Linux nanosleep takes structure with seconds and nanoseconds.
        
        tleft.tv_sec  = tleft.tv_nsec = 0;
        twait.tv_sec  = (long)(ms / 1000);
        twait.tv_nsec = (ms - (twait.tv_sec*1000)) * 1000000;
        
        return( nanosleep( &twait, &tleft ) );
}

#define OsCommit fsync

#endif // SROS_xxxxx   End of OS dependent helper functions










/* HELPER FUNCTION GROUPS:
 *
 *    Device driver I/O
 *    Sample rate
 *
 *
 *
 */




/* DEVICE DRIVER IO HELPER FUNCTION:

This function calls an I/O Control function to communicate
information between the library and the PAR4CH device driver.

After the device driver has been opened with Par4chOpen, it is ready
to provide its services.  Common services such as reading and writing
data are requested with the OsDriverRead and OsDriverWrite functions.
More specialized services are requested using the I/O Control
function.

The first argument to the I/O Control function is the device driver
handle returned by the open function.  The second argument is an IO
control code that indicates which specialized service is being
requested.  The available control codes are listed in par4chkd.h.  The
remaining arguments allow small amounts of data to be exchanged
between the library and the device driver.

The global variable Par4chLastDriverError keeps track of the last OS
provided error.  Most users will never need to access this.  If you
do, declare it as extern in your source code.

*/

long Par4chLastDriverError = 0L;


SRLOCAL int DevIoReadWrite( 
                            DEVHANDLE     Par4chHandle,
                            unsigned long IoCtlCode, 
                            void         *pValueIn,  
                            unsigned long InSize,
                            void         *pValueOut, 
                            unsigned long OutSize  
                          ) {

        int           Result;
        unsigned long BytesReturned;


        // Verify that device driver is valid (open).

        if (Par4chHandle == BAD_DEVHANDLE) {
                Par4chLastDriverError = ERROR_SERVICE_DISABLED;
                return( 0 );
                }

        
        // Request specialized services from device driver.

        Result = OsDriverIoctl(
                       Par4chHandle,     // Handle to device
                       IoCtlCode,        // IO Control code
                       pValueIn,         // Input data to driver
                       InSize,           // Length of in buffer in bytes
                       pValueOut,        // Output data from driver
                       OutSize,          // Length of out buffer in bytes
                       &BytesReturned    // Bytes placed in output buffer
                       );

        
        // Failure output.

        if (!Result) {
                Par4chLastDriverError = OsGetLastError();
                return( 0 );
                }
        
        Par4chLastDriverError = 0L;
        return( 1 );
}







/* PAR4CH SAMPLE RATE HELPER FUNCTIONS:

These are generally used to convert from user parameters like the
sampling rate to parameters required by the A/D in the init function.

Given a desired sampling rate in Hz and the GainLog value, this
helper function computes the best TurboLog rate, Decimation ratio and
ExtraDecimation value using the following formulas:

     TurboLog   = MaxGainLog - GainLog
     Decimation = ((PAR4CH_XTAL * TurboLog)/(PAR4CH_FCONST * Sps)) - 1
     ExtraDecimation = 0 if sps > 50, ...

Most Sps values can be achieved by several different TurboLog and
Decimation combinations.  Selecting a combination with the largest
possible TurboLog value gives the best resolution.

If the desired sampling rate can not be achieved with the largest
TurboLog value, that value is reduced until either the desired Sps or
the minimum TurboLog is reached.

Note that the ranges of the TurboLog rate and Decimation ratio are
limited by the ADS1210 architecture.  Only the following values are
acceptable:

       TurboLog = 0 to 4 --> rates of 1,2,4,8,16
             where TurboLog + GainLog <= 4

              19 <= Decimation <= 8000

This results in native sampling rate extremes of:

   Slowest SPS = (10MHz * 1)/(512  * 8001) =      2.441 Hz
   Fastest SPS = (10MHz * 16)/(512 * 20)   =  15625.000 Hz

To allow for slower sampling rates, additional averaging is done by
the device driver.  The number of samples included in this additional
averaging are controlled by the ExtraDecimation parameter.

Also note that because the TurboLog rate and Decimation ratio are
integers, the actual Sps rate resulting from the values computed by
this function will not give exactly the requested Sps.  Use the
function Par4chTdeToSpsGain or the formula:

     Sps = (PAR4CH_XTAL * TurboLog)/(512.0 * (Decimation+1))

to get the exact sampling rate corresponding to a particular Td pair
of values.


See the Burr Brown ADS1210 spec sheet for more information on the
operation of the sigma delta modulator.

*/

#define PAR4CH_XTAL     (10.0E+6)    // 10MHz
#define PAR4CH_FCONST   512.0L

FUNCTYPE( int ) Par4chSpsGainToTde(
                                    double Sps,
                                    int GainLog,
                                    int *TurboLog,
                                    int *Decimation,
                                    int *ExtraDecimation
                                    ) {

        double TurboXtalOverConst, NominalSps, TempSps;
        int    TurboValue;
        
        
        // Error check inputs.
        
        if ( (Sps > PAR4CH_SPS_MAX) || (Sps < PAR4CH_SPS_MIN) ) {
                *TurboLog        = -1;
                *Decimation      = -1;
                *ExtraDecimation = -1;
                return( PAR4CH_ERROR_DECIMATION );
                }

        if ( (GainLog > PAR4CH_GAIN_MAX) || (GainLog < PAR4CH_GAIN_MIN) ) {
                *TurboLog        = -1;
                *Decimation      = -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -