1 #include <lpc21xx.h> // LPC21XX Peripheral Registers
10 #define ADCCH0 22 ///< ADC0 value for PINSEL
11 #define ADCCH1 24 ///< ADC1 value for PINSEL
12 #define ADCCH2 26 ///< ADC2 value for PINSEL
13 #define ADCCH3 28 ///< ADC3 value for PINSEL
17 * Comparsion function for quicksort
19 * @param *a first number for comparion
20 * @param *b second number for comparion
22 * @return 1 if b is higher than a
24 int compare( const void *a, const void *b)
26 return (*((unsigned int*)a) < *(((unsigned int*)b)));
31 * Median filter for ADC. If new data is available the median is recalculated.
32 * This function may be called from main function, it should take long time
33 * to calculate the median for all ADC value.
35 * @param chan bit oriented (0~3) value, defines which ADC channels have new data
37 void adc_filter(unsigned char chan)
39 if(adc_update_adc & 1)
41 memcpy(&adc_filtr_0_m, adc_filtr_0, sizeof(uint16_t) * ADC_FILTR_SIZE );
42 qsort(adc_filtr_0_m , ADC_FILTR_SIZE , sizeof(uint16_t), compare);
43 adc_val[0] = adc_filtr_0_m[(ADC_FILTR_SIZE/2 + 1)];
44 adc_update_adc &= ~ 1;
47 if(adc_update_adc & 2)
49 memcpy(&adc_filtr_1_m, adc_filtr_1, sizeof(uint16_t) * ADC_FILTR_SIZE );
50 qsort(adc_filtr_1_m , ADC_FILTR_SIZE , sizeof(uint16_t), compare);
51 adc_val[1] = adc_filtr_1_m[(ADC_FILTR_SIZE/2 + 1)];
52 adc_update_adc &= ~ 2;
54 if(adc_update_adc & 4)
56 memcpy(&adc_filtr_2_m, adc_filtr_2, sizeof(uint16_t) * ADC_FILTR_SIZE );
57 qsort(adc_filtr_2_m , ADC_FILTR_SIZE , sizeof(uint16_t), compare);
58 adc_val[2] = adc_filtr_2_m[(ADC_FILTR_SIZE/2 + 1)];
59 adc_update_adc &= ~ 4;
61 if(adc_update_adc & 8)
63 memcpy(&adc_filtr_3_m, adc_filtr_3, sizeof(uint16_t) * ADC_FILTR_SIZE );
64 qsort(adc_filtr_3_m , ADC_FILTR_SIZE , sizeof(uint16_t), compare);
65 adc_val[3] = adc_filtr_3_m[(ADC_FILTR_SIZE/2 + 1)];
66 adc_update_adc &= ~ 8;
74 * ADC ISR routine. This routine reads selected ADC value and
75 * multiplies it by #ADC_MUL and adds #ADC_OFFSET to calculate the
76 * volage (3.25mV/div). After this reading the next ADC channel is
77 * set up for measuring.
79 void adc_isr_filtr(void) __attribute__ ((interrupt));
80 void adc_isr_filtr(void)
82 unsigned char chan =0;
86 chan = (char) ((ADDR>>24) & 0x07);
87 val = (((((ADDR >> 6) & 0x3FF) * ADC_MUL + ADC_OFFSET) + adc_val[chan]) >> 1) ;
92 adc_filtr_0[adc_filtr_p] = val;
97 adc_filtr_1[adc_filtr_p] = val;
102 adc_filtr_2[adc_filtr_p] = val;
107 adc_filtr_3[adc_filtr_p] = val;
110 if(adc_filtr_p == (ADC_FILTR_SIZE -1 )) adc_filtr_p = 0;
115 ADCR &= ~(ADC_CR_START_OFF_m);
121 ADCR = ((ADC_CR_ADC1_m) | (ADC_CR_CLKS_11_m) | (ADC_CR_PDN_ON_m) | (ADC_CR_START_NOW_m) | (ADC_VPB_DIV*ADC_CR_CLK_DIV_1_m));
125 ADCR = ((ADC_CR_ADC2_m) | (ADC_CR_CLKS_11_m) | (ADC_CR_PDN_ON_m) | (ADC_CR_START_NOW_m) | (ADC_VPB_DIV*ADC_CR_CLK_DIV_1_m));
129 ADCR = ((ADC_CR_ADC3_m) | (ADC_CR_CLKS_11_m) | (ADC_CR_PDN_ON_m) | (ADC_CR_START_NOW_m) | (ADC_VPB_DIV*ADC_CR_CLK_DIV_1_m));
133 ADCR = ((ADC_CR_ADC0_m) | (ADC_CR_CLKS_11_m) | (ADC_CR_PDN_ON_m) | (ADC_CR_START_NOW_m) | (ADC_VPB_DIV*ADC_CR_CLK_DIV_1_m));
142 * Inicializes ADC service for all ADC (4) channels and installs ISR routine to VIC.
143 * Automaticly starts the conversion of first channel on given conversion frequency.
145 void init_adc_filter(unsigned rx_isr_vect)
148 PINSEL1 |= ((PINSEL_1 << ADCCH0) | (PINSEL_1 << ADCCH1) | (PINSEL_1 << ADCCH2) | (PINSEL_1 << ADCCH3));
152 for (x = 0; x < 21; ++x)
163 ((uint32_t*)&VICVectCntl0)[rx_isr_vect] = 0x32;
164 ((uint32_t*)&VICVectAddr0)[rx_isr_vect] = (unsigned) adc_isr_filtr;
165 VICIntEnable = 0x40000;
167 ADCR = ((ADC_CR_ADC0_m) | (ADC_CR_CLKS_11_m) | (ADC_CR_PDN_ON_m) | (ADC_CR_START_NOW_m) | (ADC_VPB_DIV*ADC_CR_CLK_DIV_1_m));