This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Question about PEC

Hi again,

I am using C167. I am using PEC for AD-conversion.
I configure PEC as follows:
ADCIC = 0x007B;
PECC3 = 0x00FF;
SRCP3 = (int) (&ADDAT);
DSTP3 = (int) (&P3);
ADCON = 0x0090;
I works fine to transfer values to from ADDAT to port P3. . Now I want to determine how many times AD-conversion has taken place.

In PECCx there are 8-LSB are:
COUNT (PEC Transfer Count)

Now I wonder if I am on right track or there are other way to do what I want.
Even if I use the 8-LSB of PECCx I can have the max value 2 raised to power 8 i.e. 256,
what happens if the nr of AD-conversion exceed 256?

Can someone help me in this regard?
Send me mail if something is not clear.
thanks in advance
regards
/M

Parents
  • This is code I used to implement an 8-channel, 4-samples per channel, round-robin, PEC based ADC system. It stores the results as an array of 32 integers, every 4th one is from the same channel.

    #pragma PECDEF( 3 )                 // Reserve PEC ptr space
    
    /*===========================================================================
                                     VARIABLES
    ===========================================================================*/
    #define ADC_CHANNELS          (8)
    #define ADC_SAMPLES_PER_CYCLE (4)
    #define ADC_BUFFER_CNT        (ADC_CHANNELS * ADC_SAMPLES_PER_CYCLE)
    
                                                    // Storage for one cycle of AD readings (PEC target)
    static UINT volatile sdata ui16_Adc_Buffer_Array[ ADC_BUFFER_CNT ];
    
    UINT volatile ui16_Adc_Count;                   // Flag counting fill cycles
    
    BIT Initialize_ADC( void ) {
    
       UINT i;
       _atomic_( 0 );
       ADCON = 0xB000;                                    // Stop A/D
       ADCIC = ADC_IRQ_LVL;
       _endatomic_();
       for ( i = 0; i < ADC_BUFFER_CNT; ++i )             // Clear buffer
          ui16_Adc_Buffer_Array[i] = 0;
       ui16_Adc_Count = 0;
       ADEIC = 0x0004;                                    // Disable error intr
       SRCP3 = _sof_( &ADDAT );                           // Init PEC control
       DSTP3 = _sof_( &ui16_Adc_Buffer_Array[0] );
       PECC3 = 0x0200 | ADC_BUFFER_CNT;                   //  Word/Incr/Cycle cnt loops
       _atomic_( 0 );
       ADCON = 0xB2B7;                                    // A/D control - start/seq/Ch 7/slow
       ADCIC = ADC_IRQ_LVL | 0x0040;
       _endatomic_();
       while ( ui16_Adc_Count == 0 );                     // Wait for one cycle (2 msec)
       return ( TRUE );
    }
    
    void ADC_ISR( void ) interrupt ADCINT using adc_Rbank {
    
       ADST = 0;                                          // A/D control - stop
       ++ui16_Adc_Count;
       DSTP3 = _sof_( &ui16_Adc_Buffer_Array[0] );
       PECC3 = 0x0200 | ADC_BUFFER_CNT;                   //  Word/Incr/Cycle cnt loops
       _atomic_( 0 );
       ADST = 1;                                          // A/D control - start
       ADCIC = ADC_IRQ_LVL | 0x0040;                      // Clear pending requests
       _endatomic_();
    }
    
    
    This system allows the foreground to ask for either the latest reading from a channel or the average of the last 4 readings for a channel. You can easily modify it to support only one channel with 100 readings. This was originally written to be run under RTX so the atomic stuff is to prevent preemption and higher priority ISRs.
    Best luck
    Scott

Reply
  • This is code I used to implement an 8-channel, 4-samples per channel, round-robin, PEC based ADC system. It stores the results as an array of 32 integers, every 4th one is from the same channel.

    #pragma PECDEF( 3 )                 // Reserve PEC ptr space
    
    /*===========================================================================
                                     VARIABLES
    ===========================================================================*/
    #define ADC_CHANNELS          (8)
    #define ADC_SAMPLES_PER_CYCLE (4)
    #define ADC_BUFFER_CNT        (ADC_CHANNELS * ADC_SAMPLES_PER_CYCLE)
    
                                                    // Storage for one cycle of AD readings (PEC target)
    static UINT volatile sdata ui16_Adc_Buffer_Array[ ADC_BUFFER_CNT ];
    
    UINT volatile ui16_Adc_Count;                   // Flag counting fill cycles
    
    BIT Initialize_ADC( void ) {
    
       UINT i;
       _atomic_( 0 );
       ADCON = 0xB000;                                    // Stop A/D
       ADCIC = ADC_IRQ_LVL;
       _endatomic_();
       for ( i = 0; i < ADC_BUFFER_CNT; ++i )             // Clear buffer
          ui16_Adc_Buffer_Array[i] = 0;
       ui16_Adc_Count = 0;
       ADEIC = 0x0004;                                    // Disable error intr
       SRCP3 = _sof_( &ADDAT );                           // Init PEC control
       DSTP3 = _sof_( &ui16_Adc_Buffer_Array[0] );
       PECC3 = 0x0200 | ADC_BUFFER_CNT;                   //  Word/Incr/Cycle cnt loops
       _atomic_( 0 );
       ADCON = 0xB2B7;                                    // A/D control - start/seq/Ch 7/slow
       ADCIC = ADC_IRQ_LVL | 0x0040;
       _endatomic_();
       while ( ui16_Adc_Count == 0 );                     // Wait for one cycle (2 msec)
       return ( TRUE );
    }
    
    void ADC_ISR( void ) interrupt ADCINT using adc_Rbank {
    
       ADST = 0;                                          // A/D control - stop
       ++ui16_Adc_Count;
       DSTP3 = _sof_( &ui16_Adc_Buffer_Array[0] );
       PECC3 = 0x0200 | ADC_BUFFER_CNT;                   //  Word/Incr/Cycle cnt loops
       _atomic_( 0 );
       ADST = 1;                                          // A/D control - start
       ADCIC = ADC_IRQ_LVL | 0x0040;                      // Clear pending requests
       _endatomic_();
    }
    
    
    This system allows the foreground to ask for either the latest reading from a channel or the average of the last 4 readings for a channel. You can easily modify it to support only one channel with 100 readings. This was originally written to be run under RTX so the atomic stuff is to prevent preemption and higher priority ISRs.
    Best luck
    Scott

Children
No data