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

📄 ds1820.c

📁 51单片机开发与应用技术详解(珍藏版)PPT及源码
💻 C
字号:
#include <stdio.h>						//头文件
#include <reg52.h>

#define FALSE 0
#define TRUE 1
#define uchar unsigned char				//预定义

sbit DS18S20_DQ = P2^0;                	//定义P2^0引脚为DS18S20的DQ引脚

/******************************* 全局变量声明 ********************************/
uchar DS18S20ROM[8];          			// DS18S20 ROM位
uchar LastData = 0; 
uchar EndFlag = 0; 
uchar ROMFound[5][8];  					// DS18S20的ROM 代码表
uchar numROMs;
uchar CRCdsc;							//用于CRC校验

uchar code dsc[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};


void Delay(int useconds) 
{
int s;
for (s=0; s<useconds;s++);				//空循环语句实现延时
}


uchar Reset(void) 
{
uchar PresenceSignal;
DS18S20_DQ = 0;  						//拉低数据线DQ
Delay(30); 							//延时
DS18S20_DQ = 1; 						//置数据线DQ为高电平
Delay(3); 								//延时
PresenceSignal = DS18S20_DQ; 			//读取存在信号
Delay(30); 							//延时,等待时间隙结束
return PresenceSignal; 					//返回存在信号
}



void WriteBit(char val) 
{
DS18S20_DQ = 0; 						//拉低数据线DQ开始写时间隙
if(val==1)
 DS18S20_DQ =1; 						//数据线DQ置1,写1 
else
 DS18S20_DQ=0;						//数据线DQ置0,写0
Delay(5); 								//延时,在时间隙内保持电平值,
DS18S20_DQ = 1; 						//拉高数据线DQ
}
	


void WriteByte(char val) 
{
uchar i;
uchar temp;
for (i=0; i<8; i++)						//循环写入字节,每次写入一位
{ 
temp = val>>i; 							//移位
temp &= 0x01; 		
WriteBit(temp); 						//调用位写入函数
}
Delay(5);
}


uchar ReadBit(void) 
{
uchar i;
DS18S20_DQ = 0;     		 			//拉低数据总线DQ开始读时间隙
DS18S20_DQ = 1; 						//DQ置1
for (i=0; i<3; i++); 						//延时
return DS18S20_DQ ; 					//返回数据总线DQ上的位数据
}

uchar ReadByte(void) 
{
uchar i;
uchar value = 0;
for (i=0;i<8;i++) 						//读取字节,每次读取一位
{
if(ReadBit()) 
value|=0x01<<i; 					//循环左移
Delay(7); 					
}
return(value);							//返回字节数据
}


void ReadROMSerialNumber(void) 
{
int n;
char dat[9];
printf("\nReading DS18S20 ROM Code\n");	//输出信息
Reset();								//复位函数
WriteByte(0x33);						//读出ROM序列号命令
for (n=0;n<8;n++)
{
dat[n]=ReadByte();						//循环读ROM序列号
}
printf("\nDS18S20 ROMCode=%X%X%X%X\n",//输出ROM序列号
dat[7],dat[6],dat[5],dat[4],dat[3],dat[2],dat[1],dat[0]);
}


uchar CRCCheck( uchar x) 
{
CRCdsc = dsc[CRCdsc^x];				//查表校验
return CRCdsc;
}

uchar SearchDevice(void) 
{
uchar m = 1; 							//DS18S20 ROM 位索引
uchar n = 0;   							//DS18S20 ROM 字节索引
uchar k = 1;    
uchar x = 0;
uchar discrepMarker = 0; 
uchar g;
uchar nxt; 
int flag;
nxt = FALSE; 			
CRCdsc = 0; 
flag = Reset(); 							//复位函数
if(flag||EndFlag) 						//如果没有其它器件
{									
LastData = 0; 	
return FALSE; 						//返回"假"
}
WriteByte(0xF0); 						//搜索ROM 命令
do 									//循环
{					
x = 0;
if(ReadBit()==1) x = 2;
Delay(8);
if(ReadBit()==1) x |= 1; 	
if(x ==3) break;
else 
{
if(x>0) 				
g = x>>1; 			
else 
{					
if(m<LastData) 
g = ((DS18S20ROM[n]&k)>0);
else 
g = (m==LastData); 
if (g==0) discrepMarker = m;
}
if(g==1) 
DS18S20ROM[n] |= k;
else 
DS18S20ROM[n] &= ~k;
WriteBit(g); 						//位写入函数
m++; 
k = k<<1; 
if(k==0) 
{ 
CRCCheck(DS18S20ROM[n]); 	//CRC校验
n++; k++;
}
}
}while(n<8); 							//直到全部ROM字节0~7都完成
if(m<65||CRCdsc)  
LastData=0; 
else 								//搜索成功
{									
LastData = discrepMarker; 			//置位LastData, lastOne和nxt
EndFlag = (LastData==0);
nxt = TRUE; 						//表示总线上还有其它器件,搜索未结束
}
return nxt;
}


uchar FindFirstDevice(void) 
{
LastData = 0; 
EndFlag = FALSE;
return SearchDevice(); 					//搜索器件函数SearchDevice
}



void ReadData(void) 
{
int j;
char pad[10];
printf("\nReading ScratchPad Data\n");
WriteByte(0xBE);						//读暂存器命令(代码为BEH)
for (j=0;j<9;j++)							//循环读取暂存器中9个字节的数据
{
pad[j]=ReadByte();						//字节读取函数
}
printf("\n ScratchPAD DATA =%X%X%X%X%X%X\n",
pad[8],pad[7],pad[6],pad[5],pad[4],pad[3],pad[2],pad[1],pad[0]);
}


void FindDevices(void) 
{
uchar m;
  if(!Reset()) 							//复位总线
{ 									//如果存在器件则开始处理
	if(FindFirstDevice()) 					//调用FindFirstDevice函数
{
		numROMs=0;
		do 							//循环
{
			numROMs++;
			for(m=0;m<8;m++) 
{						//识别ROM代码
				ROMFound[numROMs][m]=DS18S20ROM[m]; 
			}
		 printf("\nDS18S20 ROM CODE =%02X%02X%02X%02X\n",
		 ROMFound[5][7],ROMFound[5][6],ROMFound[5][5],ROMFound[5][4],
		 ROMFound[5][3],ROMFound[5][2],ROMFound[5][1],ROMFound[5][0]);
		 }while (SearchDevice()&&(numROMs<10)); //直到没有发现其它器件
  	}
  }
}



void ReadTemperature(void) 
{
char get[10];
char temp_lsb,temp_msb;
int k;
char Ftemperature,Ctemperature;
Reset();								//复位
WriteByte(0xCC); 						//跳过ROM序列号命令(代码为CCH)
WriteByte(0x44); 						//启动温度转换命令(代码为44H)
Delay(5);
Reset();
WriteByte(0xCC); 						//跳过ROM序列号命令(代码为CCH)
WriteByte(0xBE); 						//读暂存器命令(代码为BEH)
for (k=0;k<9;k++)
{
get[k]=ReadByte();						//循环读取
}
printf("\n Scratch DATA = %X%X%X%X%X\n",
get[8],get[7],get[6],get[5],get[4],get[3],get[2],get[1],get[0]);
temp_msb = get[1];
temp_lsb = get[0];
if (temp_msb <= 0x80)
{         
temp_lsb = (temp_lsb/2);    				//移位,得到完整的温度值
} 								
temp_msb = temp_msb & 0x80;     		//屏蔽符号位之外的所有数据位
if (temp_msb >= 0x80) 
{
temp_lsb = (~temp_lsb)+1; 				// temp_lsb取补
} 
if (temp_msb >= 0x80) 
{
temp_lsb = (temp_lsb/2);					//移位,得到完整的温度值
}
if (temp_msb >= 0x80) 
{
temp_lsb = ((-1)*temp_lsb); 				//符号位
} 
printf( "\nTempC= %d degrees C\n", (int)temp_lsb );//摄氏温度值输出
Ctemperature = temp_lsb; 
Ftemperature = (((int)Ctemperature)* 9)/5 + 32;
printf( "\nTempF= %d degrees F\n", (int)Ftemperature );//华氏温度值输出
}


void main(void) 
{
uchar Select_Menu; 					//功能选择

SCON=0x50;							//初始化串行口模式1
TMOD=0x20;							//初始化T1为定时功能,模式2
PCON=0x80;							//设置SMOD=1
TL1=0xF4;							//波特率4800bit/s,初值
TH1=0xF4;						 

  TR1 = 1;       						//启动T1
  TI = 1; 								//启动发送

  while(1)								//主循环
{ 						
  printf (" AT89S52 Control DS18S20\n");		//输出信息
  printf("\n*********************************************************\n");
  printf (" Select Control Menu Option\n");
  printf (" 1. Reset 1-Wire.\n");
  printf (" 2. Read DS18S20 ROM Code.\n");
  printf (" 3. Search DS18S20 ROM.\n");
  printf (" 4. Find All DS18S20.\n");
  printf (" 5. Read DS18S20 Scratch.\n");
  printf (" 6. Read DS18S20 Temperature.\n");
  printf (" 7. Exit.\n");
  printf (" Please Input Menu Option:\n");

	Select_Menu = _getkey(); 			//从键盘输入选择数字
	switch(Select_Menu)
{
		case '1': 						//复位1-Wire总线
			printf ("\n You Select 1. Reset 1-Wire\n");
			Reset();					//复位函数
			break;
		case '2': 						//读DS18S20 ROM
			printf ("\n You Select 2. Read DS18S20 ROM Code \n");
			Reset();
			ReadROMSerialNumber();	//读取ROM代码函数
			break;
		case '3': 						//搜索DS18S20
			printf("\n You Select 3. Search DS18S20 ROM \n");
			Reset();
			FindFirstDevice();			//搜索第一个器件
			printf("\nDS18S20 ROM CODE =%02X%02X%02X%02X\n",
			  ROMFound[5][7],ROMFound[5][6],ROMFound[5][5],ROMFound[5][4],
			  ROMFound[5][3],ROMFound[5][2],ROMFound[5][1],ROMFound[5][0]);
			break;
		case '4': 						//搜索所有DS18S20
			printf ("\n You Select 4. Find All DS18S20\n");
			Reset();
			FindDevices();				//查找器件函数
			break;
		case '5': 						//读取高速暂存器
			printf ("\n You Select 5. Read DS18S20 Scratch \n");
			Reset();
			WriteByte(0xCC); 			//跳过ROM序列号命令(代码为CCH)
			ReadData();				//读取高速暂存器
			break;
		case '6': 						//读取温度
			printf ("\n You Select 6. Read DS18S20 Temperatur\n");
			ReadTemperature(); 		//读取温度值
			break;
		case '7': 						//退出程序
			printf ("\n You Select 7. Exit\n");
			goto Exit; 				//转向Exit标号处
			break;
		default: 
printf ("\n Error: Please Select Right Menu Option\n");
			break;
		}; 
  }
Exit: printf("Exit the program!");				//退出
}

⌨️ 快捷键说明

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