Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
06/25/02 00:54
Read: times


 
#24819 - RE: A/D port scan through polling in 87C552
Here's my old set a/d channel function:

bit set_ad_channel(const enum AD_CHANNELS channel)
{
    data bit success;
    data U8  buff_ad_status;

    // Assume failure, prove otherwise.
    success = FALSE;

    // Get a snapshot of the s_ad_status for multiple comparisons.
    buff_ad_status = s_ad_status;

    // Channel may be set only if A/D is not busy and not locking a value.
    if (!(buff_ad_status & (BUSY | VALUE_LOCKED))) {
        // Make sure caller didn't ask for an invalid channel.
        if (chan_num < NUM_AD_CHANNELS) {
            // Valid channel. Select the channel. Clear out old channel before
            // setting the new channel.
            s_ad_command &= ~CHANNEL_MASK;
            s_ad_command |= chan_num;
            success       = TRUE;
        }
    }

    return(success);
}

Note how I checked both busy and locked bits in the ADSTAT register? Are you doing something similar? I never used a time delay for reading either, just set an interrupt and let the ISR store the value, or, poll the ADSTAT via:
enum AD_STATES check_ad_status(void)
{
    data U8 buff_ad_status;
    data enum AD_STATES status;

    // Get copy so status doesn't change on us in mid-compare.
    buff_ad_status = s_ad_status;

    // Develop the true state of the A/D based on BUSY and VALUE_LOCKED which
    // are mutually exclusive.
    if (buff_ad_status & BUSY) {
        // Still converting.
        status = AD_BUSY;
    }
    else if (buff_ad_status & VALUE_LOCKED) {
        // Value should be read from the current channel.
        status = AD_VALUE;
    }
    else {
        // Okay to start another conversion in this case.
        status = AD_READY;
    }

    return(status);
}

and read via:
bit read_ad_result(U16 *ad_result_ptr)
{
    static data bit flag = FALSE;
    data bit success;

    // If the value is locked we don't need to worry about s_ad_status changing
    // during the course of executions (no need to buffer it).
    if (s_ad_status & VALUE_LOCKED) {
        // Create the 10-bit result from the two 8-bit sfr's.
        *ad_result_ptr  = (U16) s_ad_msb    << 2;
        *ad_result_ptr |= (U16) s_ad_status >> 6;
        s_ad_status    &= ~VALUE_LOCKED;
        success         = TRUE;
    }
    else {
        // Flag the error.
        *ad_result_ptr = 0x0000;
        success        = TRUE;
    }

    return(success);
}
Oh yeah, here's how I started an A/D conversion:
bit start_ad_conversion(enum AD_CHANNELS channel)
{
    data bit success;

    // Start a conversion if the A/D is not busy and a value is not locked.
    if (s_ad_status & BUSY) {
        // Caller should check for this failure.
        success = FALSE;
    }
    else {
        // Start a new conversion on the given channel.
        s_ad_status  &= ~VALUE_LOCKED;
        s_ad_command &= ~CHANNEL_MASK;
        s_ad_command |= (U8) channel;
        s_ad_command |= START;
        success       = TRUE;
    }

    return(success);
}
Regards,

- Mark

List of 4 messages in thread
TopicAuthorDate
A/D port scan through polling in 87C552            01/01/70 00:00      
RE: A/D port scan through polling in 87C552            01/01/70 00:00      
RE: A/D port scan through polling in 87C552            01/01/70 00:00      
RE: A/D port scan through polling in 87C552            01/01/70 00:00      

Back to Subject List