⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adc.c

📁 butterflylogger_src_20060822 for atmel avr
💻 C
📖 第 1 页 / 共 2 页
字号:
////Atmel AVR Design Contest 2006 Registration Number AT3221////***************************************************************************////  File........: ADC.c////  Author(s)...: ATMEL Norway////  Target(s)...: ATmega169////  Compiler....: AVR-GCC 3.3.1; avr-libc 1.2////  Description.: AVR Butterfly ADC routines////  Revisions...: 1.0////  YYYYMMDD - VER. - COMMENT                                       - SIGN.////  20030116 - 1.0  - Created                                       - LHM//  20031009          port to avr-gcc/avr-libc                      - M.Thomas//  20050610	      modified for VUW datalogger use				- N.Lott////***************************************************************************//mtA//#include <inavr.h>//#include "iom169.h"#include <avr/io.h>#include <avr/pgmspace.h>#include "pgmspacehlp.h"//mtE#include "main.h"#include "ADC.h"#include "BCD.h"#include "LCD_functions.h"#include "timer0.h"#include "usart.h"#include "speed.h"#include "dataflash.h"// mt __flash int TEMP_Celcius_pos[] =    // Positive Celcius temperatures (ADC-value)const int TEMP_Celcius_pos[] PROGMEM =    // Positive Celcius temperatures (ADC-value){                           // from 0 to 60 degrees	806,796,786,775,765,754,743,732,720,709,697,685,673,661,649,	636,624,611,599,586,574,562,549,537,524,512,500,488,476,464,	452,440,429,418,406,396,385,374,364,354,344,334,324,315,306,	297,288,279,271,263,255,247,240,233,225,219,212,205,199,193,	187,};// mt __flash int TEMP_Celcius_neg[] =    // Negative Celcius temperatures (ADC-value)const int TEMP_Celcius_neg[] PROGMEM =    // Negative Celcius temperatures (ADC-value){                           // from -1 to -15 degrees	815,825,834,843,851,860,868,876,883,891,898,904,911,917,923,};char 	degree = CELCIUS; // char degree = CELCIUS;extern char gLogging;extern char gLogNow;int 	gMaxTemp=1023;int 	gMinTemp=0;/*******************************************************************************   Function name : ADC_init**   Returns :       None**   Parameters :    char input**   Purpose :       Initialize the ADC with the selected ADC-channel******************************************************************************/void ADC_init(char input){	char i;		ADCSRB = (0<<ADTS2) |(0<<ADTS1) |(0<<ADTS0);      ADCSRA = (0<<ADEN) |(0<<ADIE) |(1<<ADPS2)| (0<<ADPS1) | (1<<ADPS0);    // set ADC prescaler to , 4MHz / 32 = 125kHz		if (input == VOLTAGE_SENSOR){		if (!(ADMUX & ((1<<REFS0)|(1<<REFS1)))){			ADMUX = (0<<REFS0)|(0<<REFS1);	//select external AREF			PORTF &= ~(1<<PF3);			// discharge the external capacitor			DDRF |= (1<<DDF3);						// wait ~100uS for 0.2uF to discharge from VCC			for (i=0; i < 134; i++) {};	// one loop takes 3 cpu cycles (740nS @ 4Mhz) 			DDRF &= ~(1<<DDF3);		}		ADMUX = VOLTAGE_SENSOR|(1<<REFS0)|(1<<REFS1); // select internal bandgap reference see VOLTAGE_SENSOR definition			}else{		 // Enable the VCP (VC-peripheral)		PORTF |= (1<<PF3); // mt sbi(PORTF, PORTF3);    		DDRF|=  (1<<DDF3); // sbi(DDRF, PORTF3);    		PORTF &= ~((1<<PF4)|(1<<PF5)|(1<<PF6)); 		DDRF &= ~((1<<PF4)|(1<<PF5)|(1<<PF6));		ADMUX = input;    // external AREF and ADCx    }		// do a dummy read to allow references to stabalise    ADCSRA = (1<<ADEN)| (1<<ADSC) | (0<<ADATE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);    // set ADC prescaler to , 4MHz / 32 = 125kHz    while(ADCSRA & (1<<ADSC));			// wait for conversion done, ADSC flag to zero}/*******************************************************************************   Function name : ADC_read**   Returns :       int ADC**   Parameters :    None**   Purpose :       Do a Analog to Digital Conversion******************************************************************************/int ADC_read(void){    char i;    int ADC_temp;	// mt int ADC = 0 ;	int ADCr = 0;        // To save power, the voltage over the LDR and the NTC is turned off when not used    // This is done by controlling the voltage from a I/O-pin (PORTF3)	// The VCP should be disabled if the internal reference is being used	if (ADMUX & ((1<<REFS0)|(1<<REFS1))){		// disable the VCP (VC-peripheral)		PORTF &= ~(1<<PF3);		DDRF &= ~(1<<DDF3);	}else{		// Enable the VCP (VC-peripheral)		PORTF |=(1<<PF3);		DDRF |= (1<<DDF3);	}	    //do a dummy readout first    ADCSRA |=(1<<ADEN)| (1<<ADSC);      // do single conversion    while(ADCSRA & (1<<ADSC));			// wait for conversion done, ADSC flag to zero		// do the ADC conversion 8 times for better accuracy     for(i=0;i<8;i++){        ADCSRA |= (1<<ADSC);			// do single conversion        while(ADCSRA & (1<<ADSC));		// wait for conversion done, ADSC flag to zero                ADC_temp = ADCL;				// read out ADCL register        ADC_temp += (ADCH << 8);		// read out ADCH register        		        ADCr += ADC_temp;				// accumulate result (8 samples) for later averaging    }		// average the 8 samples    ADCr = ADCr >> 3;						// disable the VCP (VC-peripheral)    PORTF &= ~(1<<PF3);	DDRF &= ~(1<<DDF3);		// disable the ADC	ADCSRA &= ~(1<<ADEN);    return ADCr;}/*******************************************************************************   Function name : ADC_periphery**   Returns :       None**   Parameters :    None**   Purpose :       Calculates the Temperature/Voltage/Ligth from the ADC_read*                   and puts it out on the LCD.******************************************************************************/void ADC_periphery(void){    int ADCresult = 0;        if (!gLogNow) {						// don't read while lig in process		ADCresult=ADC_read();			// read ADC Value				//process ADC value accordingly		switch ((ADMUX & 7)){			case TEMPERATURE_SENSOR:				ADC2Temp(FALSE,ADCresult);				break;			case LIGHT_SENSOR:				//invert for light readings more light = higher reading				ADCresult= 1023-ADCresult;				ADC2RAW(FALSE,ADCresult);				break;			case VOLTAGE_SENSOR:				ADC2Volt(FALSE,ADCresult);				break;			default:				ADC2Direction(FALSE,ADCresult,(ADMUX & 0x07));		}    }    }/*******************************************************************************   Function name : ADC2Temp**   Returns :       nothing**   Parameters :    char log (char to log to rs232 else print to screen)*					int ADCResult (ADC reading to convert)**   Purpose :       Convert an ADC reading into a temp******************************************************************************/void ADC2Temp(char log,int ADCresult){    //   int ADCresult = 0;    //   int ADCresult_temp = 0;    int Temp_int=0;    int dif;    int top;        char Temp;    unsigned char i = 0;    char TL;    char TH;     char VH;	    char VL;        if (ADCresult<gMaxTemp)   // these appear backwards (the gt and lt) due to NTC of thermister		gMaxTemp=ADCresult;    if (ADCresult>gMinTemp)		gMinTemp=ADCresult;    	if(ADCresult > 810){         // If it's a negtive temperature			for (i=0; i<=25; i++){   // Find the temperature				if (ADCresult <= pgm_read_word(&TEMP_Celcius_neg[i])){					// add a decimal reading through liner interpolation					if (ADCresult < pgm_read_word(&TEMP_Celcius_neg[i])){							dif= pgm_read_word(&TEMP_Celcius_neg[i])-pgm_read_word(&TEMP_Celcius_neg[i-1]);						top =(ADCresult-pgm_read_word(TEMP_Celcius_neg[i-1]))*100;												Temp_int = top/(dif+1);						i++;					}					break;				}			}						if (!log) LCD_putc(0, '-');       // Put a minus sign in front of the temperature		}		else if (ADCresult < 800){   // If it's a positive temperature			for (i=0; i<60; i++)  {				if (ADCresult >= pgm_read_word(&TEMP_Celcius_pos[i])){					// add a decimal reading through liner interpolation					if (ADCresult > pgm_read_word(&TEMP_Celcius_pos[i])){							dif= pgm_read_word(&TEMP_Celcius_pos[i-1])-pgm_read_word(&TEMP_Celcius_pos[i]);						top =(pgm_read_word(&TEMP_Celcius_pos[i-1])-ADCresult)*100;												Temp_int = top/(dif+1);						i--;					}					break;				}			}        		} else{                        //If the temperature is zero degrees			i = 0;			LCD_putc(0, ' ');		}				Temp = CHAR2BCD2(i);        // Convert from char to bin		TL = (Temp & 0x0F) + '0';   // Find the low-byte		TH = (Temp >> 4) + '0';     // Find the high-byte				Temp= CHAR2BCD2(Temp_int);		VH = (Temp >> 4) + '0';		VL = (Temp & 0x0F) + '0';				if(log)	{			USART_Tx(TH);			USART_Tx(TL);			USART_Tx('.');			USART_Tx(VH);			USART_Tx(VL);		} else {			LCD_putc(0, TH);			LCD_putc(1, TL);			LCD_putc(2, VH);			LCD_putc(3, VL);			LCD_putc(4, '*');			LCD_putc(5, 'C');			LCD_Colon(TRUE);			LCD_putc(6, '\0');		}}/*******************************************************************************   Function name : ADC2Direction**   Returns :       nothing**   Parameters :    char log (char to log to flash else print to screen)*					int ADCResult (ADC reading to convert)**   Purpose :       Convert an ADC reading into a Direction Reading******************************************************************************/void ADC2Direction(char log, int ADCresult, char sensor){    //  int Temp_int;    int Temp;    char TL;    char TH;     char THH;        Temp = CHAR2BCD3(ADCresult);                    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -