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
Hi all again, As I told in my previous mail. I am trying to calculate the average value for 100 AD-conversion values (in volts) using PEC. I have written a small code as below:
int value; int counter = 0; float x, y,z, m; void main(void) { ADCIC = 0x0079; // (ILVL) = 14, (GLVL) = 1 ADCON = 0x0090; // load ADC control register PECC1 = 0x00FF; // count continours IEN = 1; while(1) { if(counter<=100) { ADST=1; //Start AD conversion SRCP1=(int)(&ADDAT); //Get data from ADDAT DSTP1=(int)(&value); //Move data till variabeln value ADST=0; //Stop AD conversion x=value; //change type of value to float y=x/1023*5; //Calculate voltage. Vref =5,0V. z=z+y; //Accumulate result in variable z m=z/antal; //Save average in variable m counter++; } } }
Dear Mohammad, this sounds like a totally new approach. Your code looks like you are polling the ADC Result register. Therefore you do not need the PEC transfer mechanism. But between starting and reading the ADC you must wait the ADC conversion time. Check the busy flag of the ADC (ADBSY). If ready then read ADDAT and accumulate the values as described. BTW your code accumulate 101 ADC values. regards Uwe
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_(); }