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

📄 ds18b20.c

📁 这是一个有关C8051F020单片机的实验教学材料,相信对于单片机的研究人员会有很大的帮助.
💻 C
字号:
/*
	数字温度传感器DS18b20试验

	试验准备:用连接线将JH端子的DS12B80位与CN7或CN8的P37口相连
	运行此程序,温度值将在数码管上显示.用手触摸T1芯片(DS18B20)
	观察温度变化.

*/

#include <c8051f020.h>                    // SFR declarations
#include <intrins.h>

#define  WRITE       0x00                 // WRITE direction bit
#define  READ        0x01                 // READ direction bit

#define  CHIP_B      0x70
#define  SMB_START      0x08              // (MT & MR) START transmitted
#define  SMB_RP_START   0x10              // (MT & MR) repeated START
#define  SMB_MTADDACK   0x18              // (MT) Slave address + W transmitted;
                                          //  ACK received
#define  SMB_MTADDNACK  0x20              // (MT) Slave address + W transmitted;
                                          //  NACK received
#define  SMB_MTDBACK    0x28              // (MT) data byte transmitted; ACK rec'vd
#define  SMB_MTDBNACK   0x30              // (MT) data byte transmitted; NACK rec'vd
#define  SMB_MRADDACK   0x40              // (MR) Slave address + R transmitted;
                                          //  ACK received
#define  SMB_MRADDNACK  0x48              // (MR) Slave address + R transmitted;
                                          //  NACK received
#define  SMB_MRDBNACK   0x58              // (MR) data byte rec'vd; NACK transmitted
//-----------------------------------------------------------------------------------
//Global VARIABLES
//-----------------------------------------------------------------------------------

char COMMAND;                             // Holds the slave address + R/W bit for
char COMMAND1;                                          // use in the SMBus ISR.

char WORD;                                // Holds data to be transmitted by the SMBus
unsigned char totalnumber,sendnumber;                               // OR data that has just been received.

unsigned char xdata SENDMODE;                                         // that has just been received.


bit SM_BUSY;                              // This bit is set when a send or receive
                                          // is started. It is cleared by the
                                          // ISR when the operation is finished.

sbit DataPortDS1820 = P3^5;

unsigned char wr_data[8];
unsigned char rd_data[8];

void Delay1us(unsigned char us)
{
	while (us)
	{
		_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
		--us;
	}

/*
   TCON  &= ~0xc0;              // STOP Timer1 and clear overflow flag
   TMOD  &= ~0xf0;              // configure Timer1 to 16-bit mode
   TMOD  |=  0x10;
   CKCON |=  0x10;              // Timer1 counts SYSCLKs

   TR1 = 0;                     // STOP Timer1
   TH1 = (-SYSCLK/us) >> 8;		// set Timer1 to overflow in us
   TL1 = -SYSCLK/us;
   TR1 = 1;         			// START Timer1
   while (TF1 == 0);            // wait for overflow
   TF1 = 0;                     // clear overflow indicator
*/
}

void Delay15us(void)  
{
	Delay1us(15);
}


void Delay10us(void)
{	
	Delay1us(10);
}

bit RstDS1820(void)		//返回0-有设备连接1-无设备连接
{
	unsigned char i;
	bit RstFlag;
	RstFlag=1;	
	DataPortDS1820=0;
	for (i=0;i<100/*40*/;i++)	//480us
		Delay15us(); 
	DataPortDS1820=1;
	for(i=0;i<4;i++)			//15us-60us
	{
		Delay15us();
	}
	for (i=0;i<16;i++)			//60us-240us
	{
		Delay15us();
		if (DataPortDS1820==0) RstFlag=0;
	}
	for (i=0;i<16;i++)			//240us
	{
		Delay15us();
	}
	return RstFlag;	
}

void WriteDS1820(unsigned char ch)
{
unsigned char i;
	DataPortDS1820=1;
	Delay1us(1);
	for (i=0;i<8;i++)
	{
		EA=0;
		DataPortDS1820=0;
		Delay15us();
		DataPortDS1820=ch&0x1;
		EA=1;
		Delay15us();Delay15us();Delay15us();
		DataPortDS1820=1;
		ch=ch>>1;
		Delay1us(1);
	}
}

unsigned char ReadDS1820(void)
{
	unsigned char i,ch;
	ch=0;
	DataPortDS1820=1;
	Delay1us(1);
	for (i=0;i<8;i++)
	{
		EA=0;
		DataPortDS1820=0;
		Delay10us();
		DataPortDS1820=1;
		Delay1us(2);
		ch=ch>>1;
		if (DataPortDS1820==1)
		{
			ch=ch+0x80;
		}
		EA=1;
		Delay15us();Delay15us();Delay15us();
	}	
	return ch;
}

void SkipROMCode(void)
{
	RstDS1820();
	WriteDS1820(0xcc);
}
void StartADC(void)
{

	RstDS1820();			//复位
	WriteDS1820(0xcc);		//广播
	WriteDS1820(0x44);		//启动AD转换 12bit700ms
}

unsigned int GetTempValue(void)
{
	unsigned char i,j;
	unsigned int T;
	SkipROMCode();
	WriteDS1820(0xBE); 
	i=ReadDS1820();
	j=ReadDS1820();
	StartADC();
	T=i+j*256;
	if (T==0xffff) return 0xffff;
	if (T>0x8000) 
	{
		T=-T;
		return(0x8000+T*5/8);
	}
	else
		return(T*5/8);
}

void sleep_ms(unsigned int count)
{
	unsigned char ii,jj;
	for(ii=0;ii<count;ii++)
	{
		for(jj=0;jj<250;jj++)
		_nop_();
	}
}


void SYSCLK_Init (void)
{
	int i;								// delay counter
	OSCXCN = 0x67;						// start external oscillator with
										// 18.432MHz crystal
	for (i=0; i < 256; i++);			// Wait for osc. to start up
	while (!(OSCXCN & 0x80));			// Wait for crystal osc. to settle
	OSCICN = 0x88;						// select external oscillator as SYSCLK
										// source and enable missing clock
										// detector
	//OSCICN = 0x07;					//interal 16MHZ
}

void PORT_Init (void)
{
	XBR0    = 0x07;                     // Enable SMBus, SPI0, and UART0
	XBR2	= 0x44;						// Enable crossbar and weak pull-ups
	P0MDOUT	= 0x15;
}

void SLA_SEND(char chip_select, char *wr_data, char number)
{
   SENDMODE=0x01;
   totalnumber=number;
   sendnumber=number;
   while(SM_BUSY);                        // Wait while SMBus is busy.
   SM_BUSY = 1;                           // SMBus busy flag set.
   SMB0CN = 0x44;                         // SMBus enabled, ACK low.
   COMMAND = (chip_select | WRITE);       // COMMAND = 7 address bits + WRITE.
   //OP_CODE = out_op;                      // WORD = OP_CODE to be transmitted.
   //WORD = out_data;                       // DATA = data to be transmitted.
   STO = 0;
   STA = 1;                               // Start transfer.
	while(SM_BUSY);   
}

void Init18b20(void)
{
	SkipROMCode();
	WriteDS1820(0x4e);
	WriteDS1820(38);
	WriteDS1820(20);
	WriteDS1820(0x7f);
}

void main (void) 
{
	unsigned char temp;
	unsigned int w;
   unsigned char data Number[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
	WDTCN = 0xde;
	WDTCN = 0xad;           //关看门狗
	SYSCLK_Init ();         //初始化时钟
	PORT_Init ();           //初始化IO口
	Init18b20();
   SMB0CN = 0x44;                         // Enable SMBus with acknowledge low (AA = 1)
   SMB0CR = -80;                          // SMBus clock rate = 100 kHz
   //SMB0ADR = MY_ADD;                      // Set own slave address.
   EIE1 |= 2;                             // SMBus interrupt enable
   SM_BUSY = 0;                           // Free bus for first transfer.
   SI = 0;
	EA=1;					//开中断
	for (;;)
	{
		sleep_ms(250);
		sleep_ms(250);
		sleep_ms(250);
		w = GetTempValue();
		wr_data[0] = 0x00;
		wr_data[1] = 0x17;
		wr_data[2] = 0x00;
		temp = (w%1000)/100;
		wr_data[3] = Number[temp];
		temp = (w%100)/10;
		wr_data[4] = Number[temp]|0x80;
		temp = (w%10);
		wr_data[5] = Number[temp];
		SLA_SEND(CHIP_B,wr_data,0x06);
		sleep_ms(250);
		sleep_ms(250);
		_nop_();
		sleep_ms(250);
		sleep_ms(250);
	}
}

//------------------------------------------------------------------------------------
// SMBus Interrupt Service Routine
//------------------------------------------------------------------------------------

void SMBUS_ISR (void) interrupt 7
{
   switch (SMB0STA){                    // Status code for the SMBus 
                                        // (SMB0STA register)

      // Master Transmitter/Receiver: START condition transmitted.
      // Load SMB0DAT with slave device address.  Mask out R/W bit since all transfers
      // start with an OP_CODE write.
      case SMB_START:	//0x08
         SMB0DAT = COMMAND ;			// Load address of the slave to be accessed.
                                        // Mask out R/W bit because first transfer
                                        // will always be a write of the OP_CODE.
         STA = 0;                       // Manually clear STA bit
         SI = 0;                        // Clear interrupt flag
         break;

      // Master Transmitter/Receiver: Repeated START condition transmitted.
      // This state only occurs during a READ, after the OP_CODE has been sent.  Load
      // device address + READ into SMB0DAT.
      case SMB_RP_START:	//0x10
         SMB0DAT = COMMAND1;
         STA = 0;                       // Manually clear START bit.
         SI = 0;
         break;

      // Master Transmitter: Slave address + WRITE transmitted.  ACK received.
      // Load OP_CODE into SMB0DAT.
      case SMB_MTADDACK:	//0x18
         SMB0DAT = wr_data[0];
         SI = 0;                        // Clear interrupt flag
         break;

      // Master Transmitter: Slave address + WRITE transmitted.  NACK received.
      // The slave is not responding.  Use ACK polling to retry.
      case SMB_MTADDNACK:	//0x20
         STO = 1;
         STA = 1;
         SI = 0;                        // Clear interrupt flag
         break;

      // Master Transmitter: Data byte transmitted.  ACK received.
      // Check OP_CODE - If it is a READ code, send repeated START to begin
      // read.  If it is a WRITE code, load WORD into SMB0DAT for transfer.
      // If it is not a valid code, then either 1) data has been transmitted
      // and the transfer is finished, or 2) there is an error.  In either case,
      // send STOP and end transfer.
      case SMB_MTDBACK:		//0x28
         switch (SENDMODE){         	// Check only lower 4 bits.

            // OP_CODE is a READ.  Send repeated START.
            case 1:
			   sendnumber--;
			   if(sendnumber)
			   SMB0DAT = wr_data[totalnumber-sendnumber];
			   else{
			   		STO=1;
				   	SM_BUSY=0;
				}

               //OP_CODE = 0;               // Clear OP_CODE so transfer ends the next
               break;                     // time this state occurs 
            case 0:
			     STO = 0;
               STA = 1;
               break;                          // (after data is sent).

		
            default:                      // No valid OP_CODE.  End transfer.
               STO = 1;
               SM_BUSY = 0;
               break;
         }
         SI = 0;
         break;

      // Master Transmitter: Data byte transmitter.  NACK received.
      // Use ACK polling to retry transfer.
      case SMB_MTDBNACK:	//0x30
         STO = 1;
         STA = 1;
         SI = 0;                          // Clear interrupt flag
         break;

      // Master Receiver: Slave address + READ transmitted.  ACK received.
      // Set to transmit NACK after next transfer since it will be the 
      // last (only) byte.
      case SMB_MRADDACK:	//0x40
         
		 AA = 0;                          // NACK sent during acknowledge cycle.
         SI = 0;
         break;

      // Master Receiver: Slave address + READ transmitted.  NACK received.
      // Slave not responding. Send repeated START to try again.
      case SMB_MRADDNACK:	//0x48
         STO = 0;
         STA = 1;
         SI = 0;
         break;

      // Master Receiver: Data byte received.  NACK transmitted.
      // Read operation has completed.  Read data register and send STOP.
      case SMB_MRDBNACK:	//0x58
         rd_data[0] = SMB0DAT;
         STO = 1;
         SM_BUSY = 0;
         AA = 1;                          // Set AA for next transfer
         SI = 0;
         break;

      // All other status codes invalid.  Reset communication.
      default:
         STO = 1;
         SM_BUSY = 0;
         break;
      }

}


⌨️ 快捷键说明

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