找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 4465|回復(fù): 1
收起左側(cè)

單片機(jī)溫控系統(tǒng)程序代碼

[復(fù)制鏈接]
ID:115502 發(fā)表于 2016-4-20 18:18 | 顯示全部樓層 |閱讀模式
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char          
#define uint unsigned int
sbit key0=P1^0;
sbit key1=P1^2;
sbit key2=P1^4;
sbit key3=P1^6;
sbit led0=P3^0;
sbit led1=P3^3;
sbit beep=P3^7;
sbit rs=P2^0;
sbit rw=P2^1;
sbit en=P2^2;
sbit DQ=P2^3;
bit DS_OK=1; //溫度傳感器正常標(biāo)志
bit HI_alarm=0;LO_alarm=0;        //溫度正常標(biāo)志,超出上下限時,=1
char alarm_HL[]={10,-10};
uint time=0;
uchar temp_num[]={0x00,0x00};  //用于存儲高字節(jié)與低字節(jié)
uchar display_digit[]={0,0,0,0};//存儲顯示溫度字符
uchar current_count=0;   //存儲整數(shù)(高字節(jié)低三位與低字節(jié)高四位)
uchar alarm_HI_LO[]={"HI:     LO:      "};
uchar temperature_display[]={"TEMP:           "};
uchar code tab0[]={"welcome to here"};
uchar code tab1[]={"----sky"};
uchar code temperature_title[]={"THE TEMPPERATURE"};
uchar code alarm_title[]={"ALARM TEMP HI LO"};
uchar code df_tab[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
void delay(uint z)
{
        uint x;
        while(z--)
                for(x=120;x>0;x--);
}
void delay_4us()
{_nop_();_nop_();_nop_();_nop_();}
void delay_us(uint a)
{
        while(a--);
}
uchar LCD_check_busy()
{
        uchar state;
        rs=0;
        rw=1;
        delay_4us();
        en=1;
        state=P0;
        delay_4us();
        en=0;
        delay_4us();
        return state;
}
void LCD_write_cmd(uchar cmd)
{
    while((LCD_check_busy()&0x80)==0x80);
        rs=0;
        rw=0;
        delay_4us();
        en=1;
        P0=cmd;
        delay_4us();
        en=0;
        delay_4us();
}
void LCD_write_data(uchar dat)
{
        while((LCD_check_busy()&0x80)==0x80);
        rs=1;
        rw=0;
        delay_4us();
        en=1;
        P0=dat;
        delay_4us();
        en=0;
        delay_4us();
}
void LCD_display(uchar *s)
{
        uchar i;
        for(i=0;i<16;i++)
        {
                LCD_write_data(s[i]);       
        }
}
void LCD_init()
{
        LCD_write_cmd(0x38);
        LCD_write_cmd(0x0c);
        LCD_write_cmd(0x06);
        LCD_write_cmd(0x01);
}
//LCD*************************************************
/*****************************************************/
/****************************************************/
/****************************************************/
uchar DS_init()   //檢查溫度傳感器
{
        uchar state;
        DQ=1;
        delay_us(8); //精確定時
        DQ=0;
        delay_us(80);
        DQ=1;
        delay_us(8);
        state=DQ;
        delay(100);
        return state;
}
void DS_write_byte(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {               
                if((dat&0x01)==0) //寫0
                {
                        DQ=0;
                        delay_us(5);
                        DQ=1;
                }
       
                else                                 //寫1
                {
                        DQ=0;
                        delay_us(1);
                        DQ=1;
                        delay_us(4);
                }       
                dat>>=1;
        }
}
uchar DS_read_byte() //讀一個字節(jié)
{
        uchar i,dat=0;
        for(i=0;i<8;i++)
        {
                DQ=0;
                dat>>=1;
                DQ=1;
                if(DQ==1)
                        dat|=0x80;
                else
                        dat|=0x00;
                delay_us(30);
                DQ=1;
        }
        return dat;
}

void DS_read_temperature()
{       
        uchar a=15;
        alarm_HL[0]=a%10;
        alarm_HL[1]=-(a/10);
        if(DS_init()==1)         //檢查初始化溫度傳感器
                DS_OK=0;
        else
        {
                DS_init();
                DS_write_byte(0xcc); //跳過序列號
                DS_write_byte(0x44); //啟動溫度轉(zhuǎn)換
                DS_init();                   //重新檢查溫度傳感器
                DS_write_byte(0xcc);//
                DS_write_byte(0xbe);//啟動讀取溫度
/****先讀低8位,再讀高8位,不可調(diào)換************/
                temp_num[1]=DS_read_byte();
                temp_num[0]=DS_read_byte();
/***先裝載TH,再裝載TL******************************/       
                alarm_HL[0]=DS_read_byte();         //讀警報數(shù)據(jù)
                alarm_HL[1]=DS_read_byte();
                DS_OK=1;                         //正常工作
        }
}
/*void key_set_HL()
{
        if(key2==0)
        {
                alarm_HL[0]++;
                if(alarm_HL[0]==40)
                        alarm_HL[0]=20;
        }
        if(key3==0)
        {
                alarm_HL[1]--;
                if(alarm_HL[1]==-30)
                        alarm_HL[1]=-10;
        }
} */
void DS_set_alarm()
{
        DS_init();
        //key_set_HL();
        DS_write_byte(0xcc);
        DS_write_byte(0x4e);
/***        //寫數(shù)據(jù)到RAM,先寫TH,再寫TL,不可調(diào)換*/
        DS_write_byte(alarm_HL[0]);
        DS_write_byte(alarm_HL[1]);
        DS_write_byte(0x7f); //12位高精確度
        DS_init();
        DS_write_byte(0xcc);
        DS_write_byte(0x48);//復(fù)制數(shù)據(jù)到存儲器
}
void LCD_display_temperature()
{
        char sign_current_count;        //有符號型變量
        uchar flag=0;//負(fù)數(shù)標(biāo)識
        /***高5位為1(0XF8)則為負(fù)數(shù),為負(fù)數(shù)時取反加一****/
        if((temp_num[0]&0xf8)==0xf8)
        {
                temp_num[0]=~temp_num[0];  //負(fù)數(shù)取反
                temp_num[1]=~temp_num[1]+1;
                if(temp_num[1]==0x00)
                        temp_num[0]++;
                flag=1;//負(fù)數(shù)標(biāo)識
        }
        /****溫度小數(shù)部分*********/
        display_digit[3]=df_tab[temp_num[1]&0x0f];
    /*溫度整數(shù)部分(高字節(jié)低4位與低字節(jié)高4位,無符號)***/
        current_count=((temp_num[1]&0xf0)>>4)|((temp_num[0]&0x07)<<4);
         /*有符號的當(dāng)前溫度值,注意定義是char           */
/***判斷sign_current_count是否等于current_count*****
***若相等則選擇-current_count,否則選擇current_count*****/
        sign_current_count=flag?
                -current_count:current_count;
        /*高低溫報警標(biāo)志(與char類型alarm_HL比較,可以區(qū)分正負(fù)號比較)           */
/**先比較大小,再選擇1或者0;再賦值***********可以用IF語句代替******/
        HI_alarm=sign_current_count>=alarm_HL[0]?
                1:0;       
        LO_alarm=sign_current_count<=alarm_HL[1]?
                1:0;
/*        //分解整數(shù)部分                  */
        display_digit[0]=current_count/100;
        display_digit[1]=current_count%100/10;
        display_digit[2]=current_count%10;

   /***刷新LCD顯示緩沖***/
    temperature_display[11]=display_digit[3]+'0';
        temperature_display[10]='.';
        temperature_display[9]=display_digit[2]+'0';
        temperature_display[8]=display_digit[1]+'0';
        temperature_display[7]=display_digit[0]+'0';
        /*百位為0時不顯示*/
        if(display_digit[0]==0)
                temperature_display[7]=' ';
                /*百位為0,且十位為0時不顯示          */
        if((display_digit[0]==0)&(display_digit[1]==0))
                temperature_display[8]=' ';
   // 負(fù)號顯示在恰當(dāng)位置
        if(flag)
        {
                if(temperature_display[8]==' ')
                        temperature_display[8]='-';
                else
                {
                        if(temperature_display[7]==' ')
                                temperature_display[7]='-';
                        else
                                temperature_display[6]='-';
                }
        }
       
        LCD_write_cmd(0x80+0x00);
        LCD_display(temperature_title);

        LCD_write_cmd(0x80+0x40);
        LCD_display(temperature_display);
       
        LCD_write_cmd(0x80+0x4e);
        LCD_write_data('C');
       
}


/*******************************************************/
/***********************************************************/
/**********************************************
************************************
******************************************************/
/*****顯示報警溫度************************************/

void LCD_display_alarm_temperature()
{
/****顯示高溫*****************************************************/
        uchar i;
        uchar flag=0;//負(fù)號標(biāo)志
        if(alarm_HL[0]<0)
        {
                alarm_HL[0]=~alarm_HL[0]+1;
                flag=1;
        }
       
        /***分解高溫****************************************/
        alarm_HI_LO[4]=alarm_HL[0]/100+'0';
        alarm_HI_LO[5]=alarm_HL[0]%100/10+'0';
        alarm_HI_LO[6]=alarm_HL[0]%10+'0';
  /****屏蔽高位不顯示******************************************/
        if(alarm_HI_LO[4]=='0')
                alarm_HI_LO[4]=' ';
        if(alarm_HI_LO[4]==' '&&alarm_HI_LO[5]=='0')
                alarm_HI_LO[5]=' ';
  /****負(fù)號放在適當(dāng)?shù)奈恢?*************************************/
        if(flag)
        {
                if(alarm_HI_LO[4]==' ')
                        alarm_HI_LO[4]='-';
                else
                        if(alarm_HI_LO[5]==' ')
                                alarm_HI_LO[5]='-';
                        else
                                alarm_HI_LO[3]='-';
        }
/************************************************************/
/**********低溫報警值****************************************/         
         flag=0;
         if(alarm_HL[1]<0)
        {
                alarm_HL[1]=~alarm_HL[1]+1;
                flag=1;
        }
/****分解低溫*********************************************/       
        alarm_HI_LO[12]=alarm_HL[1]/100+'0';
        alarm_HI_LO[13]=alarm_HL[1]%100/10+'0';
        alarm_HI_LO[14]=alarm_HL[1]%10+'0';
/*********屏蔽高位不顯示************************************/
        if(alarm_HI_LO[12]=='0')
                alarm_HI_LO[12]=' ';
        if(alarm_HI_LO[12]==' '&&alarm_HI_LO[13]=='0')
                alarm_HI_LO[13]=' ';
/********負(fù)號顯示在適當(dāng)位置************************************/
        if(flag)
        {
                if(alarm_HI_LO[12]==' ')
                        alarm_HI_LO[12]='-';
                else
                        if(alarm_HI_LO[13]==' ')
                                alarm_HI_LO[13]='-';
                        else
                                alarm_HI_LO[11]='-';
        }  

        /****顯示高低溫報警溫度************************************/

        LCD_write_cmd(0x80+0x00);
        for(i=0;i<16;i++)
                LCD_write_data(alarm_title[i]);
        LCD_write_cmd(0x80+0x40);
        for(i=0;i<16;i++)
                LCD_write_data(alarm_HI_LO[i]);

        LCD_write_cmd(0x80+0x47);
        LCD_write_data('C');
        LCD_write_cmd(0x80+0x4f);
        LCD_write_data('C');
}       
void main()
{
        uchar i;
        uchar current_opteration=1;
        LCD_init();
        led0=1;
        led1=1;
        TMOD=0x01;
        TH0=-1000/256;
        TL0=-1000%256;
        EA=1;
        ET0=1;

        key_set_HL();
        DS_set_alarm();
        DS_read_temperature();
        delay(50);

        LCD_write_cmd(0x80+0x00);
        for(i=0;i<16;i++)
        {
                LCD_write_data(tab0[i]);
                delay(20);       
        }
        LCD_write_cmd(0x80+0x48);
        for(i=0;i<8;i++)
        {
                LCD_write_data(tab1[i]);       
                delay(20);
        }
        delay(1000);
        for(i=0;i<16;i++)
        {
                LCD_write_cmd(0x1c);
                delay(20);
        }
        delay(50);
                                         
        LCD_write_cmd(0x01);         
       
        while(1)
        {
                   if(key0==0)
                                   current_opteration=1;
                   if(key1==0)
                                   current_opteration=2;
                        switch(current_opteration)
                        {
                                case 1:
                                        DS_read_temperature();
                                        if(DS_OK)
                                        {
                                                if(HI_alarm==1||LO_alarm==1)
                                                        TR0=1;
                                                else
                                                        TR0=0;
                                                        LCD_display_temperature();
                                         }
                                                delay(100);
                                 break;
                                 case 2:
                                          DS_read_temperature();
                                         LCD_display_alarm_temperature();
                                         delay(100);
                                         break;
                }
        }
}

void timer0() interrupt 1
{       
        TH0=-1000/256;
        TL0=-1000%256;
        beep=~beep;
        if(++time==400)
        {
                time=0;
                if(HI_alarm)
                        led0=~led0;
                else
                        led0=1;
                if(LO_alarm)
                        led1=~led1;

相關(guān)帖子

回復(fù)

使用道具 舉報

ID:1 發(fā)表于 2016-4-20 18:56 | 顯示全部樓層
void timer0() interrupt 1 函數(shù)不完整  待樓主補(bǔ)齊后再加分
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表