Der ATmega328p verfügt über einen 10-Bit-ADC, der nach dem Verfahren der sukzessiver Approximation arbeitet. Der ADC ist mit einem 8-Kanal-Analog-Multiplexer ausgestattet, der die Erfassung von acht massebezogenen Spannungen ermöglicht.
Eine interne Band-Gap Refernz von nominal 1,1 V (VBG) oder AVCC stehen als Referenzspannung zur Verfügung gestellt.
Das Programm readadc.ff startet eine AD-Umsetzung und fragt das Ergebnis der Umsetzung ab. Im linken Bild ist die nach erfolgter Compilation gestartete periodische AD-Umsetzung zu sehen. Der erste Wert der AD-Umsetzung ist ungültig, weshalb beim Wort adc@ auch zwei AD-Umsetzungen nacheinander gestartet werden und nur die zweite das Ergebnis zur Verfügung stellt. Details hierzu sind dem Datenblatt des ATmega328p zu entnehmen.
Im rechten Bild ist der Aufruf der Worte adc-test1 und adc-test2 gezeigt. Das Wort adc-test1 ruft für die internen Quellen GND, VBG und TEMP(eratur Sensor) jeweils eine AD-Umsetzuung auf. Beim Wort adc-test2 kann eine bekannte Spannung (hier bieten sich GND, 3,3 V oder 5 V an) über den Eingang A0 erfasst und angezeigt werden.
\ ********************************************************************* \ Filename: readadc.ff * \ Date: 29.12.2014 * \ FF Version: 5.0 * \ Copyright: Claus Kuhnel * \ Author: Claus Kuhnel * \ ********************************************************************* \ FlashForth is licensed acording to the GNU General Public License* \ ********************************************************************* \ Read the ADC of Arduino Uno (ATmega328p) -readadc marker -readadc \ Registers of interest on the ATmega328p $7c constant ADMUX $7a constant ADCSRA $7b constant ADCSRB $79 constant ADCH $78 constant ADCL %1110 constant VBG %1000 constant TEMP %1111 constant GND %01000000 constant REF \ AVCC as reference %01000000 constant ADSC \ Start ADC #5 constant col : init ( -- ) di %10000111 ADCSRA c! \ ADC enable, Prescaler 128 ei ; : adc@ ( channel -- u ) REF or ADMUX c! ADSC ADCSRA c@ or ADCSRA c! begin ADSC ADCSRA mtst 0= until ADSC ADCSRA c@ or ADCSRA c! begin ADSC ADCSRA mtst 0= until ADCL c@ ADCH c@ #8 lshift + ; : main ( channel -- ) init begin dup cr adc@ col u.r #500 ms key? until drop ; : .result ( u -- ) dup col u.r 5000 1024 */ ." -> " . ." mV" cr ; \ ADC test with internal sources : adc-test1 ( -- ) cr ." ADC Test for Ardunio Uno (ATmega328p) with internal sources" cr ." GND: " GND adc@ .result ." VBG: " VBG adc@ .result ." TEMP: " TEMP adc@ .result ; \ ADC test with external sources (uses ADC0) : adc-test2 ( -- ) cr ." ADC Test for Ardunio Uno (ATmega328p) with external sources" cr ." Connect ADC0 (A0) to a known voltage." cr ." Measure this voltage and enter its value in mV." cr ." Enter voltage : " tib 5 accept tib swap drop drop cr \ type cr ." Measured value: " 0 adc@ .result ; \ Test reading ADC periodically until any key is pressed. decimal VBG main