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

📄 sht.c

📁 butterflylogger_src_20060822 for atmel avr
💻 C
字号:
////Atmel AVR Design Contest 2006 Registration Number AT3221////----------------------------------------------------------------------------------//// Sensirion SHTxx Humidity Sensor Library//// Library for using the SHT1x humidity and temperature// sensors from Sensirion (http://www.sensirion.com).// Based on Sensirion application note "Sample Code SHTxx".//// To use:// - supply 5V to SHTxx (constants in calculations assume 5V, see ShtCalculate() and SHTxx datasheet)// - connect the clock pin of the SHTxx to pin B1 (see Sht.h to change)// - connect the data pin of the SHTxx to pin B2 (see Sht.h to change)//// - call ShtInit() to initialize pins, call when the processor starts// - call ShtMeasure(MEASURE_TEMP) and ShtMeasure(MEASURE_HUMIDITY) to make the measurements// - call ShtCalculate() to convert measurements to real-world units//// - call ShtReadStatus() and ShtWriteStatus() to modify the status register////// ToDo:// - verify checksum digits sent from SHTxx// - implement soft-reset// - handle 12/8-bit temp/humidity readings//// History:// 2003-Jul-03	BL	- Created// 2004-Jul-15  NL  - Adapted for IAR Compiler// 2005-Jun-00	NL	- Converted back to GCC//----------------------------------------------------------------------------------#include <avr/io.h>#include <avr/interrupt.h>#include <avr/pgmspace.h>#include <avr/sleep.h>#include <inttypes.h>#include "sht.h"// Macro definitions// ( GNU compatability Macros )#ifndef sbi    #define _BV(bit)			(1 << (bit))    #define sbi(x,bit)			(x |= _BV(bit)) // set bit  ( GNU compatability )    #define cbi(x,bit)			(x &= ~_BV(bit)) // clear bit  ( GNU compatability )#endif#ifndef bit_is_set    #define bit_is_set(sfr, bit) (sfr & _BV(bit))    #define bit_is_clear(sfr, bit) (!(sfr & _BV(bit)))#endifvoid enable_data(void) 		{ sbi(SHT_DDR, SHT_DATA);	}	// Drive DATA pinvoid disable_data(void)		{ cbi(SHT_DDR, SHT_DATA); 		// Release DATA pin							  sbi(SHT_PORT, SHT_DATA); }void data_high(void)		{ sbi(SHT_PORT, SHT_DATA); }	// DATA pin highvoid data_low(void)			{ cbi(SHT_PORT, SHT_DATA); }	// DATA pin lowvoid clock_high(void)		{ sbi(SHT_PORT, SHT_CLOCK); } 	// CLOCK pin highvoid clock_low(void)		{ cbi(SHT_PORT, SHT_CLOCK); }	// CLOCK pin lowvoid sht_pwrOn(void) 		{ sbi(SHT_PORT, SHT_PWR);}    // power onvoid sht_pwrOff(void) 		{ cbi(SHT_PORT, SHT_PWR);}    // power off//----------------------------------------------------------------------------------// Initialize AVR i/o pins.//----------------------------------------------------------------------------------void ShtInit(void){	sbi(SHT_DDR, SHT_PWR);	sht_pwrOn();	sbi(SHT_DDR, SHT_CLOCK);		// Set clock pin to output	cbi(SHT_PORT, SHT_CLOCK);		// Turn off clock pin	disable_data();}//----------------------------------------------------------------------------------// generates a transmission start//       _____         ________// DATA:      |_______|//           ___     ___// SCK : ___|   |___|   |______////----------------------------------------------------------------------------------void transstart(void){	enable_data();	data_high();	clock_low();	DELAY(SHT_DELAY);	DELAY(SHT_DELAY);	clock_high(); DELAY(SHT_DELAY);	data_low();	DELAY(SHT_DELAY);	clock_low();	DELAY(SHT_DELAY); DELAY(SHT_DELAY);	clock_high();	DELAY(SHT_DELAY);	data_high();	DELAY(SHT_DELAY);	clock_low();}//----------------------------------------------------------------------------------// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart//       _____________________________________________________         ________// DATA:                                                      |_______|//          _    _    _    _    _    _    _    _    _        ___     ___// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______//----------------------------------------------------------------------------------void ShtReset(void){	unsigned char i;	enable_data();	data_high();	clock_low();	for(i=0;i<10;i++) //9 SCK cycles	{		clock_high();		Delay_us(SHT_DELAY);		clock_low();		Delay_us(SHT_DELAY);	}	transstart(); //transmission start}//----------------------------------------------------------------------------------// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"//----------------------------------------------------------------------------------char read_byte(void){	unsigned char i,val=0;	disable_data();	// Read in 8 bits, LSB first	for (i=0x80;i>0;i/=2)	{		clock_high();		DELAY(SHT_DELAY);		if (bit_is_set(SHT_PIN, SHT_DATA))			val=(val | i); //read bit		clock_low();	}	// Send ACK	enable_data();	data_low();	clock_high();	DELAY(SHT_DELAY);	clock_low();	disable_data();	return val;}//----------------------------------------------------------------------------------// Writes a byte on the Sensibus and checks the acknowledge.// Returns 0 if the successful//----------------------------------------------------------------------------------char write_byte(unsigned char value){	unsigned char i;	unsigned char error = 0;	// Write each bit one at a time, LSB first	enable_data();	for (i=0x80;i>0;i/=2)	{		if (i & value)			data_high();		else			data_low();		clock_high();		DELAY(SHT_DELAY);		DELAY(SHT_DELAY);		clock_low();	}	disable_data();	// Read ACK	clock_high();	DELAY(SHT_DELAY);	error = bit_is_set(SHT_PIN, SHT_DATA);	clock_low();	return error; //error=1 in case of no acknowledge}//----------------------------------------------------------------------------------// Read humidity or temperature from the sensor.// Returns the value in ticks. Use sht_calc() to convert to real world units.// Returns 0xFFFF if the measurment failed//----------------------------------------------------------------------------------int ShtMeasure(unsigned char mode){	unsigned int 	temp = 0xFFFF;	unsigned char	checksum;	unsigned char 	c;	// Signal start of communications	transstart();	// Request measurement	write_byte(mode);	// Sensor lowers the data line when measurement	// is complete. Wait up to 2 seconds for this.	for (c=0; c<20; c++)	{		if (! bit_is_set(SHT_PIN, SHT_DATA))			break;		DELAY(1000000/10);	}	// Read the measurement	if (! bit_is_set(SHT_PIN, SHT_DATA))	{		temp = read_byte();		temp = temp << 8;		temp += read_byte();		checksum = read_byte();	}	return temp;}	/* 	this can be done on the host computer post logging	*//----------------------------------------------------------------------------------------// Calculates tempurature in ^C and humidity in %RH (temperature compensated)// sht_measure() returns temp and humidity in ticks. Use this function to convert// to compensated values in real world units.//// This function returns integers with 2 assumed decimal places. For example 2550// means 25.50. This is to avoid including the floating point math library.//// input :	humi [Ticks] (12 bit)// 			temp [Ticks] (14 bit)// output: 	humi [%RH] (2 fixed decimals)// 			temp [^C]  (2 fixed decimals)//----------------------------------------------------------------------------------------void ShtCalculate(int *p_temperature, int *p_humidity){	const long D1x100 = -40 * 100;					// for 5V power	const long D2x100 = 0.01 * 100;					// for 14bit temp	const long C1x100 = -4 * 100;					// for 12bit humidity	const long C2x10000 = 0.0405 * 10000;			// for 12bit humidity	const long C3x10000000 = -0.0000028 * 10000000;	// for 12bit humidity	const long T1x100000 = 0.01 * 100000;			// for 12bit humidity	const long T2x100000 = 0.00008 * 100000;		// for 12bit humidity	long t = *p_temperature;			// temperatere in ticks from sensor	long rh = *p_humidity;				// humidity in ticks from sensor	long t_C;							// temperature in celcius: 2 fixed decimals	long rh_lin;						// relative humidity: 2 fixed decimals	long rh_true;						// temp compensated humidity: 2 fixed decimals	t_C = D1x100 + D2x100*t;			// calculate tempurature in celcius from ticks	rh_lin = (C3x10000000*rh*rh)/100000 + (C2x10000*rh)/100 + C1x100;	rh_true = ((t_C-(25*100)) * (T1x100000 + T2x100000*rh))/100000 + rh_lin;	if(rh_true>10000)rh_true=10000; 	//cut if the value is outside of	if(rh_true<10)rh_true=10; 			//the physical possible range	*p_temperature=(int)t_C; 			//return temperature [^C]	*p_humidity=(int)rh_true;	 		//return humidity[%RH]	}*///----------------------------------------------------------------------------------// Reads the status register with checksum (8-bit)//----------------------------------------------------------------------------------char ShtReadStatus(unsigned char *p_value){	unsigned char error=0;	unsigned char checksum=0;	transstart(); 					//transmission start	error = write_byte(STATUS_REG_R); 	//send command to sensor	*p_value = read_byte(); 			//read status register (8-bit)	checksum = read_byte(); 			//read checksum (8-bit)	return error; 						//error=1 in case of no response form the sensor}//----------------------------------------------------------------------------------// Writes the status register . Note this library only supports the default// 14 bit temp and 12 bit humidity readings.//----------------------------------------------------------------------------------char ShtWriteStatus(unsigned char value){	unsigned char error=0;	transstart(); 					//transmission start	error += write_byte(STATUS_REG_W);	//send command to sensor	error += write_byte(value); 		//send value of status register	return error; 						//error>=1 in case of no response form the sensor}//----------------------------------------------------------------------------------// delay for a minimum of <us> microseconds // the time resolution is dependent on the time the loop takes // e.g. with 4Mhz and 5 cycles per loop, the resolution is 1.25 us //----------------------------------------------------------------------------------void Delay_us(unsigned long us){ 	// 6 cpu cycles per loop + 16 cycles overhead    unsigned short  delay_loops;    register unsigned short  i;    delay_loops = (us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty) 	// one loop takes 5 cpu cycles     for (i=0; i < delay_loops; i++) {};	return;}

⌨️ 快捷键说明

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