Sign in Join
Wiki copytemporary

AVR Embedded Tutorial - Analog Read: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: AVR Embedded Tutorial - Analog Read

OldNewLine
1+# Analog Read
2+
3+This code is for an Atmega328/Arduino runnning at 16MHz. How to control the UART can be found here:
4+
5+`   `[[AVR Embedded Tutorial - UART|UART UARTInit and UARTSendString (...]]
6+
7+The ATmega328 can measure with 10-bit accuracy, so a value between 0..1023 is output.
8+
9+## Polling method
10+
11+### Initialize ADC
12+
13+Configure analog reading. AVcc is used as the reference voltage, this is the easiest way. This must be configured with **ADMUX**.
14+
15+The following reference voltages can be configured with ADMUX:
16+
17+| Bit 7 | Bit 6 | Description |
18+|-------|-------|-------------|
19+| 0 | 0 | Pin AREF |
20+| 0 | 1 | Use AVcc |
21+| 1 | 0 | \- |
22+| 1 | 1 | 2.56V |
23+
24+The converter is started with **ADCSRA**.
25+
26+``` pascal
27+procedure ADC_Init;
28+ begin
29+ ADMUX := (1 shl REFS); // Use AVcc for reference
30+ ADCSRA := (1 shl ADEN) or %111; // Switch on converter, divider 128
31+ end;
32+```
33+
34+### Measuring
35+
36+The procedure for measuring is as follows.
37+
38+- Specify the port.
39+- Wait until the measurement is complete.
40+- Read out the measured value.
41+
42+With ADMUX you have to enter the reference voltage again because it shares the register with the reference. You could also do an OR operation with ADMUX .
43+
44+``` pascal
45+function ADC_Read(Port : byte) : integer;
46+ begin
47+ ADMUX := (1 shl REFS) or (Port and $0F); // Specify port
48+ ADCSRA := ADCSRA or ( 1 shl ADSC ); // Start measuring
49+
50+ while (ADCSRA and (1 shl ADSC)) <> 0 do // Wait until measured
51+ begin
52+ end;
53+
54+ Result := ADC; // Read out the measured value
55+ end;
56+```
57+
58+If you always read in from the same port, you only have to call up the ADMUX line once. You can also start measuring directly after the while loop which saves a few clock cycles.
59+
60+### Output via UART
61+
62+Buffer variables for the measurement data.
63+
64+``` pascal
65+var
66+ Data : integer;
67+ s : string[10];
68+```
69+
70+The measurement data is then output in an endless loop.
71+
72+``` pascal
73+ begin
74+ // Initialize UART
75+ UARTInit;
76+
77+ // Initialize ADC
78+ ADC_Init;
79+
80+ // Allow interrupt
81+ asm Sei end;
82+
83+ // output measured values.
84+ repeat
85+ Data := ADC_Read(0);
86+ str(Data : 6, s);
87+ UARTSendString(s);
88+ until 1 = 2;
89+ end.
90+```
91+
92+## Interrupt method
93+
94+The advantage of the interrupt-controlled method is that you do not have to wait until the measurement is finished, so you have time for other things.
95+
96+### Initialisation
97+
98+The difference:
99+
100+- With ADMUX you enter the input port at the beginning.
101+- At ADCSRA you have to start the first measurement with ADSC.
102+- With ADIE you communicate that the conversion interrupt is controlled.
103+
104+``` pascal
105+procedure ADC_Init;
106+ const
107+ Port = 0;
108+
109+ begin
110+ ADMUX := (1 shl REFS) or (Port and $0F);
111+ ADCSRA := %111 or (1 shl ADEN) or (1 shl ADSC) or (1 shl ADIE);
112+ end;
113+```
114+
115+### Output measured value in the interrupt
116+
117+``` pascal
118+procedure ADC_Ready public name 'ADC_ISR'; interrupt;
119+ var
120+ Data : integer;
121+ s : string[10];
122+
123+ begin
124+ Data := ADC;
125+ ADCSRA := ADCSRA or (1 shl ADSC);
126+ str(Data : 6, s);
127+ UARTSendString(s);
128+ end;
129+```
130+
131+> **Tip:** Interrupt routines should be kept short. This does not mean that you cannot do any processing in an interrupt routine, but you do need to ensure that when the next interrupt occurs, the last one is not still running.
132+
133+### Main program
134+
135+Since the measurement is interrupt-controlled, the main loop remains empty. It is important to switch on the interrupts.
136+
137+``` pascal
138+begin
139+ // Initialize UART
140+ UARTInit;
141+
142+ // ADC
143+ ADC_Init;
144+
145+ // Allow interrupt
146+ asm Sei end;
147+
148+ // main loop
149+ repeat
150+ // Do something
151+ until 1 = 2;
152+end.
153+```
154+
155+# See also
156+
157+- [[AVR Embedded Tutorial|AVR Embedded Tutorials]] - Overview
158+
159+---
160+*From the Free Pascal wiki, page "AVR Embedded Tutorial - Analog Read", as it stood on 2020-01-24 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
161+Category: AVR
162+Category: Arduino
163+Category: Embedded
164+Category: Tutorials

Back to history