You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			92 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
| #include <avr/io.h>
 | |
| #include <avr/pgmspace.h>
 | |
| #include <avr/interrupt.h>
 | |
| #include <stdlib.h>
 | |
| #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
 | |
| }
 |