[En-Nut-Discussion] Analog input

The Laing Family laing at bigpond.net.au
Sat Jan 17 03:51:15 CET 2004


Hmmm, I think this may be a bit trickier than it first appears - at least I
have been struggling with the same issue. However, I think I have pretty
well worked it out, though I would be very grateful for someone to correct
any mistakes I have made. A few notes:

1) Port F is not marked in any way on my Ehthernut 2.0 board, and its
location is not explained in the hardware manual. However, it is the only
20-way IDC connector on the board and is located on the edge of the board
next to the programming port socket.

2) The allocation of the pins is shown in the circuit diagrams at the back
of the hardware manual, and the AVCC5 pins are nearest the R3 resistor.

3) The documentation in the Atmega128 datasheet is pretty exhaustive and
very useful.

As for software, I have slightly modified Lars Andersson's code to use only
1 function (I don't know why he bothered with a separate initalisation
function?), and include my code below. Using this, I get a reasonably linear
reading of the voltage on the input up to about 3V, then it seems to flatten
out.

I hope this is useful to someone....

Regards,

Simon (Laing)

/*
 * FUNCTION:    ADConvert
 *
 * DESCRIPTION: Read one of the analog channels using a simple,
non-interrupt driven ADC driver
 *
 *				This involves manipulating the ADC registers, which are specified as
follows
 *				for the Atmega128 (see page 243-246 of the Atmega128 Manual)
 *
 *					Register	Bit	Name	Value	Meaning
 *				 	ADMUX		 7 	REFS1 	  1		Use internal 2.56V REF with external
capacitor at AREF pin
 *				 	ADMUX		 6	REFS0	  1		Use internal 2.56V REF with external capacitor
at AREF pin
 *				 	ADMUX		 5	ADLAR 	  0		Left Adjust Result (0 = Right-adjusted)
 *				 	ADMUX		4-0	MUX4..0	  n		Input Channel and Gain Selection
 *
 *				 	ADCSRA		 7	ADEN 	  1		AD converter on
 *					ADCSRA		 6	ADSC	  0 	Start Conversion
 *				 	ADCSRA		 5	ADFR 	  0		Free-running Select (0 = OFF)
 *				 	ADCSRA		 4	ADIF	  0		ADC Interrupt Flag (Set when conversion
completes)
 *				 	ADCSRA		 3	ADIE	  0		ADC Interrupt Enable (Interrupts enabled when
set)
 *				 	ADCSRA	 	2-0	ADPS2..0  7		Pre-scaler Select bits (Gives division
factors from 2 to 128)
 *
 * PARAMETERS:	Channel:		Analog channel to read (0 - 7)
 *				DivFactor:		Division factor - any power of 2 up to 128.
 *
 * RETURN CODE: 10-bit analog value
 *
 * SOURCE: 		Derived from Lars Andersson on
http://news.gmane.org/gmane.comp.hardware.microcontrollers.ethernut
 */
int ADConvert(short Channel, short DivFactor)
{
	int ADresult;							/* Result to be returned								*/
	int DivMask = 0;						/* Bit mask for the requested division factor			*/
	int	i;									/* Loop counter for computing log value					*/

	/*
	 * Set the multiplexer register
	 */
	ADMUX = 0xC0 | (Channel & 0x07);		/* Use internal ref voltage and set
channel */

	/*
	 * Compute the bit mask for the division factor
	 */
	for (i = 0; i < 8; i++)
	{
		/*
		 * Need to take the log of the requested division factor. Do this by
		 * working out which is the most significant bit
		 */
		if (DivFactor & 0x01)
			DivMask = i;
		DivFactor >>= 1;
	}

	/*
	 * Set up the Control and Status register. Enable ADC, clear ADIF (by
setting it!),
	 * and set the division factor
	 */
	ADCSRA = (0x90 | DivMask);

	/*
	 * Delay a little to settle the MUX
	 */
	NutDelay(40);

	/*
	 * Start the ADC and wait for it to complete the conversion
	 */
	sbi(ADCSRA, ADSC);               		/* Start ADC	*/
	loop_until_bit_is_set(ADCSRA, ADIF); 	/* Wait for ADIF, will happen soon */

	/*
	 * Read the input value
	 */
	ADresult = ADCL;			    		/* Read LSB first   */
	ADresult |= ((int)ADCH) << 8;			/* then MSB         */

	/*
	 * Clear the ADCSRA, including the AD Interrupt Flag (by setting it!)
	 */
	ADCSRA = 0x10;

	return(ADresult);
}



> -----Original Message-----
> From: en-nut-discussion-bounces at egnite.de
> [mailto:en-nut-discussion-bounces at egnite.de]On Behalf Of Simon Biniek
> Sent: Saturday, 17 January 2004 1:29 AM
> To: Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] Analog input
>
>
> > Do some have a example how i can use the analog
> > input on ethernut using the internal analog input og
> > port F?
>
> It's the third time you've asked that and you've got
> an awnser and example code here in the group.
> First off all read the Datasheet of the AtMega128.
>
> > I have a ordninary temperature resistor. I want to
> > sample the value of the resistor.
> > On port F it is pins fra 1..8. How do i connect the
> > resistor?
>
> Analog Inputs can't directly mesare resistors. They
> only can measure voltages. You have to build a voltage
> divider or a robinson bridge.
>
> regards
>
> Simon
>
>
> __________________________________
> Do you Yahoo!?
> Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes
> http://hotjobs.sweepstakes.yahoo.com/signingbonus
> _______________________________________________
> En-Nut-Discussion mailing list
> En-Nut-Discussion at egnite.de
> http://www.egnite.de/mailman/listinfo.cgi/en-nut-discussion




More information about the En-Nut-Discussion mailing list