-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathadc.c
More file actions
77 lines (68 loc) · 2.43 KB
/
Copy pathadc.c
File metadata and controls
77 lines (68 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
* Lab Power
*st7565.h
* ADC
*
* read analog channels
* - PA1 - Voltmeter
* - PA4 - Vin - Input Voltage
* - PA4 - Iucurr - Current on microcurrent device
* - PA4 - Iout - Output current (main shunt)
* - PA4 - Vout - Output voltage
*/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <stddef.h>
#include "adc.h"
#include "util.h"
void adc_init () {
// Calibrate ADC
ADCA.CALL = util_read_calib_byte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0) );
ADCA.CALH = util_read_calib_byte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1) );
// PORTA is all inputs
PORTA.DIR = 0;
PORTA.PIN0CTRL = PORT_ISC_INPUT_DISABLE_gc;
// PORTA.PIN1CTRL = PORT_ISC0_bm | PORT_ISC1_bm | PORT_ISC2_bm;
// PORTA.PIN2CTRL = PORT_ISC0_bm | PORT_ISC1_bm | PORT_ISC2_bm;
PORTA.PIN3CTRL = PORT_ISC_INPUT_DISABLE_gc;
PORTA.PIN4CTRL = PORT_ISC_INPUT_DISABLE_gc;
PORTA.PIN5CTRL = PORT_ISC_INPUT_DISABLE_gc;
PORTA.PIN6CTRL = PORT_ISC_INPUT_DISABLE_gc;
PORTA.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc;
// Enable the ADC
// ADCA_REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm | ADC_TEMPREF_bm;
// ADCA_REFCTRL = ADC_REFSEL_VCC_gc;
// ADCA_REFCTRL = DAC_REFSEL_AREFA_gc;
ADCA_REFCTRL = ADC_REFSEL_INT1V_gc;
ADCA_CTRLB = ADC_RESOLUTION_12BIT_gc;
// ADCA_PRESCALER = ADC_PRESCALER0_bm | ADC_PRESCALER1_bm; // 32Mhz /32 = 1Mhz
ADCA_PRESCALER = ADC_PRESCALER_DIV32_gc; // 32Mhz/256 = 125k
ADCA_CTRLA = ADC_ENABLE_bm;
}
int adc_read (uint8_t channel) {
int sum;
uint8_t j;
if (channel>=10) {
ADCA.CH0.CTRL = ADC_CH_INPUTMODE_INTERNAL_gc; // internal source
ADCA.CH0.MUXCTRL = ((channel-10)<<3); // Temp - Bandgap - Vcc - DAC
// ADCA.CH0.MUXCTRL = ADC_CH_MUXINT_SCALEDVCC_gc; // Vcc/10
// ADCA.CH0.MUXCTRL = ADC_CH_MUXINT_BANDGAP_gc;
// ADCA.CH0.MUXCTRL = ADC_CH_MUXINT_TEMP_gc;
} else {
ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; // single ended
ADCA.CH0.MUXCTRL = (channel<<3); // Gnd
}
// ADCA.CH0.MUXCTRL = c; // PORTA:2
// ADCA.CH0.MUXCTRL = 1; // Vin
// ADCA.CH0.CTRL |= ADC_CH_START_bm; // start conversion on channel 0
// Take multiple readings and average them out
sum=0;
for (j=0; j<ADCA_AVGCOUNT; j++) {
ADCA.CTRLA |= ADC_CH0START_bm;
while(!ADCA.CH0.INTFLAGS);
ADCA.CH0.INTFLAGS=ADC_CH_CHIF_bm;
sum += ADCA.CH0RES;
}
return (sum/ADCA_AVGCOUNT) - ADCA_OFFSET;
}