Squirrels have fuzzy tails.
0 Members and 1 Guest are viewing this topic.
return (inb(ADCL) | (inb(ADCH)<<8)); // read ADC (full 10 bits);
/*! \file a2d.h \brief Analog-to-Digital converter function library. *///*****************************************************************************//// File Name : 'a2d.h'// Title : Analog-to-digital converter functions// Author : Pascal Stang - Copyright (C) 2002// Created : 4/08/2002// Revised : 4/30/2002// 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//// modified by bobgardner on avrfreaks.com to handle 16 channels of ADC// - required for ATmega2560, 1280// - define mistakes found and corrected by www.societyofrobots.com////*****************************************************************************//additions with //BG by Bob Gardner for mega2560 16 ch a/d (untested!)#ifndef A2D_H#define A2D_H// defines// A2D clock prescaler select// *selects how much the CPU clock frequency is divided// to create the A2D clock frequency// *lower division ratios make conversion go faster// *higher division ratios make conversions more accurate#define ADC_PRESCALE_DIV2 0x00 ///< 0x01,0x00 -> CPU clk/2#define ADC_PRESCALE_DIV4 0x02 ///< 0x02 -> CPU clk/4#define ADC_PRESCALE_DIV8 0x03 ///< 0x03 -> CPU clk/8#define ADC_PRESCALE_DIV16 0x04 ///< 0x04 -> CPU clk/16#define ADC_PRESCALE_DIV32 0x05 ///< 0x05 -> CPU clk/32#define ADC_PRESCALE_DIV64 0x06 ///< 0x06 -> CPU clk/64#define ADC_PRESCALE_DIV128 0x07 ///< 0x07 -> CPU clk/128// default value#define ADC_PRESCALE ADC_PRESCALE_DIV64// do not change the mask value#define ADC_PRESCALE_MASK 0x07// A2D voltage reference select// *this determines what is used as the// full-scale voltage point for A2D conversions#define ADC_REFERENCE_AREF 0x00 ///< 0x00 -> AREF pin, internal VREF turned off#define ADC_REFERENCE_AVCC 0x01 ///< 0x01 -> AVCC pin, internal VREF turned off#define ADC_REFERENCE_RSVD 0x02 ///< 0x02 -> Reserved#define ADC_REFERENCE_256V 0x03 ///< 0x03 -> Internal 2.56V VREF// default value#define ADC_REFERENCE ADC_REFERENCE_AVCC// do not change the mask value#define ADC_REFERENCE_MASK 0xC0// bit mask for A2D channel multiplexer#define ADC_MUX_MASK 0x1F// channel defines (for reference and use in code)// these channels supported by all AVRs with A2D#define ADC_CH_ADC0 0x00#define ADC_CH_ADC1 0x01#define ADC_CH_ADC2 0x02#define ADC_CH_ADC3 0x03#define ADC_CH_ADC4 0x04#define ADC_CH_ADC5 0x05#define ADC_CH_ADC6 0x06#define ADC_CH_ADC7 0x07#define ADC_CH_ADC8 0x08 //BG add 8 more chans#define ADC_CH_ADC9 0x09#define ADC_CH_ADC10 0x0a#define ADC_CH_ADC11 0x0b#define ADC_CH_ADC12 0x0c#define ADC_CH_ADC13 0x0d#define ADC_CH_ADC14 0x0e#define ADC_CH_ADC15 0x0f#define ADC_CH_122V 0x1E ///< 1.22V voltage reference#define ADC_CH_AGND 0x1F ///< AGND// these channels supported only in ATmega128// differential with gain/*#define ADC_CH_0_0_DIFF10X 0x08#define ADC_CH_1_0_DIFF10X 0x09#define ADC_CH_0_0_DIFF200X 0x0A#define ADC_CH_1_0_DIFF200X 0x0B#define ADC_CH_2_2_DIFF10X 0x0C#define ADC_CH_3_2_DIFF10X 0x0D#define ADC_CH_2_2_DIFF200X 0x0E#define ADC_CH_3_2_DIFF200X 0x0F*/// differential#define ADC_CH_0_1_DIFF1X 0x10#define ADC_CH_1_1_DIFF1X 0x11#define ADC_CH_2_1_DIFF1X 0x12#define ADC_CH_3_1_DIFF1X 0x13#define ADC_CH_4_1_DIFF1X 0x14#define ADC_CH_5_1_DIFF1X 0x15#define ADC_CH_6_1_DIFF1X 0x16#define ADC_CH_7_1_DIFF1X 0x17#define ADC_CH_0_2_DIFF1X 0x18#define ADC_CH_1_2_DIFF1X 0x19#define ADC_CH_2_2_DIFF1X 0x1A#define ADC_CH_3_2_DIFF1X 0x1B#define ADC_CH_4_2_DIFF1X 0x1C#define ADC_CH_5_2_DIFF1X 0x1D// compatibility for new Mega processors// ADCSR hack apparently no longer necessary in new AVR-GCC#ifdef ADCSRA#ifndef ADCSR #define ADCSR ADCSRA#endif#endif#ifdef ADATE #define ADFR ADATE#endif// function prototypes//! Initializes the A/D converter// (turns ADC on and prepares it for use)void a2dInit(void);//! Turn off A/D convertervoid a2dOff(void);//! sets the division ratio of the A/D converter clock// this function is automatically called from a2dInit()// with a default valuevoid a2dSetPrescaler(unsigned char prescale);//! configures which voltage reference the A/D converter uses// this function is automatically called from a2dInit()// with a default valuevoid a2dSetReference(unsigned char ref);//! sets the a2d input channelvoid a2dSetChannel(unsigned char ch);//! start a conversion on the current a2d input channelvoid a2dStartConvert(void);//! return TRUE if conversion is completeu08 a2dIsComplete(void);//! starts a conversion on A/D channel# ch,// returns the 10-bit value of the conversion when it is finishedunsigned short a2dConvert10bit(unsigned char ch);//! starts a conversion on A/D channel# ch,// returns the 8-bit value of the conversion when it is finishedunsigned char a2dConvert8bit(unsigned char ch);#endif
/*! \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/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 convertervoid 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 convertervoid 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 referencevoid a2dSetReference(unsigned char ref){ outb(ADMUX, ((inb(ADMUX) & ~ADC_REFERENCE_MASK) | (ref<<6)));}// sets the a2d input channelvoid 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 channelvoid a2dStartConvert(void){ sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag sbi(ADCSR, ADSC); // start conversion}// return TRUE if conversion is completeu08 a2dIsComplete(void){ return bit_is_set(ADCSR, ADSC);}// Perform a 10-bit conversion// starts conversion, waits until conversion is done, and returns resultunsigned short a2dConvert10bit(unsigned char ch){ a2dCompleteFlag = FALSE; // clear conversion complete flag/*if (bit_is_set(ch, 5)) ADCSRB |= _BV(MUX5);else ADCSRB ^= _BV(MUX5);*/ 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) //old version return ADC;//new version code}// Perform a 8-bit conversion.// starts conversion, waits until conversion is done, and returns resultunsigned 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;}
outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel
if (ch >= 8) ADCSRB |= _BV(MUX5);else ADCSRB &= ~_BV(MUX5); outb(ADMUX, (inb(ADMUX) & ~7) | (ch & 7)); // set channel