Anda di halaman 1dari 6

Light and Temperature Sensors

Prerequisites for the program Make sure you have a working MAX232 interfacing circuit connected to the UART such as the one shown here. Make sure you have tested the UART communications with windows hyperterminal using uart.h and uart.c include files as shown in the section here. ADC value is printed to hyperterminal so make sure you have tested the UART as shown in the above step first. The ATmega32 ADC The ATmega32 has an internal analog to digital converter to sample analog signals. It also has a multiplexer so that it is possible to sample 8 different single ended analog signals. Port A is a shared port that can be used for either digital data or analog inputs.

The Multiplexer allows 8 single ended inputs at the same time. Inputs can also be differential ADC0, ADC1, ADC2 inputs are equipped with an AMP to increase signal level by differential gain in steps of 0 dB (1x), 20 dB (10x), or 46 dB (200x)

ADMUX Register

REFS1 0 0 1 1 pin

REFS0 0 1 0 1

Methods for selecting Voltage Reference AREF, Internal Vref turned off AVcc with external capacitor at AREF pin Reserved Internal 2.56V Voltage Reference with external capacitor at AREF

The analog to digital converter needs a reference voltage to determine the conversion range. The minimum value of the analog signal is represented by ground and the maximum value by Vref. For most applications Vcc is sufficient by setting bit REFS0 to 1. Vcc is prone to noise so as a result an external decoupling capacitor is recommended. ADMUX |= _BV(REFS0);

Analog Channel and Gain Selection Bits

By setting the bits 4,3,2,1,0 different options are available. Amplifier gain is only available through differential inputs. MUX4 0 0 0 0 0 0 0 0 AMP 0 10x 0 10x 0 200x 0 200x 0 10x 0 10x 0 200x 0 200x 1 1 1 1 1 1 1 1 1 1 1 1 1 MUX3 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 MUX2 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 MUX1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 MUX0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 Single Ended ADC0 ADC1 ADC2 ADC3 N/A ADC4 ADC5 ADC6 ADC7 +ve ADC0 ADC1 ADC0 ADC1 ADC2 ADC3 ADC2 ADC3 ADC0 ADC1 ADC2 N/A ADC3 ADC4 ADC5 ADC6 ADC7 ADC0 ADC1 ADC2 ADC3 ADC4

Differential Inputs -ve ADC0 ADC0 ADC0 ADC0 ADC2 ADC2 ADC2 ADC2 ADC1 ADC1 ADC1 ADC1 ADC1 ADC1 ADC1 ADC1 ADC2 ADC2 ADC2 ADC2 ADC2 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x

In a simple case we can use a single ended input. Any port from ADC0 to ADC7 will work. ADCport can be any number from 0 to 7 and passed through the function: ReadADC(uint8_t ADCport) ADCport=ADCport&0b00000111; ADMUX|=ADCport;

ADCSRA - Control and Status Register

Bit 7 ADEN: Set this to 1 to enable the microcontroller ADC circuits. 0 will switch it off. ADCSRA |= _BV(ADEN); Bit 6 ADSC: Setting ADSC bit to 1 starts the conversion process. This bit is automatically cleared when the conversion process is completed. This is the ADC's way of letting you know that the conversion is completed. Starts the single mode conversion process. ADCSRA |= _BV(ADSC); This while loop waits for the ADSC bit to become 0 again. while( ADCSRA & _BV(ADSC) ); ADPS2, ADPS1, ADPS0: These bits determine the division factor between the XTAL frequency and the ADC input clock. Converting an analog signal to digital requires a clock frequency for the approximation circuitry. Remember the strips under a curve in maths class? The more strips the better the approximation of the analog signal. A frequency between 50Khz and 200Khz is usual for maximum resolution. The prescaler frequency is made from the CPU frequency by using a division factor. This is determined by setting the bits ADPS2, ADPS1, ADPS0. ADPS2 0 0 0 0 1 1 1 1 ADPS1 0 0 1 1 0 0 1 1 ADPS0 0 1 0 1 0 1 0 1 Division Factor 2 2 4 8 16 32 64 128

With a typical 16Mhz clock frequency connected to this microcontroller. 16000,000 / 128 = 125Khz which is within the maximum resolution range so we choose a prescaler division factor of 128 by setting pins ADPS2, ADPS1, ADPS0 to 1. ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);

/********************************************************** Author:Peter J. Vis Last Updated:8 Dec 2009

Microcontroller:ATmega32 Crystal:16Mhz Platform:Development System URL:http://www.petervis.com/C/development/introduction.html LIMITATIONS: No portion of this work can be used in commercial applications without written permission.This program can be published in magazines and articles with previous consent and as long as credit is given to the author. PURPOSE: To test the Light Dependent Resistor Sensor. To calibrate for maximum and minimum values. CIRCUIT: LDR connected to ADC2 port of the ATmega32 **********************************************************/ #define F_CPU 16000000UL #include #include #include #include <avr/io.h> <util/delay.h> "uart.h" "uart.c"

// prototypes void initADC(); void uart_init(); uint16_t ReadADC(uint8_t ADCport); int main() { uint8_t i; uint16_t analog_value; // init ADC initADC(); // init UART - this function is in an external file uart.c // this is needed to make printf work to send // characters to hyperterminal uart_init(); // init hyperterminal by sending VT100 escape sequences printf("\x1B[2J\x1B\x63"); // Print a welcome message. printf("Hello... are you ready to calibrate? \r\n");

while(1) { //read LDR Sensor on port ADC02 ReadADC(2); // read the result from the ADC register analog_value = ADC; // move the hyperterminal cursor to the next line // [2;1H move cursor to Row 2, Column 1, 2K // erases the line printf("\x1B[2;1H\x1B[2K"); //print a 10-bit analog value to hyperterminal printf("ADC value: %u\r\n", analog_value); //wait 100ms for(i=0; i<10; i++) _delay_ms(10); } } return 0;

/************************************************* This function will Initialize the ADC for the correct Vref and Prescaler and enable it. *************************************************/ void initADC() { // init ADC // select Vref -> AVcc with external // capacitor at AREF pin ADMUX |= _BV(REFS0); // select prescaler of 128 ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); //enable ADC ADCSRA |= _BV(ADEN); }

/********************************************************** This function will read the ADC value from the ADC port specified. port values - my system has 3 different sensors on different ports. Pass the relavent value to the function for the sensor required. ADCPort Circuit 0 Analog Input 1 Thermistor 2 LDR **********************************************************/ uint16_t ReadADC(uint8_t ADCport) { ADCport=ADCport&0b00000111; ADMUX|=ADCport; // start the single conversion mode process ADCSRA |= _BV(ADSC); // wait for the conversion to finish, // the ADC signals that it's // completed by automatically clearing the ADSC bit. // wait in a while loop for the bit to clear while( ADCSRA & _BV(ADSC) ); return(ADC);

Anda mungkin juga menyukai