Skip to content

Commit 97128af

Browse files
author
Markus Seidl
committed
Copied version 1.37m from mikrocontroller.net svn
0 parents  commit 97128af

File tree

731 files changed

+451403
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

731 files changed

+451403
-0
lines changed

ADC.c

+191
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
/* ************************************************************************
2+
*
3+
* ADC functions
4+
*
5+
* (c) 2012-2017 by Markus Reschke
6+
* based on code from Markus Frejek and Karl-Heinz Kübbeler
7+
*
8+
* ************************************************************************ */
9+
10+
11+
/*
12+
* local constants
13+
*/
14+
15+
/* source management */
16+
#define ADC_C
17+
18+
19+
/*
20+
* include header files
21+
*/
22+
23+
/* local includes */
24+
#include "config.h" /* global configuration */
25+
#include "common.h" /* common header file */
26+
#include "variables.h" /* global variables */
27+
#include "functions.h" /* external functions */
28+
29+
30+
/* ************************************************************************
31+
* ADC
32+
* ************************************************************************ */
33+
34+
35+
/*
36+
* read ADC and return voltage in mV
37+
* - use Vcc as reference by default
38+
* - switch to bandgap reference for low voltages (< 1.0V) to improve
39+
* ADC resolution
40+
* - with a 125kHz ADC clock a single conversion needs about 0.1ms
41+
* with 25 samples we end up with about 2.6ms
42+
*
43+
* requires:
44+
* - Probe: input channel of ADC MUX (lower 4 or 5 bits)
45+
* must not include setting of voltage reference
46+
*
47+
*/
48+
49+
uint16_t ReadU(uint8_t Probe)
50+
{
51+
uint16_t U; /* return value (mV) */
52+
uint8_t Counter; /* loop counter */
53+
uint8_t Bits; /* reference bits */
54+
uint32_t Value; /* ADC value */
55+
56+
Probe |= ADC_REF_VCC; /* use AVcc as default reference */
57+
/* and external buffer cap anyway */
58+
59+
sample:
60+
61+
ADMUX = Probe; /* set input channel and U reference */
62+
63+
/*
64+
* dummy conversion
65+
* - if voltage reference has changed run a dummy conversion
66+
* - recommended by datasheet
67+
*/
68+
69+
Bits = Probe & ADC_REF_MASK; /* get reference bits */
70+
if (Bits != Cfg.RefFlag) /* reference has changed */
71+
{
72+
wait100us(); /* time for voltage stabilization */
73+
74+
ADCSRA |= (1 << ADSC); /* start conversion */
75+
while (ADCSRA & (1 << ADSC)); /* wait until conversion is done */
76+
77+
Cfg.RefFlag = Bits; /* update bits */
78+
}
79+
80+
81+
/*
82+
* sample ADC readings
83+
*/
84+
85+
Value = 0UL; /* reset sampling variable */
86+
Counter = 0; /* reset counter */
87+
88+
while (Counter < Cfg.Samples) /* take samples */
89+
{
90+
ADCSRA |= (1 << ADSC); /* start conversion */
91+
while (ADCSRA & (1 << ADSC)); /* wait until conversion is done */
92+
93+
Value += ADCW; /* add ADC reading */
94+
95+
/* auto-switch voltage reference for low readings */
96+
if (Counter == 4) /* 5 samples */
97+
{
98+
if ((uint16_t)Value < 1024) /* < 1V (5V / 5 samples) */
99+
{
100+
if (Bits != ADC_REF_BANDGAP) /* bandgap ref not selected */
101+
{
102+
if (Cfg.AutoScale == 1) /* autoscaling enabled */
103+
{
104+
Probe &= ~ADC_REF_MASK; /* clear reference bits */
105+
Probe |= ADC_REF_BANDGAP; /* select bandgap reference */
106+
107+
goto sample; /* re-run sampling */
108+
}
109+
}
110+
}
111+
}
112+
113+
Counter++; /* one less to do */
114+
}
115+
116+
117+
/*
118+
* convert ADC reading to voltage
119+
* - single sample: U = ADC reading * U_ref / 1024
120+
*/
121+
122+
/* get voltage of reference used */
123+
if (Bits == ADC_REF_BANDGAP) /* bandgap reference */
124+
{
125+
U = Cfg.Bandgap; /* voltage of bandgap reference */
126+
}
127+
else /* - */
128+
{
129+
U = Cfg.Vcc; /* voltage of Vcc */
130+
}
131+
132+
/* convert to voltage; */
133+
Value *= U; /* ADC readings * U_ref */
134+
// Value += 511 * Cfg.Samples; /* automagic rounding */
135+
Value /= 1024; /* / 1024 for 10bit ADC */
136+
137+
/* de-sample to get average voltage */
138+
Value /= Cfg.Samples;
139+
U = (uint16_t)Value;
140+
141+
return U;
142+
}
143+
144+
145+
146+
/* ************************************************************************
147+
* convenience functions
148+
* ************************************************************************ */
149+
150+
151+
/*
152+
* wait 5ms and then read ADC
153+
* - same as ReadU()
154+
*/
155+
156+
uint16_t ReadU_5ms(uint8_t Probe)
157+
{
158+
wait5ms(); /* wait 5ms */
159+
160+
return (ReadU(Probe));
161+
}
162+
163+
164+
165+
/*
166+
* wait 20ms and then read ADC
167+
* - same as ReadU()
168+
*/
169+
170+
uint16_t ReadU_20ms(uint8_t Probe)
171+
{
172+
wait20ms(); /* wait 20ms */
173+
174+
return (ReadU(Probe));
175+
}
176+
177+
178+
179+
/* ************************************************************************
180+
* clean-up of local constants
181+
* ************************************************************************ */
182+
183+
184+
/* source management */
185+
#undef ADC_C
186+
187+
188+
189+
/* ************************************************************************
190+
* EOF
191+
* ************************************************************************ */

0 commit comments

Comments
 (0)