We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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
Sorry, I sent my mail too fast with wrong code. The right one comes here: I am trying to calculate the 100 AD-conversion values. I have written the following code to initialize the PEC. interrupt (ADCINT) void AverageADC(void); unsigned int AD_buffer[10]; void ADCinit(void) { ADCIC = 0x0079; // (ILVL) = 14, (GLVL) = 1 ADCON = 0x0090; // load ADC control register PECC1 = 0x0264; // count 100, transfer a word, inc dst pointer SRCP1 = (unsigned int)&ADDAT; DSTP1 = (unsigned int)&AD_buffer; } interrupt (ADCINT) void AverageADC(void) { dprintf("Average %i", AD_buffer/100); } Does anybody see anything missing in this code? Of course "main" and some display code is missing delibrately. Any comment will be appreciated. regards /M
HI Mohammad Your array needs place for 100 entries if you want to do 100 PEC transfers. unsigned int AD_buffer[100]; I always use the following syntax to init the PEC Destination pointer DSTP0 = _sof_ (AD_buffer); I don't know if your syntax runs correctly. During the interrupt function you have to reinitialize all the PEC registers if you want to have a continous conversion mode. regards Uwe
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_(); }