EZ430 Chronos 自带程序源码:温度计示范程序

EZ430 Chronos 自带程序源码:温度计示范程序

temperature.c
// *************************************************************************************************
//
//	Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ 
//	 
//	 
//	  Redistribution and use in source and binary forms, with or without 
//	  modification, are permitted provided that the following conditions 
//	  are met:
//	
//	    Redistributions of source code must retain the above copyright 
//	    notice, this list of conditions and the following disclaimer.
//	 
//	    Redistributions in binary form must reproduce the above copyright
//	    notice, this list of conditions and the following disclaimer in the 
//	    documentation and/or other materials provided with the   
//	    distribution.
//	 
//	    Neither the name of Texas Instruments Incorporated nor the names of
//	    its contributors may be used to endorse or promote products derived
//	    from this software without specific prior written permission.
//	
//	  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//	  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//	  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
//	  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
//	  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
//	  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
//	  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
//	  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
//	  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
//	  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
//	  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// *************************************************************************************************
// Temperature measurement functions.
// *************************************************************************************************


// *************************************************************************************************
// Include section

// system
#include "project.h"

// driver
#include "temperature.h"
#include "ports.h"
#include "display.h"
#include "adc12.h"
#include "timer.h"

// logic
#include "user.h"


// *************************************************************************************************
// Prototypes section
u8 is_temp_measurement(void);
s16 convert_C_to_F(s16 value);
s16 convert_F_to_C(s16 value);


// *************************************************************************************************
// Defines section


// *************************************************************************************************
// Global Variable section
struct temp sTemp;


// *************************************************************************************************
// Extern section


// *************************************************************************************************
// @fn          reset_temp_measurement
// @brief        Reset temperature measurement module.
// @param       none
// @return       none
// *************************************************************************************************
void reset_temp_measurement(void)
{
	// Set flag to off
  	sTemp.state = MENU_ITEM_NOT_VISIBLE; 

	// Perform one temperature measurements with disabled filter
	temperature_measurement(FILTER_OFF);
}


// *************************************************************************************************
// @fn          temperature_measurement
// @brief        Init ADC12. Do single conversion of temperature sensor voltage. Turn off ADC12.
// @param       none
// @return       none
// *************************************************************************************************
void temperature_measurement(u8 filter)
{
	u16 adc_result;
	volatile s32 temperature;
	
	// Convert internal temperature diode voltage 
	adc_result = adc12_single_conversion(REFVSEL_0, ADC12SHT0_8, ADC12INCH_10);
	
	// Convert ADC value to "xx.x °C"
 	// Temperature in Celsius
    // ((A10/4096*1500mV) - 680mV)*(1/2.25mV) = (A10/4096*667) - 302
    // = (A10 - 1855) * (667 / 4096)
    temperature = (((s32)((s32)adc_result-1855))*667*10)/4096;
	
	// Add temperature offset
	temperature += sTemp.offset;	
	
	// Store measured temperature 
	if (filter == FILTER_ON)
	{
		// Change temperature in 0.1° steps towards measured value
		if (temperature > sTemp.degrees)		sTemp.degrees += 1;
		else if (temperature < sTemp.degrees)	sTemp.degrees -= 1;
	}
	else
	{
		// Override filter 
		sTemp.degrees = (s16)temperature;
	}

	// New data is available --> do display update
	display.flag.update_temperature = 1;
}


// *************************************************************************************************
// @fn          convert_C_to_F
// @brief        Convert °C to °F 
// @param       s16 value		Temperature in °C
// @return       s16 			Temperature in °F
// *************************************************************************************************
s16 convert_C_to_F(s16 value)
{
	s16 DegF;

	// Celsius in Fahrenheit = (( TCelsius × 9 ) / 5 ) + 32
    DegF = ((value*9*10)/5/10)+32*10;
    
	return (DegF);
}


// *************************************************************************************************
// @fn          convert_F_to_C
// @brief        Convert °F to °C 
// @param       s16 value		Temperature in 2.1 °F
// @return       s16 			Temperature in 2.1 °C
// *************************************************************************************************
s16 convert_F_to_C(s16 value)
{
	s16 DegC;

	// TCelsius =( TFahrenheit - 32 ) × 5 / 9
    DegC = (((value-320)*5))/9;
    
	return (DegC);
}


// *************************************************************************************************
// @fn          is_temp_measurement
// @brief        Returns TRUE if temperature measurement is enabled. 
// @param       none
// @return       u8
// *************************************************************************************************
u8 is_temp_measurement(void)
{
	return (sTemp.state == MENU_ITEM_VISIBLE);
}


// *************************************************************************************************
// @fn          mx_temperature
// @brief        Mx button handler to set the temperature offset. 
// @param       u8 line		LINE1
// @return       none
// *************************************************************************************************
void mx_temperature(u8 line)
{
	s32 temperature;
	s16 temperature0;
	volatile s16 temperature1;
	volatile s16 offset;

	// Clear display
	clear_display_all();

	// When using English units, convert internal °C to °F before handing over value to set_value function
	if (!sys.flag.use_metric_units)
	{
		// Convert global variable to local variable
		temperature  = convert_C_to_F(sTemp.degrees);
		temperature0 = sTemp.degrees;
	}
	else
	{
		// Convert global variable to local variable
		temperature  = sTemp.degrees;
		temperature0 = temperature;
	}

	// Loop values until all are set or user breaks	set
	while(1) 
	{
		// Idle timeout: exit without saving 
		if (sys.flag.idle_timeout) break;

		// Button STAR (short): save, then exit 
		if (button.flag.star) 
		{
			// For English units, convert set °F to °C
			if (!sys.flag.use_metric_units)
			{
				temperature1 = convert_F_to_C(temperature);	
			}
			else
			{
				temperature1 = temperature;
			}

			// New offset is difference between old and new value
			offset = temperature1 - temperature0;
			sTemp.offset += offset;

			// Force filter to new value
			sTemp.degrees = temperature1;
			
			// Set display update flag
			display.flag.line1_full_update = 1;

			break;
		}

		// Display °C or °F depending on unit system
		if (sys.flag.use_metric_units)		display_char(LCD_SEG_L1_0, 'C', SEG_ON);
		else								display_char(LCD_SEG_L1_0, 'F', SEG_ON);
		display_symbol(LCD_SEG_L1_DP1, SEG_ON);
		display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON);			

		// Set current temperature - offset is set when leaving function
		set_value(&temperature, 3, 1, -999, 999, SETVALUE_DISPLAY_VALUE + SETVALUE_DISPLAY_ARROWS, LCD_SEG_L1_3_1, display_value1);
	}	
	
	// Clear button flags
	button.all_flags = 0;
}


// *************************************************************************************************
// @fn          display_temperature
// @brief        Common display routine for metric and English units. 
// @param       u8 line			LINE1
//				u8 update		DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR
// @return       none
// *************************************************************************************************
void display_temperature(u8 line, u8 update)
{
	u8 * str;
	s16 temperature;

	// Redraw whole screen
	if (update == DISPLAY_LINE_UPDATE_FULL)	
	{
		// Menu item is visible
		sTemp.state = MENU_ITEM_VISIBLE; 
		
		// Display °C / °F
		display_symbol(LCD_SEG_L1_DP1, SEG_ON);
		display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON);
		if (sys.flag.use_metric_units)	display_char(LCD_SEG_L1_0, 'C', SEG_ON);
		else							display_char(LCD_SEG_L1_0, 'F', SEG_ON);
		
		// Perform one temperature measurement with disabled filter
		temperature_measurement(FILTER_OFF);
		
		// Display temperature
		display_temperature(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
	}
	else if (update == DISPLAY_LINE_UPDATE_PARTIAL)
	{
		// When using English units, convert °C to °F (temp*1.8+32)
		if (!sys.flag.use_metric_units)
		{
		    temperature = convert_C_to_F(sTemp.degrees);              
		}
		else
		{
			temperature = sTemp.degrees;
		}
		
		// Indicate temperature sign through arrow up/down icon
		if (temperature < 0) 
		{
			// Convert negative to positive number
			temperature = ~temperature;
			temperature += 1;
			
			display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
			display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
		}
		else // Temperature is >= 0
		{
			display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
			display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
		}	
		
		// Limit min/max temperature to +/- 99.9 °C / °F
		if (temperature > 999 ) temperature = 999;

		// Display result in xx.x format
		str = itoa(temperature, 3, 1);
		display_chars(LCD_SEG_L1_3_1, str, SEG_ON);
	}
	else if (update == DISPLAY_LINE_CLEAR)
	{
		// Menu item is not visible
		sTemp.state = MENU_ITEM_NOT_VISIBLE; 	
		
		// Clean up function-specific segments before leaving function
		display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
		display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
		display_symbol(LCD_UNIT_L1_DEGREE, SEG_OFF);
		display_symbol(LCD_SEG_L1_DP1, SEG_OFF);
	}
}

 

temperature.h

// *************************************************************************************************
//
//	Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ 
//	 
//	 
//	  Redistribution and use in source and binary forms, with or without 
//	  modification, are permitted provided that the following conditions 
//	  are met:
//	
//	    Redistributions of source code must retain the above copyright 
//	    notice, this list of conditions and the following disclaimer.
//	 
//	    Redistributions in binary form must reproduce the above copyright
//	    notice, this list of conditions and the following disclaimer in the 
//	    documentation and/or other materials provided with the   
//	    distribution.
//	 
//	    Neither the name of Texas Instruments Incorporated nor the names of
//	    its contributors may be used to endorse or promote products derived
//	    from this software without specific prior written permission.
//	
//	  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//	  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//	  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
//	  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
//	  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
//	  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
//	  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
//	  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
//	  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
//	  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
//	  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// *************************************************************************************************

#ifndef TEMPERATURE_H_
#define TEMPERATURE_H_

// *************************************************************************************************
// Include section


// *************************************************************************************************
// Prototypes section

// internal functions
extern void reset_temp_measurement(void);
extern u8 is_temp_measurement(void);
extern void temperature_measurement(u8 filter);

// menu functions
extern void mx_temperature(u8 line);
extern void display_temperature(u8 line, u8 update);


// *************************************************************************************************
// Defines section


// *************************************************************************************************
// Global Variable section
struct temp
{
	// MENU_ITEM_NOT_VISIBLE, MENU_ITEM_VISIBLE
	menu_t	 	state;
	// Temperature (癈) in 2.1 format
	s16		degrees;
	// User set calibration value (癈) in 2.1 format
	s16		offset;
};
extern struct temp sTemp;


// *************************************************************************************************
// Extern section


#endif /*TEMPERATURE_H_*/

你可能感兴趣的:(EZ430 Chronos 自带程序源码:温度计示范程序)