×
单片机 > 单片机程序设计 > 详情

M16温度传感器DS18B20控制示例程序

发布时间:2020-06-04 发布时间:
|

//DS18b20的C语言驱动程序,三位数码管显示,读取当前环境温度,精度达0.1度,温度范围0-99度 
//DS18B20 详细引脚功能描述1、GND 地信号;2、DQ数据输入出引脚。开漏单总线接口引脚。当被用在寄生电源下 
//也可以向器件提供电源;3、VDD可选择的VDD 引脚。当工作于寄生电源时,此引脚必须接地。 
//DS18B20 的使用方法。DS18B20 采用的是1-Wire 总线协议方式 

//即在一根数据线实现数据的双向传输 
//编译环境 AVR Studio 4.13/AVR GCC 
//系统时钟7.3728MHz,设置熔丝位为外部高频石英晶体振荡,启动时间4.1ms  
//*********************************************************************** 
//   包含文件 
//*********************************************************************** 

#include  
#include  
#define  F_CPU 7372800  //  单片机 主频为7.3728MHz,用于延时子程序 
#include  
#include  
#include  
#include      //中断信号头文件 

//*********************************************************************** 
//   定义变量区 
//   CH451各个功能命令值,根据需要写入 
//*********************************************************************** 
#define CH451_RESET     0x0201                  //复位 
#define CH451_LEFT MOV    0x0300          //设置移动方式-作移 
#define CH451_LEFTCYC   0x0301          //设置移动方式-左循 
#define CH451_RIGHT MOV   0x0302          //设置移动方式-右移 
#define CH451_RIGHTCYC  0x0303          //设置移动方式-右循  
#define CH451_SYSOFF    0x0400                  //关显示、键盘、看门狗 
#define CH451_SYSON1    0x0401                  //开显示 
#define CH451_SYSON2    0x0403                  //开显示、键盘 
#define CH451_SYSON3    0x0407                  //开显示、键盘、看门狗功能 
#define CH451_DSP       0x0500                  //设置默认显示方式 
#define CH451_BCD       0x0580                  //设置BCD译码方式 
#define CH451_TWINKLE   0x0600          //设置闪烁控制 
#define CH451_DIG0      0x0800                  //数码管位0显示 
#define CH451_DIG1      0x0900          //数码管位1显示  
#define CH451_DIG2      0x0a00           //数码管位2显示 
#define CH451_DIG3      0x0b00           //数码管位3显示 
#define CH451_DIG4      0x0c00           //数码管位4显示 
#define CH451_DIG5      0x0d00                 //数码管位5显示  
#define CH451_DIG6      0x0e00                 //数码管位6显示  
#define CH451_DIG7      0x0f00              //数码管位7显示 

#define LED0  0x0000  //数码管位0显示的数据 
#define led1  0x0000         //数码管位0显示的数据;0x0010为不亮 
#define led2  0x0000  //数码管位0显示的数据 
#define led3  0x0010  //数码管位0显示的数据 
#define led4  0x0010  //数码管位0显示的数据 
#define led5  0x0010  //数码管位0显示的数据 
#define led6  0x0010  //数码管位0显示的数据 
#define led7  0x0010  //数码管位0显示的数据 

#define dclk0          PORTD &= ~(1 <#define dclk1          PORTD |= (1 <#define din0           PORTD &= ~(1 <#define din1           PORTD |= (1 <#define load0          PORTD &= ~(1 <#define load1          PORTD |= (1 <
#define DQ_IN         DDRC &= ~(1 <#define DQ_OUT         DDRC |= (1 <#define DQ_CLR         PORTC &= ~(1 <电平 
#define DQ_SET         PORTC |= (1 <#define DQ_R         PINC & (1 <

#define delay_us(x)     _delay_us(x)    //AVR GCC延时函数 x(us) 
#define delay_ms(x)     _delay_ms(x)    //AVR GCC延时函数 x(ms) 

#define uchar           unsigned char 
#define uint            unsigned int 
uint value; 
uint temp,A1,A2,A3;                     //定义的变量,显示数据处理 
uchar flag1;             
uchar table[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06, 
               0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d, 
     0x0e,0x0f}; //数码管的BCD码 


//************************************************************************* 
//   初始化子程序 
//************************************************************************* 

void system_init() 


SFIOR=(1<<2)|SFIOR;                      //PUD=1;关闭上拉电阻 
PORTD=0x70; 
DDRD=0x70; 



void ch451_init() 

  din0;                         //先低后高,选择4线输入 
  din1; 


//************************************************************************* 
//  输出命令子程序 
//  定义一无符号整型变量存储12字节的命令字 
 //************************************************************************ 
  void ch451_write(unsigned int command) 

  unsigned char i; 
  load0;                                  //命令开始        
  for(i=0;i<12;i++) 
   {                               //送入12位数据,低位在前 
      
     if(command&1) 
  { 
    din1; 

  } 
  else 
    din0;  
     dclk0; 
     dclk1;                              //上升沿有效 
     command>>=1;                                 
   } 
     load1;                              //加载数据 



//************************************************************************* 
//   显示函数 
//************************************************************************* 
void display(uint b_d,uint s_d,uint g_d) 

 ch451_init(); 
 ch451_write(CH451_SYSOFF);  //关显示、键盘、看门狗 
 ch451_write(CH451_SYSON1);   //开显示 
 ch451_write(CH451_BCD);   //设置BCD译码方式 
 ch451_write(CH451_TWINKLE);  //设置闪烁控制  

 ch451_write(CH451_DIG0|table[b_d]);         //显示百位数据 
 ch451_write(CH451_DIG1|table[s_d]|0x80); //显示十位数据 
 ch451_write(CH451_DIG2|table[g_d]);  //显示个位数据  
 ch451_write(CH451_DIG3|led3);       //其他数码管不显示,熄灭状态 
 ch451_write(CH451_DIG4|led4); 
 ch451_write(CH451_DIG5|led5); 
 ch451_write(CH451_DIG6|led6); 
 ch451_write(CH451_DIG7|led7); 



  
//*************************************************************************  
//   DS18B20初始化 
//************************************************************************* 

unsigned char ds1820_reset(void)                 //初始化和复位 


unsigned char i; 
        DQ_OUT; 
 DQ_CLR; 
 delay_us(500);    //延时500uS(480-960) 
 DQ_SET; 
 DQ_IN; 
 delay_us(80);    //延时80uS 
 i = DQ_R; 
 delay_us(500);    //延时500uS(保持>480uS) 
  
 if (i)  
        { 
  return 0x00; 
   
        } 
 else  
        { 
  return 0x01; 
   
        } 




//*************************************************************************  
//   DS18B20读一个字节函数 
//*************************************************************************  
    
unsigned char ds1820_read_byte(void)  


 unsigned char i; 
 unsigned char value = 0; 
 for (i = 8; i != 0; i--)  
        { 
  value >>= 1; 
  DQ_OUT; 
  DQ_CLR; 
                delay_us(4);    //*延时4uS 
   
  DQ_SET; 
  DQ_IN; 
                delay_us(10);    //*延时10uS 
   
  if (DQ_R)  
                { 
   value|=0x80; 
    
                } 
  delay_us(60);          //*延时60uS 
   
        } 
  
 return(value); 


//*************************************************************************  
//   向18B20写一个字节函数 
//*************************************************************************   

/*DS18B20字节写入函数*/ 
void ds1820_write_byte(unsigned char value)  


 unsigned char i; 
 for (i = 8; i != 0; i--)  
        { 
  DQ_OUT; 
  DQ_CLR; 
                delay_us(4);   //延时4uS 
  if (value & 0x01)  
                { 
   DQ_SET; 
    
                } 
  delay_us(80);   //延时80uS 
  DQ_SET;           //位结束 
  value >>= 1; 
   
        } 
  

//************************************************************************* 
//    发送温度转换命令 
//*************************************************************************  

/*启动ds1820转换*/ 
void ds1820_start(void) { 

 ds1820_reset(); 
 ds1820_write_byte(0xCC); //勿略地址 
 ds1820_write_byte(0x44); //启动转换 


//************************************************************************* 
//    DS8B20读取温度信息 
//*************************************************************************  

unsigned int ds1820_read_temp(void)  


 unsigned int i; 
 unsigned char buf[9]; 

 ds1820_reset(); 
 ds1820_write_byte(0xCC); //勿略地址 
 ds1820_write_byte(0xBE); //读取温度 
 for (i = 0; i         { 
  buf[i] = ds1820_read_byte(); 
   
        } 
 i = buf[1]; 
 i <<= 8; 
 i |= buf[0]; 
 value=i; 
        value=value*0.625;    //不是乘以0.0625的原因是为了把小数点后一位数据也转化为可以显示的数据 
                          //比如温度本身为27.5度,为了在后续的数据处理程序中得到BCD码,我们先放大到275 
                                        //然后在显示的时候确定小数点的位置即可,就能显示出27.5度了 
        //value=value*10; 
 return i; 


  

//************************************************************************* 
//  温度数据处理函数 
//************************************************************************* 
 void data_do(uint d) 
 { 
     uint A2t; 
     A1=d/100;                       //分出百,十,和个位 
     A2t=d%100; 
     A2=A2t/10; 
     A3=A2t%10; 


//************************************************************************* 
//   主程序 
//************************************************************************* 

void main(void) 


 DDRC = 0x00; 
 PORTC = 0xFF; 
 system_init();                         //系统初始化 
 delay_ms(250);  
 ds1820_reset();         //复位D18B20 
 while (1) 
        { 
  ds1820_start();         //启动一次转换 
  delay_ms(300);   //等待转换结束 
  ds1820_read_temp();  //读取温度数值 
        data_do(value);            //处理数据,得到要显示的值 
     display(A1,A2,A3);              //显示温度值 
     delay_ms(1000);                 //延时1S 
   
        } 




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32中断向量表的位置.重定向