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

📄 onewirelib.c

📁 学完单片机就要使用实时系统在单片机上运行
💻 C
📖 第 1 页 / 共 2 页
字号:
//////////////////
// OneWireLib.c
// (C) 2004 Steve Childress stevech@san.rr.com
// NOTE: the test function at the bottom of this file can be 
//       omitted from the compilation of this library.

#include "OPEX.h"

// Define which bit on which port is one-wire
#define IODDR 	DDRA
#define OUTPORT PORTA
#define INPORT  PINA
#define IOBIT 	7
#define IOBITMASK 0x80



// this math works for CPU clocks 1MHz or more
// CPU clock at 6MHz  so  1/f = 0.16uSec = 160 nsec
// 8MHz  = 125ns
// 10Mhz = 100ns
// 16MHz = 62ns
const int xCLOCKS_PER_USEC = 1000 / 160; 	// 1000 nSec = 1uSec

#define FALSE 0
#define TRUE 1

extern char StringBuf1[];

// Externally useful routines
int 	OWReset(void);	// TRUE if device(s) detected
void	OWFamilySelect(unsigned char family_code);
int 	OWFirst(void);	
int 	OWNext(void);
int 	OWVerify(void);

// internal OW routines
int 	OWSearch(void);
void 	OWTargetSetup(unsigned char family_code);
void 	OWFamilySkipSetup(void);

void 	OWWriteByte(unsigned char byte_value);
void 	OWWriteBit(unsigned char bit_value);
unsigned char OWReadBit(void);
unsigned char docrc8(unsigned char value);


////////////////////////
// Static
// global search state
unsigned char ROM_NO[8];
int LastDiscrepancy;
int LastFamilyDiscrepancy;
int LastDeviceFlag;
unsigned char crc8;



/////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------------
// I/O PORT FUNCTIONS FOR ONE WIRE
//--------------------------------------------------------------------------


//--------------------------------------------------------------------------
// Reset the 1-Wire bus and return the presence of any device
// Reset is a 0 on the bus for at least 480uSec
// RETURN: state = 0 if no devices detected	
////////////////////////////////////////////////
int OWReset(void)
{
	register unsigned int n;
	int ret = 0;
		
	// create 480uSec reset pulse with CPU looping (oh my)
	n = (xCLOCKS_PER_USEC * 480) / 3;	// compile-time math
	sbi(IODDR, IOBIT);			// output mode
	cbi(OUTPORT, IOBIT);  		// begin the reset, 0 to the bu
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	sbi(OUTPORT, IOBIT); 	// unreset
	cbi(IODDR, IOBIT);		// pin is an input

	// now expect a presence pulse created by any connected 1-wire chip
	n = 0;
	while ((INPORT & IOBITMASK) == 0)  // should go hi after RC chargeup, a few uSec
		if (++n == 0)
			goto err0;
	n = 0;
	while ((INPORT & IOBITMASK) != 0)   // within 60uSec bus should go low, presence pulse
		if (++n == 0)
			goto err0;
	n = 0;
	while ((INPORT & IOBITMASK) == 0)   // should go hi at end of 60-240us presence pulse
		if (++n == 0)
			goto err0;
	ret = 1;
err0:
	return(ret);	
}



//--------------------------------------------------------------------------
// Send 8 bits of data to the 1-Wire bus
//
void OWWriteByte(unsigned char byte_value)
{
	BYTE i;
	
	sbi(IODDR, IOBIT);	// output mode
	cli();		// takes about 600 uSec for this loop
	for (i = 1; i != 0; i <<= 1)
		OWWriteBit( (byte_value & i) != 0 );
	sei();
}
//--------------------------------------------------------------------------
// Send 1 bit of data to the 1-Wire bus
//
void OWWriteBit(unsigned char bit_value)
{
	int n;
	BYTE ie;
		
	ie = SREG & 0x80;
	cli();
	
	sbi(IODDR, IOBIT);	// output mode
	cbi(OUTPORT, IOBIT);		// start bit cell
	n = (xCLOCKS_PER_USEC * 2) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	if (bit_value)
		sbi(OUTPORT, IOBIT);	// sending a 1
	n = (xCLOCKS_PER_USEC * 70) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	sbi(OUTPORT, IOBIT);
	n = (xCLOCKS_PER_USEC * 4) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	if (ie)
		sei(); 
}
//--------------------------------------------------------------------------
// Read 1 bit of data from the 1-Wire bus
// Return 1 : bit read is 1
// 0 : bit read is 0
//
unsigned char OWReadBit()
{
	BYTE b, ie;
	register int n;

	ie = SREG & 0x80;
	cli();
	
	sbi(IODDR, IOBIT);			// make output
	cbi(OUTPORT, IOBIT);		// start bit cell
	n = (xCLOCKS_PER_USEC * 10) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	sbi(OUTPORT, IOBIT);		// for pull up
	cbi(IODDR, IOBIT);			// make input
	n = (xCLOCKS_PER_USEC * 5) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	b = INPORT & IOBITMASK;	// sample data
	n = (xCLOCKS_PER_USEC * 60) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	sbi(IODDR, IOBIT);			// make output, port bit is 1
	n = (xCLOCKS_PER_USEC * 10) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	if (ie)
		sei();		
	return(b != 0);	
}
//--------------------------------------------------------------------------
unsigned char OWReadByte(void)
{
	BYTE i, b = 0;
	
	cli();
	for (i = 8; i != 0; --i)  {
		b >>= 1;
		if (OWReadBit() != 0)
			b |= 0x80;
	}	
	sei();
	return b;
}
//////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------------
// Find the 'first' devices on the 1-Wire bus
// Return TRUE : device found, ROM number in ROM_NO buffer
// FALSE : no device present
//
int OWFirst(void)
{
	// reset the search state
	LastDiscrepancy = 0;
	LastDeviceFlag = FALSE;
	LastFamilyDiscrepancy = 0;
	return(OWSearch());
}

//--------------------------------------------------------------------------
// Find the 'next' devices on the 1-Wire bus
// Return TRUE : device found, ROM number in ROM_NO buffer
// FALSE : device not found, end of search
//
int OWNext(void)
{
	// leave the search state alone
	return(OWSearch());
}

//--------------------------------------------------------------------------
// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
// search state.
// Return TRUE : device found, ROM number in ROM_NO buffer
// FALSE : device not found, end of search
//
int OWSearch(void)
{
	unsigned char id_bit_number;
	unsigned char id_bit, cmp_id_bit;
	unsigned char rom_byte_mask, search_direction;
	int last_zero, rom_byte_number, search_result;

	// initialize for search
	id_bit_number = 1;
	last_zero = 0;
	rom_byte_number = 0;
	rom_byte_mask = 1;
	search_result = 0;
	crc8 = 0;
	
	// if the last call was not the last one
	if (!LastDeviceFlag)  {
		// 1-Wire reset
		if (!OWReset())  {		// <<< do a bus reset
			// reset the search
			LastDiscrepancy = 0;
			LastDeviceFlag = FALSE;
			LastFamilyDiscrepancy = 0;
			//OPEX_putline_P(PSTR("OWReset err"));
			return FALSE;
		}

		// issue the search command
		OWWriteByte(0xF0);

		// loop to do the search
		do  {
			// read a bit and its complement
			id_bit = OWReadBit();
			cmp_id_bit = OWReadBit();
			// check for no devices on 1-wire
			if ((id_bit == 1) && (cmp_id_bit == 1))	// means no response from bus
				break;
			else  {
				// all devices coupled have 0 or 1
				if (id_bit != cmp_id_bit)
					search_direction = id_bit; // bit write value for search
				else  {
					// if this discrepancy if before the Last Discrepancy
					// on a previous next then pick the same as last time
					if (id_bit_number < LastDiscrepancy)
						search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
					else

⌨️ 快捷键说明

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