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

📄 ds1820.c

📁 基于AVR的超声波测距程序
💻 C
字号:
#include <avr/io.h>
#include <avr/wdt.h>
#include <stdio.h>
#include <avr/delay.h>
#include <avr/signal.h>
#include "MyDef.h"
#include "ds1820.h"

const uchar CRC_Code[256]={    	//DS1820 CRC校验表
	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
}; 

uchar Init_DS1820(void)            //DS1820初始化
{
	uchar flg;
	SET_1820_DATOUT;
	CLR_1820_DAT; 
	delay_nus(500);    

	SET_1820_DATIN;            //输入 释放
	delay_nus(80);     
	if(CHECK_1820_DAT)          //等待回复
		flg = 0;       
	else
		flg = 1;        //0表示初始化成功 
	
    delay_nus(240);    //回复的低电平在60到240US

	SET_1820_DATOUT; 
	SET_1820_DAT;            //回到初始DQ=1;
	return flg; 
}

//-------------- 写DS1820温度 --------------------

void write_DS1820(uchar dat)   //写DS1820温度 
{
    uchar i; 
 	SET_1820_DATOUT;            //控制脚定义成输出  
    for(i=0;i<8;i++)  
		{  
			CLR_1820_DAT;
			delay_nus(5);  
			if(dat&1)        //写数据,从低位开始  
				{
					SET_1820_DAT;       // bit=1
				} 
			else
				{ 
					CLR_1820_DAT;       // bit=0
				}
			delay_nus(60);   // wait for 60us ,total > 60us
			SET_1820_DAT;          //再次拉高
			delay_nus(10);    //写两个位之间的间隔
			dat>>=1; 
		}  
    SET_1820_DAT;  
}

//--------------- 读DS1820温度 -------------------

uchar read_DS1820(void)   //读DS1820温度
{
	uchar i, dat=0;        // dat用于存储读到的数据
     
	SET_1820_DATOUT;               //第一次拉低,设置引脚为输出    
    for(i=0;i<8;i++)  
		{  
			dat>>=1;  
			CLR_1820_DAT;          
			delay_nus(5);    //拉低5微秒
              
			SET_1820_DATIN;          //定义成输入,读入状态
			delay_nus(5);    //等DS1820响应
			if(CHECK_1820_DAT)        //读状态,放入dat中
				{
					dat |=0x80;    //放到最高位,左移
				}		                
			delay_nus(80);   //wait for 60~120us 

			SET_1820_DAT;     
			SET_1820_DATOUT;         //再次定义成输出
        }  

   return dat;  
}
 
uchar DS1820CRCDETECT(void)
{
	uchar i;
    uchar rom64[8];
	uchar crc_temp=0;

	Init_DS1820();          //初始化,然后读出温度值
	write_DS1820(0xCC);     //发送ROM命令,不进行匹配 
	write_DS1820(0x4E);     //发送功能命令,写配置寄存器  
    write_DS1820(0x02);     // TH
	write_DS1820(0x80);     // TL
	write_DS1820(0x7F);     // Config  :0x1F:9位, 0x3F:10位 ,0x5F:11位 ,0x7F:12位
                          // 所需时间: 93.75ms   187.75ms    375ms      750ms
    Init_DS1820();          //初始化,然后读出温度值
	write_DS1820(0x33);     //发送ROM命令,读64-bit ROM 值 
	for(i=0;i<8;i++)
		{
			rom64[i]=read_DS1820(); 
		}

	crc_temp = CRC_Code[rom64[0]];   //算第一个CRC码 
	
	for(i=1;i<7;i++)           //后面的CRC码:I = (当前CRC) EXOR (输入字)
		{
			crc_temp =  CRC_Code[rom64[i]^crc_temp];
		}

	if(crc_temp == rom64[7])
		{
#ifdef Debug		
//			printf("\nDS1820 ROM CRC SUCCESS");
#endif		
			return 1;
		}

	else
		{
#ifdef Debug			
//			printf("\nDS1820 ROM CRC FAIL");
#endif		
		}
	return 0;
}


float GetTemperature(void)
{
	float temperature;
	ulong temp;
	uchar scr_pad[9];
	uchar crc_temp=0;
	uchar i=0;
	
	Init_DS1820();          //初始化DS1820
	write_DS1820(0xCC);     //发送ROM命令,不进行匹配 
	write_DS1820(0x44);     //启动DS1820进行转换  
        
	delay_nms(1000);	     //延时等转换完成

	Init_DS1820();          //初始化,然后读出温度值
	write_DS1820(0xCC);     //发送ROM命令,不进行匹配 
	write_DS1820(0xBE);     //发送功能命令,读出暂存寄存器中内容
		
	for(i=0;i<9;i++)
		{
			scr_pad[i]=read_DS1820();   //读出9位scratchpad 的值
		}

//----------下面校验读出的值是否正确---------------

	crc_temp = CRC_Code[scr_pad[0]];   //选算第一个CRC码 
			
	for(i=1;i<8;i++)          
		{
			crc_temp =  CRC_Code[scr_pad[i]^crc_temp];
		}

	if( crc_temp==scr_pad[8] ) //如果结果正确则显示
		{
     
			if(scr_pad[1]&0x08)
				{
           
					scr_pad[1]=~scr_pad[1];
					scr_pad[0]=~scr_pad[0];

					SREG=SREG&(~(1<<SREG_C));   //清零 C 进位
					scr_pad[0]++;
					if(SREG&(1<<SREG_C))        //如果有进位,则高位加1
						scr_pad[1]++;
				}

			temp = scr_pad[1];
			temp = (temp << 8) + scr_pad[0];

			temperature = temp*0.0625;       //得到真实十进制温度值,因为DSDS1820
	
#ifdef Debug	
//	printf("\nCurrent Temperature: %5.1f Degrees",temperature);
#endif	

		}
	else                    //结果不正确则提示错误
		{
			temperature = -100; // 用 -100表示 温度输出错误
#ifdef Debug			
//			printf("\nError Occured!!! Wrong Temperature"); 
#endif	
		}

	return temperature;

}

⌨️ 快捷键说明

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