mirror of
https://github.com/arduino/Arduino.git
synced 2024-11-30 11:24:12 +01:00
117 lines
3.5 KiB
C
Executable File
117 lines
3.5 KiB
C
Executable File
/*! \file a2d.c \brief Analog-to-Digital converter function library. */
|
|
//*****************************************************************************
|
|
//
|
|
// File Name : 'a2d.c'
|
|
// Title : Analog-to-digital converter functions
|
|
// Author : Pascal Stang - Copyright (C) 2002
|
|
// Created : 2002-04-08
|
|
// Revised : 2002-09-30
|
|
// Version : 1.1
|
|
// Target MCU : Atmel AVR series
|
|
// Editor Tabs : 4
|
|
//
|
|
// This code is distributed under the GNU Public License
|
|
// which can be found at http://www.gnu.org/licenses/gpl.txt
|
|
//
|
|
//*****************************************************************************
|
|
|
|
#include <avr/io.h>
|
|
#include <avr/signal.h>
|
|
#include <avr/interrupt.h>
|
|
|
|
#include "global.h"
|
|
#include "a2d.h"
|
|
|
|
// global variables
|
|
|
|
//! software flag used to indicate when
|
|
//! the a2d conversion is complete
|
|
volatile unsigned char a2dCompleteFlag;
|
|
|
|
// functions
|
|
|
|
//! initialize a2d converter
|
|
void a2dInit(void)
|
|
{
|
|
sbi(ADCSR, ADEN); // enable ADC (turn on ADC power)
|
|
cbi(ADCSR, ADFR); // default to single sample convert mode
|
|
a2dSetPrescaler(ADC_PRESCALE); // set default prescaler
|
|
a2dSetReference(ADC_REFERENCE); // set default reference
|
|
cbi(ADMUX, ADLAR); // set to right-adjusted result
|
|
|
|
sbi(ADCSR, ADIE); // enable ADC interrupts
|
|
|
|
a2dCompleteFlag = FALSE; // clear conversion complete flag
|
|
sei(); // turn on interrupts (if not already on)
|
|
}
|
|
|
|
//! turn off a2d converter
|
|
void a2dOff(void)
|
|
{
|
|
cbi(ADCSR, ADIE); // disable ADC interrupts
|
|
cbi(ADCSR, ADEN); // disable ADC (turn off ADC power)
|
|
}
|
|
|
|
//! configure A2D converter clock division (prescaling)
|
|
void a2dSetPrescaler(unsigned char prescale)
|
|
{
|
|
outb(ADCSR, ((inb(ADCSR) & ~ADC_PRESCALE_MASK) | prescale));
|
|
}
|
|
|
|
//! configure A2D converter voltage reference
|
|
void a2dSetReference(unsigned char ref)
|
|
{
|
|
outb(ADMUX, ((inb(ADMUX) & ~ADC_REFERENCE_MASK) | (ref<<6)));
|
|
}
|
|
|
|
//! sets the a2d input channel
|
|
void a2dSetChannel(unsigned char ch)
|
|
{
|
|
outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel
|
|
}
|
|
|
|
//! start a conversion on the current a2d input channel
|
|
void a2dStartConvert(void)
|
|
{
|
|
sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag
|
|
sbi(ADCSR, ADSC); // start conversion
|
|
}
|
|
|
|
//! return TRUE if conversion is complete
|
|
u08 a2dIsComplete(void)
|
|
{
|
|
return bit_is_set(ADCSR, ADSC);
|
|
}
|
|
|
|
//! Perform a 10-bit conversion
|
|
// starts conversion, waits until conversion is done, and returns result
|
|
unsigned short a2dConvert10bit(unsigned char ch)
|
|
{
|
|
a2dCompleteFlag = FALSE; // clear conversion complete flag
|
|
outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel
|
|
sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag
|
|
sbi(ADCSR, ADSC); // start conversion
|
|
//while(!a2dCompleteFlag); // wait until conversion complete
|
|
//while( bit_is_clear(ADCSR, ADIF) ); // wait until conversion complete
|
|
while( bit_is_set(ADCSR, ADSC) ); // wait until conversion complete
|
|
|
|
// CAUTION: MUST READ ADCL BEFORE ADCH!!!
|
|
return (inb(ADCL) | (inb(ADCH)<<8)); // read ADC (full 10 bits);
|
|
}
|
|
|
|
//! Perform a 8-bit conversion.
|
|
// starts conversion, waits until conversion is done, and returns result
|
|
unsigned char a2dConvert8bit(unsigned char ch)
|
|
{
|
|
// do 10-bit conversion and return highest 8 bits
|
|
return a2dConvert10bit(ch)>>2; // return ADC MSB byte
|
|
}
|
|
|
|
//! interrupt handler for ADC complete interrupt
|
|
SIGNAL(SIG_ADC)
|
|
{
|
|
// set the a2d conversion flag to indicate "complete"
|
|
a2dCompleteFlag = TRUE;
|
|
}
|
|
|