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

📄 ds1820.c

📁 学完单片机就要使用实时系统在单片机上运行
💻 C
字号:
#include "OPEX.h"
// DS1820.c
// (C) 2004 Steve Childress stevech@san.rr.com
// this math works for CPU clocks 1MHz or more
// CPU clock at 6000000	  so  1/f = 0.16uSec = 160nsec
const int CLOCKS_PER_USEC = 1000 / 160; 	// 1000 nSec = 1uSec
// 8MHz  = 125ns
// 10Mhz = 100ns
// 16MHz = 62ns

#define IODDR 	DDRA
#define OUTPORT PORTA
#define INPORT  PINA
#define IOBIT 	7
#define IOBITMASK 0x80

void report(OPEX_TCB *);
extern char StringBuf1[];


///////////////////////////////////////////////
// this will loop for about 250 microseconds, normal conditions
int onew_presence_check(void)	// return 1 if presence of 1-wire chip(s) detected
{
	BYTE t;
	int ret = 0;

	t = 0;
	while ((INPORT & IOBITMASK) == 0)  // should go hi after RC chargeup
		if (++t == 0)
			goto err0;
	t = 0;
	while ((INPORT & IOBITMASK) != 0)   // should go low, presence pulse
		if (++t == 0)
			goto err0;
	t = 0;
	while ((INPORT & IOBITMASK) == 0)   // should go hi at end of 240us presence pulse
		if (++t == 0)
			goto err0;
	ret = 1;
err0:
	return(ret);
}

void *onew_reset_tcb;
////////////////////////////////////////////////
void onew_reset_end(OPEX_TCB *me)
{	
	cli();					// presence pulse comes soon
	sbi(OUTPORT, IOBIT); 	// unreset
	cbi(IODDR, IOBIT);		// pin is an input
	if (onew_presence_check())
		++me->state;
	sei();
	me->funcp = onew_reset_tcb;
	OPEX_sched_resched(me, 0, 0, 0, 0, 0);
}
////////////////////////////////////////////////
void onew_reset_begin(OPEX_TCB *me)
{
	sbi(IODDR, IOBIT);			// output mode
	cbi(OUTPORT, IOBIT);  		// begin the reset
	onew_reset_tcb = me->funcp;
	me->funcp = &onew_reset_end;
	OPEX_sched_resched(me, 0, 0, 0, 0, 1);
}



////////////////////////////////////////////////
void onew_sendbit(BYTE d)
{
	register int n;	// must be two bytes
	
	//cli();
	cbi(OUTPORT, IOBIT);		// start bit cell
	n = (CLOCKS_PER_USEC * 6) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	if (d)
		sbi(OUTPORT, IOBIT);	// sending a 1
	n = (CLOCKS_PER_USEC * 60) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	sbi(OUTPORT, IOBIT);
	n = (CLOCKS_PER_USEC * 1) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	//sei(); 
}

//////////////////////////////////////////////////		
void onew_send(BYTE b)
{
	BYTE i;
	
	sbi(IODDR, IOBIT);	// output mode
	cli();		// takes about 600 uSec for this loop
	for (i = 1; i != 0; i <<= 1)
		onew_sendbit( (b & i) != 0 );
	sei();
}

/////////////////////////////////////////////////
// receive one bit from one wire.
// caller should have turned off interrupts
BYTE onew_receivebit(void)
{
	BYTE b;
	register int n;


	sbi(IODDR, IOBIT);			// make output
	cbi(OUTPORT, IOBIT);		// start bit cell
	n = (CLOCKS_PER_USEC * 6) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	sbi(OUTPORT, IOBIT);		// for pull up
	cbi(IODDR, IOBIT);			// make input
	n = (CLOCKS_PER_USEC * 12) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;
	b = INPORT & IOBITMASK;
	n = (CLOCKS_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 = (CLOCKS_PER_USEC * 2) / 3;	// compile-time math
	while (--n)				//  delay, 3 clocks per loop iteration
		;		
	return(b != 0);		
}

/////////////////////////////////////////////////
BYTE onew_receive_byte(void)
{
	BYTE b = 0;
	BYTE i;
	
	cli();
	for (i = 8; i != 0; --i)  {
		b >>= 1;
		if (onew_receivebit() != 0)
			b |= 0x80;
	}	
	sei();
	return(b);
}





BYTE onew_data[9];
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

void DS1820(OPEX_TCB *me)
{
	union {
		int n;
		BYTE b[2];
	} temperature;
	
	BYTE t;
	char *p = NULL;
	
	sbi(IODDR, IOBIT);		// output
	sbi(OUTPORT, IOBIT);		// put a one on the bus, let it sit a while
		
	//report(me);
	switch(me->state)  {
		case 0:	
			++me->state;
			onew_reset_begin(me);	// skips next state if presence of chip(s) detected
			break;
		case 1:		
			goto err0;				// error condition
			break;
		case 2:	
			onew_send(0xcc);	// skip ROM, just one device
			++me->state;  
			OPEX_sched_resched(me, 0, 0, 0, 0, 1); 
			break;
		case 3:
			++me->state;
			onew_send(0x44);	// convert command	takes 750mSec
			OPEX_sched_now(me);
			OPEX_sched_resched(me, 0, 0, 0, 0, TicksPerSecond - (TicksPerSecond/4) ); 
			break;
		case 4:
			++me->state;
			onew_reset_begin(me);	// skips next state if presence of chip(s) detected
			break;
		case 5:
			goto err0;
			break;
		case 6:
			++me->state;
			onew_send(0xcc);	// skip ROM, just one device
			OPEX_sched_resched(me, 0, 0, 0, 0, 1); 
 			break;		
		case 7:	
			onew_send(0xBE);	// read scratchpad command	
			for (t = 0; t <= 8; ++t)
				onew_data[t] = onew_receive_byte();
			temperature.b[0] = onew_data[0];
			temperature.b[1] = onew_data[1];
			for (t = 0; t <= 8; ++t)  {
				sprintf_P(StringBuf1, PSTR(" %d 0x%X"), t, onew_data[t]);
				OPEX_puts(StringBuf1);
			}
			OPEX_nl();
			
			if (temperature.n >= 0)
				t = (temperature.n & 1) ? 5 : 0;
			else
				t = (temperature.n & 1) ? 0 : 5;		
			sprintf_P(StringBuf1, PSTR(" Temp: %d.%d C  0x%X"), temperature.n/2, t, temperature.n);
			OPEX_putline(StringBuf1);
			if (temperature.n >= 0)
				t = (temperature.n & 1) ? 5 : 0;
			else
				t = (temperature.n & 1) ? 0 : 5;
			// temperature LSB is 2**-1.   
			temperature.n = ((18 * temperature.n) / 10) + (32*2);  // mul by 10*1.8 divide by 10 add scaled 32
			sprintf_P(StringBuf1, PSTR(" Temp: %d.%d F  0x%X"), temperature.n/2, t, temperature.n);			
			OPEX_putline(StringBuf1);
			goto out;
			break;					
	}
	return;		// reenter, with state variable set

err0:
	sei();
	p = PSTR("onew presence err");
	
out:
	sbi(IODDR, IOBIT);
	sbi(OUTPORT, IOBIT);			// leave at 1
	if (p != NULL)
		OPEX_putline_P(p);
	me->state = 0;	
	//OPEX_sched_resched(me, 0, 0, 0, 3, 0);	// again later
	OPEX_sched_quit();
}

⌨️ 快捷键说明

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