#include #include #include #include #include "pt100.h" uint16_t adc_buffer[AVRG]; volatile float ch_values[10]; void adc_init(void){ ADCA.CTRLB = ADC_FREERUN_bm; ADCA.REFCTRL = ADC_REFSEL_VCC_gc; ADCA.PRESCALER = ADC_PRESCALER_DIV512_gc; uint8_t CalibrationByteL; uint8_t CalibrationByteH; NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc; CalibrationByteL = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0)); CalibrationByteH = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1)); NVM_CMD = NVM_CMD_NO_OPERATION_gc; ADCA.CALL = CalibrationByteL; ADCA.CALH = CalibrationByteH; ADCA.CTRLA = ADC_ENABLE_bm; ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc; } void dma_init(void){ DMA.CTRL = DMA_ENABLE_bm; DMA.CH0.CTRLB = DMA_CH_TRNINTLVL_LO_gc; DMA.CH0.TRFCNT = AVRG * 2; DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm; DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; //repeat endless DMA.CH0.CTRLA |= DMA_CH_REPEAT_bm; DMA.CH0.REPCNT = 0; DMA.CH0.SRCADDR0 = ((uintptr_t)&ADCA.CH0.RES) & 0xFF; DMA.CH0.SRCADDR1 = (((uintptr_t)&ADCA.CH0.RES) >> 0x08) & 0xFF; DMA.CH0.SRCADDR2 = (((uintptr_t)&ADCA.CH0.RES) >> 0x0F) & 0xFF; DMA.CH0.DESTADDR0 = ((uintptr_t)adc_buffer) & 0xFF; DMA.CH0.DESTADDR1 = ((uintptr_t)adc_buffer >> 0x08) & 0xFF; DMA.CH0.DESTADDR2 = ((uintptr_t)adc_buffer >> 0x0F) & 0xFF; DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_DESTRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc; DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; } float avrg(uint16_t * values, uint16_t length){ uint64_t res = 0; //ommit first and last sample for(uint16_t i=1; i < length-1; i++){ res += values[i]; } return (float)(res)/(length-2); } ISR(DMA_CH0_vect){ static uint8_t pin = 0; DMA.INTFLAGS |= DMA_CH0TRNIF_bm; // clear flag DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_OFF_gc; ADCA.CTRLB = 0; // stop ADC uint8_t old_pin = pin; pin=(pin+1)%10; ADCA.CH0.MUXCTRL = pin << ADC_CH_MUXPOS_gp; // give MUX time to switch during calculation float temp = avrg(adc_buffer, AVRG); temp = temp - ADC_0V_COUNT; temp = (temp)/ (4096-ADC_0V_COUNT) * ADC_MAX_VOLT; if(old_pin <= 8){ /* pt100 temperature channels */ temp = (temp * REF_OHMS)/(SUPPLY_VOLTS - temp); temp = (temp-100)/0.3927; //pt100 formula ch_values[old_pin] = temp; } if(old_pin == 9){ /* 24V supply voltage measurement */ // resistor devider 33k and 1k ch_values[old_pin] = temp * 34; } DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; ADCA.CTRLB = ADC_FREERUN_bm; // start ADC again }