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

📄 temprature.c

📁 利用C8051F单片机控制DS18B20温度传感器
💻 C
字号:
#include "C8051F330.h"
//晶振11.0592MHz
#define TRUE 1
#define FALSE 0
#define ADC0START ADC0CN|=0x10;

sbit lamp=P0^7;
sbit DQ=P0^6;
sbit setHigh=P0^4;
sbit setLow=P0^5;
sbit nowHigh=P1^2;
sbit nowLow=P1^3;
sbit null1=P0^1;
sbit null2=P1^0;

unsigned char n,a=0;
unsigned char tempratureSet=0x00,tempratureNow=0x00;

bit isnewdata;
unsigned int kk=0;
float temp=0.0;
float count=0.0;

void initial(void);
void timer_init(void);
void adc0_Rx(void);//对滑动变阻器采样
void delayus(unsigned int x);
void displaySet(unsigned char tempr);//显示设定温度
void displayNow(unsigned char tempr);//显示当前温度
void init_18B20(void);//初始化18B20
void write_18B20(unsigned char x);//向18B20写数据
unsigned char read_18B20(void);//读取18B20数据

void main(void)
{
    float sumTemp=0.0;
    unsigned char index=0;
    initial();
    timer_init();
    isnewdata=0;
    lamp=FALSE;
    null1=FALSE;
    null2=FALSE;

    while(1)
    {
        adc0_Rx();
        ADC0START;
        if(isnewdata)
    	{
            isnewdata=0;
            delayus(1000);
            kk=ADC0H*256;
            kk+=ADC0L;
            ADC0H=0x00;
            ADC0L=0x00;
            temp=(float)kk/1024.0;
            temp*=100;
            sumTemp+=temp;
            index++;
    	}
        if(10==index)
    	{
            tempratureSet=(unsigned char)(sumTemp/10.0);
            sumTemp=0.0;
            index=0;
    	}
        if(tempratureSet>=tempratureNow)
            lamp=TRUE;
        else
            lamp=FALSE;
    }
}

void delayus(unsigned int x)
{ 
    while(x)
    {
        x--;
    }
}

void initial(void)
{
    PCA0MD=0x00;//禁用看门狗

    P0MDIN=0xF3;
    P0MDOUT=0xBF;
    P0SKIP=0x2D;
    lamp=FALSE;

    tempratureSet=0x00;
    tempratureNow=0x00;

    P1MDIN=0xFC;
    P1MDOUT=0xFF;
    P1SKIP=0x03;//跳过ADC

    XBR0=0x00;
    XBR1=0x40;
    
    //*/使用内部高频时钟
    OSCICL=0xFF;
    OSCICN=0x80;//系统时钟15/8M
    CLKSEL=0x00;
    //*/
    //*/切换到外部振荡器
    OSCXCN=0x67;
    for(n=0;n<255;n++);
    while(0==(OSCXCN&0x80))
    {
    }
    CLKSEL=0x01;//外部振荡器
    OSCICN=0x00;
    //*/
    //初始化ADC0
    AMX0N=0x11;//选择GND为负输入,ADC0工作在单端方式
    ADC0CF=0xB8;//采样频率1M,0x58,2M
    ADC0CN=0x80;//当ADC0CN|=0x10的时候启动ADC0
    REF0CN=0x07;//内部电压基准
    //
    IE=0x8A;
    EIE1=0x0C;//开ADC中断

    setHigh=FALSE;
    setLow=FALSE;
    nowHigh=FALSE;
    nowLow=FALSE;
}

void timer_init(void)
{
    TL0=0x00;
    TH0=0x00;
    TL1=0xF0;
    TH1=0xFF;
    TMOD=0x11;//T0,T1,16位定时器
    CKCON=0x01;//系统时钟1/4
    TCON=0x50;//启动T0,T1
}

void adc0_Rx(void)
{
    AMX0P=0x09;//选择滑动变阻器为正输入
}

void displaySet(unsigned char tempr)
{
    unsigned char tempHigh,tempLow;
    tempHigh=(unsigned char)tempr/10;
    tempLow=tempr%10;
    tempHigh<<=4;
    tempHigh|=0x0F;
    tempLow<<=4;
    tempLow|=0x0F;

    nowHigh=TRUE;
    nowLow=TRUE;

    setHigh=FALSE;
    setLow=TRUE;
    P1|=0xF0;
    P1&=tempHigh;
    delayus(4000);
    setHigh=TRUE;

    setHigh=TRUE;
    setLow=FALSE;
    P1|=0xF0;
    P1&=tempLow;
    delayus(4000);
    setLow=TRUE;
}

void displayNow(unsigned char tempr)
{
    unsigned char tempHigh,tempLow;
    tempHigh=(unsigned char)tempr/10;
    tempLow=tempr%10;
    tempHigh<<=4;
    tempHigh|=0x0F;
    tempLow<<=4;
    tempLow|=0x0F;

    setHigh=TRUE;
    setLow=TRUE;

    nowHigh=FALSE;
    nowLow=TRUE;
    P1|=0xF0;
    P1&=tempHigh;
    delayus(4000);
    nowHigh=TRUE;

    nowHigh=TRUE;
    nowLow=FALSE;
    P1|=0xF0;
    P1&=tempLow;
    delayus(4000);
    nowLow=TRUE;
}

void init_18B20(void)
{
    DQ=TRUE;
    DQ=FALSE;
    delayus(700);//>480us
    DQ=TRUE;
    delayus(17);
    while(FALSE!=DQ);
    delayus(200);//60~240us
}

void write_18B20(unsigned char x)
{
    unsigned char m;
    for(m=0;m<8;m++)
    {
        DQ=TRUE;
        DQ=FALSE;
        delayus(1);
        if(x&(1<<m))//写数据,从低位开始
            DQ=TRUE;
        else
            DQ=FALSE;
        delayus(100);//60us
    }
    DQ=TRUE;
    delayus(1);
}

unsigned char read_18B20(void)
{
    unsigned char temp,l;
    temp=0;
    for(l=0;l<8;l++)
    {
        temp>>=1;
        DQ=FALSE;
        delayus(1);
        DQ=TRUE;
        delayus(1);
        if(DQ)
            temp|=0x80;
        delayus(100); //60~120us
        DQ=TRUE;
    }
    delayus(1);
    return (temp);
}

void t0_ISR() interrupt 1
{
    unsigned char temh,teml;
    TCON&=~0x01;
    if(0==a)
    {
        temh=0;
        teml=0;
        init_18B20();//复位18b20
        write_18B20(0xCC);//发出转换命令
        write_18B20(0x44);
        delayus(1000);
        init_18B20();
        write_18B20(0xCC);//发出读命令
        write_18B20(0xBE);
        teml=read_18B20();//读数据
        temh=read_18B20();
        count=(temh*256.0+teml*1.0)*0.0625;//计算具体温度
        tempratureNow=(unsigned char)(count);
    }
    a++;
    if(a>100)
        a=0;
    TCON|=0x01;
}

void t1_ISR() interrupt 3
{
    if(85==tempratureNow)tempratureNow=0;
    displayNow(tempratureNow);
    displaySet(tempratureSet);
    TCON|=0x40;
}

void adc0_ISR() interrupt 10
{
    isnewdata=1;
    AD0INT=0;
}

⌨️ 快捷键说明

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