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

AVR单片机的DS18B20 C语言程序

发布时间:2020-06-05 发布时间:
|
#include   
#include   
  
#define uchar unsigned char   
#define uint  unsigned int     
//   
#define     BIT_SET(a,b)    a|=(1<                                                                         
#define     BIT_CLR(a,b)    a&=~(1<//清零位a.b                                                                                     
#define     BIT_INV(a,b)    a^=(1< //翻转位a.b   
#define     BIT_STATUS(a,b) a&(1<  //读取位a.b   
   
/   
#define     CLR_DS18B20     BIT_CLR(PORTC,PC7)      //数据线强制拉低   
#define     SET_DS18B20     BIT_SET(PORTC,PC7)      //数据线强制拉高,上拉   
#define     HLD_DS18B20     BIT_SET(DDRC,PC7)       //Mega16控制总线   
#define     RLS_DS18B20     BIT_CLR(DDRC,PC7)           //释放总线   
#define     STU_DS18B20     BIT_STATUS(PINC,PC7)        //数据线的状态   
   
uchar const SEG7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};   
uchar const ACT[8]={0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10};   
uint T;   
//=============================   
void delayUs(uchar temp)   
{   
     while(temp--);   
}   
   
uchar resetDS18B20(void);   
unsigned int readTempDS18B20(void);   
 
void port_init(void)   
{   
 PORTA = 0xFF;   
 DDRA  = 0x00;   
 PORTB = 0xFF;   
 DDRB  = 0xFF;  //输出   
 PORTC = 0xFF;     
 DDRC  = 0xFF;  //输出    
 DDRD  = 0xFF;   
 PORTD = 0xFF;   
}   
void delay_ms(uint k)              
{   
    uint i,j;   
    for(i=0;i 
    {   
       for(j=0;j<570;j++);   
    }   
}   
//=============================   
void display(uchar counter)    
{                  
            uchar i;   
            DDRA=0xff;             
            DDRC=0xff;         
            PORTA=0x00;        
            PORTC=0xff;        
            for(i=0;i<100;i++)      
           {                       
           PORTA=SEG7[counter];     
           PORTC=ACT[3];               
           delay_ms(10);                   
           PORTA=SEG7[counter/10];     
           PORTC=ACT[2];   
           delay_ms(10);               
           PORTA=SEG7[counter/100];    
           PORTC=ACT[1];           
           delay_ms(10);   
           PORTA=SEG7[counter/1000];       
           PORTC=ACT[0];           
           delay_ms(10);   
                       
           }                       
}                             
void main()   
{   
   
    port_init();   
       
   
    while(1)   
    {   
            resetDS18B20();   
            T=readTempDS18B20();   
            T=T>>4;                       //去除ds18b20转换的小数位(低四位)   
            display(T);   
    }   
}   
   
[page]
   
/   
uchar resetDS18B20(void)   
{   
    uchar errTime=0;   
    RLS_DS18B20;        //释放总线   
    _NOP();   
    HLD_DS18B20;        //Maga16控制总线   
    CLR_DS18B20;        //强制拉低   
    delayUs(255);       //209.42us   
    delayUs(255);       //209.42us   
    delayUs(255);       //83.28us   
    //以上的三个延时大于480us   
    RLS_DS18B20;        //释放总线,总线自动上拉   
    _NOP();            
    while(STU_DS18B20)     
    {   
        delayUs(4);     //5.15us   
        errTime++;   
        if(errTime>20)   
        return(0x00);       //如果等待大于约 5.15us*20就返回0x00,报告复位失败(实际上只要等待15-60us)   
    }   
    errTime=0;   
    while(!(STU_DS18B20))      
    {   
        delayUs(4);     //5.15us   
        errTime++;   
        if(errTime>50)   
        return(0x00);       //如果等带大于约 5.15us*50就返回0x00,报告复位失败(实际上只要等待60-240us)   
    }   
    return(0xff);   
}   
   
   
/   
uchar readByteDS18B20(void)   
{   
    uchar i;   
    uchar retVal=0;   
    RLS_DS18B20;        //释放总线   
    for(i=8;i>0;i--)   
    {   
        retVal>>=1;   
        HLD_DS18B20;    //Maga16控制总线   
        CLR_DS18B20;    //强制拉低   
        NOP();   
        NOP();   
        NOP();   
        NOP();   
        NOP();   
        NOP();   
        NOP();     
        NOP();          //延时大于1us      
        RLS_DS18B20;        //释放总线,DS18B20会将总线强制拉高   
        NOP();   
        NOP();   
        NOP();   
        if(STU_DS18B20)   
        retVal|=0x80;   
        delayUs(16);        //14.92us   
        delayUs(16);        //14.92us   
        RLS_DS18B20;        //释放总线   
        delayUs(35);        //30.38us   
    }   
    delayUs(1);         //2.71us(大于1us就行了)   
    return(retVal);   
}   
   
   
/   
void writeByteDS18B20(uchar wb)   
{   
    uchar i;   
    uchar temp;   
    RLS_DS18B20;        //释放总线   
    for(i=0;i<8;i++)   
    {   
        HLD_DS18B20;        //Maga16控制总线   
        CLR_DS18B20;        //强制拉低   
        delayUs(16);        //14.92us   
        temp=wb>>i;   
        temp&=0x01;   
        if(temp)   
        RLS_DS18B20;        //释放总线   
        else   
        CLR_DS18B20;        //强制拉低   
        delayUs(16);        //14.92us   
        delayUs(35);        //30.38us   
        RLS_DS18B20;        //释放总线   
        delayUs(1);         //2.71us(大于1us就行了)   
    }   
}   
   
/   
unsigned int readTempDS18B20(void)   
{   
    uchar tempL,tempH;   
    uint x;   
    resetDS18B20();   
    writeByteDS18B20(0xcc);     //跳过ROM   
    writeByteDS18B20(0x44);     //启动温度转换   
    delayUs(1);   
    resetDS18B20();   
    writeByteDS18B20(0xcc);     //跳过ROM   
    writeByteDS18B20(0xbe);     //读数据   
    tempL=readByteDS18B20();   
    tempH=readByteDS18B20();   
    x=(tempH<<8)|tempL;   
    return(x);   
}



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

热门文章 更多
如何为单片机选择合适的负载电容