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

📄 18b20.c

📁 基于AT91SAM7S64的温度计
💻 C
字号:
#include <AT91SAM7S64.H> 	   // AT91SAM7S64处理器的寄存器头文件
#include "lib_AT91SAM7S64.h"
#include "18B20.h"
#include "Board.h"

void delay_us(int n)
{
 unsigned char i;
 for(;n>0;n--)
 {
  for(i=0;i<10;i++)
  {;}
 }
}

/////////// 复位1-wire总线,并探测是否有温度芯片DS18B20挂在总线上////////////
int ds18b20_reset(void)  
{  
     int sdt;
	 unsigned char bus_flag;   //用来返回的标志位 
    DQ_TO_0;      
    AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);       
         DQ_1;
		 delay_us(1);
		 DQ_0; 
        delay_us(500);        //延时490us 
     
        DQ_1;          
        DQ_TO_1;      //设置1-wire总线为输入
  		AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);
           delay_us(67.5);    
         
    // 探测总线上是否有器件
	  sdt=*AT91C_PIOA_PDSR;    
    if(sdt&DQ_18B20)  
       { 
	    bus_flag=0;       // 复位单总线但没有发现有器件在线 
		AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,LED0); 
     	}
        else
		{ 
		 bus_flag=1;  // 复位单总线并发现有器件在线 
		 AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,LED1);
		 } 
        delay_us(490-67.5);  
         DQ_1;  
    return(bus_flag);  
}  

/////////// 写命令或数据到温度芯片DS18B20(发送一个字节)/////////// 
  
void ds18b20_write(unsigned char dat)  
{  
    unsigned char count;  

        DQ_TO_0;               // 设置1-wire总线为输出
        AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);
    // 每个字节共8位,一次发一位  
    for(count=0; count<8; count++) {   
        if(dat&0x01)  
                { 
				     delay_us(1); 	  
				     DQ_0; 
		            	delay_us(6);
				        DQ_1;
						 delay_us(62);  						 
                } 
                 
                else  
                {  
				   delay_us(1);
				   DQ_0; 
				    delay_us(62);
					DQ_1; 	           
                 } 
                dat >>= 1;
				AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,LED2); 
    }  
}  

///////////// 从温度芯片DS18B20读配置或数据(接收一个字节) //////////// 
unsigned char ds18b20_read(void)  
{  
    unsigned char  count,temp;
	int sdt;  
    temp = 0x00;                // 数据接收准备  
    for(count=0; count<8; count++) {        
         DQ_TO_0;
		 AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);             
        DQ_0;
		delay_us(2);
         DQ_1;  
		 	temp>>=1;     
                DQ_TO_1;    // 设置1-wire总线为输入
					AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20); 
                 delay_us(3);         
         		
                sdt=*AT91C_PIOA_PDSR;    
                if(sdt&DQ_18B20)
				{
	                 temp|=0x80;   // 读取总线电平,先收低位再收高位
					  
					 }  
                else 
				{
				temp&=0x7f;
        		 }
				 
                delay_us(62);  // 必须大于60us
				DQ_TO_0;
			
		 AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);
		 DQ_1;  
    }  
	AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,LED3);
    return temp;	   
}  
/////////////温度转换函数////////////////////// 
void convert_T(void)  
{  
    if(ds18b20_reset()==1) {     // 如果复位成功  
        ds18b20_write(0xcc);     // 跳过多器件识别  
        ds18b20_write(0x44);     // 启动温度转换  
    }  
}  

//////////////// 读取转换后的温度值 /////////////////////// 
unsigned int read_Tz(void)  
{  
    unsigned char a,b,temp; 
        volatile unsigned int t=0; 
      
    if(ds18b20_reset()==1) {           // 如果复位成功  
        ds18b20_write(0xcc);     // 跳过多器件识别  
        ds18b20_write(0xbe);     // 读暂存器  
        a = ds18b20_read();           //读取温度值低位 
        b = ds18b20_read();           //读取温度值高位 
    //前5位符号,温度大于0,这5位为0,值乘0.0625即得实际温度 
           //温度小于0,这5位为1,数值取反加1再乘0.0625即得实际温度 
        temp = b & 0x80; 
    if(temp == 0) 
        { 
                t = b << 4; 
				a=a>>4;
                t = t + a; 
        } 
        else 
        { 
                b = b & 0x07; 
                t = b << 8; 
                t = t + a; 
                t = ~t + 1; 
        } 
        t = t * 0.625;      
        return(t); 
        } 
} 

⌨️ 快捷键说明

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