找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4033|回复: 1
打印 上一主题 下一主题
收起左侧

单片机温控系统程序代码

[复制链接]
跳转到指定楼层
楼主
ID:115502 发表于 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; //温度传感器正常标志
bit HI_alarm=0;LO_alarm=0;        //温度正常标志,超出上下限时,=1
char alarm_HL[]={10,-10};
uint time=0;
uchar temp_num[]={0x00,0x00};  //用于存储高字节与低字节
uchar display_digit[]={0,0,0,0};//存储显示温度字符
uchar current_count=0;   //存储整数(高字节低三位与低字节高四位)
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() //读一个字节
{
        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); //启动温度转换
                DS_init();                   //重新检查温度传感器
                DS_write_byte(0xcc);//
                DS_write_byte(0xbe);//启动读取温度
/****先读低8位,再读高8位,不可调换************/
                temp_num[1]=DS_read_byte();
                temp_num[0]=DS_read_byte();
/***先装载TH,再装载TL******************************/       
                alarm_HL[0]=DS_read_byte();         //读警报数据
                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);
/***        //写数据到RAM,先写TH,再写TL,不可调换*/
        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);//复制数据到存储器
}
void LCD_display_temperature()
{
        char sign_current_count;        //有符号型变量
        uchar flag=0;//负数标识
        /***高5位为1(0XF8)则为负数,为负数时取反加一****/
        if((temp_num[0]&0xf8)==0xf8)
        {
                temp_num[0]=~temp_num[0];  //负数取反
                temp_num[1]=~temp_num[1]+1;
                if(temp_num[1]==0x00)
                        temp_num[0]++;
                flag=1;//负数标识
        }
        /****温度小数部分*********/
        display_digit[3]=df_tab[temp_num[1]&0x0f];
    /*温度整数部分(高字节低4位与低字节高4位,无符号)***/
        current_count=((temp_num[1]&0xf0)>>4)|((temp_num[0]&0x07)<<4);
         /*有符号的当前温度值,注意定义是char           */
/***判断sign_current_count是否等于current_count*****
***若相等则选择-current_count,否则选择current_count*****/
        sign_current_count=flag?
                -current_count:current_count;
        /*高低温报警标志(与char类型alarm_HL比较,可以区分正负号比较)           */
/**先比较大小,再选择1或者0;再赋值***********可以用IF语句代替******/
        HI_alarm=sign_current_count>=alarm_HL[0]?
                1:0;       
        LO_alarm=sign_current_count<=alarm_HL[1]?
                1:0;
/*        //分解整数部分                  */
        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]=' ';
   // 负号显示在恰当位置
        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;//负号标志
        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]=' ';
  /****负号放在适当的位置**************************************/
        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]=' ';
/********负号显示在适当位置************************************/
        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;

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2016-4-20 18:56 | 只看该作者
void timer0() interrupt 1 函数不完整  待楼主补齐后再加分
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表