第5届试题解析

#include "reg52.h"
#include "onewire.h"
#include "intrins.h"



sfr  P4 = 0xC0;    

sbit H1 = P3^0;
sbit H2 = P3^1;
sbit H3 = P3^2;
sbit H4 = P3^3;
sbit L1 = P3^4;
sbit L2 = P3^5;
sbit L3 = P4^2;
sbit L4 = P4^4;
sbit Led1 = P0^0;
sbit Led2 = P0^1;

unsigned char clr = 0,key_value = 0;     //清除标志位和键值
unsigned char Current_Temp = 0,T_Max = 30,T_Min = 20; //分别记录当前温度和默认最大值与最小值温度
unsigned char setmode = 0; //温度显示模式和设置模式标志
unsigned char T_Mode = 0 ;// 温度模式
unsigned char t_count = 0; //计时用于Led的不同闪烁时间
unsigned char flag = 0,Led_flag;    //按键按下标志位 和led闪烁标志
unsigned char yi,er,san,si,wu,liu,qi,ba; //数码管位
//0-9  0xbf代表 -
unsigned char code SMG_Duan_num[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff};

//-----------------------------简单延时-----------------------------

void Delay_ms(unsigned char t)        //@11.0592MHz
{
     while(t--);
}
//--------------------------------74HC138初始化-------------------------
void Init_74HC138(unsigned char n)
{
     switch(n)
    {
         case 4:P2 = (P2 & 0x1f) | 0x80;break;//Y4
        case 5:P2 = (P2 & 0x1f) | 0xa0;break;//Y5
        case 6:P2 = (P2 & 0x1f) | 0xc0;break;//Y6
        case 7:P2 = (P2 & 0x1f) | 0xe0;break;//Y7
        case 0:P2 = (P2 & 0x1f) | 0x00;break;//关闭
    }
}
//--------------------------------系统初始化----------------------------
void InitSystem(void)
{
     //关闭Led
    Init_74HC138(4);
    P0 = 0xff;
    //关闭继电器和蜂鸣器
    Init_74HC138(5);
    P0 = 0x00;
}
//---------------------------------数码管安位显示-------------------------
void SMG_DisplayBit(unsigned char pos ,unsigned char dat)
{
     Init_74HC138(6); //Y6
    P0 = (0x01 << pos);
    Init_74HC138(7);//Y7
    P0 = dat;
}
//---------------------------------关闭所有数码管--------------------------
void SMG_Close(unsigned char dat)
{
     Init_74HC138(6);
    P0 = 0xff; //全部选通
    Init_74HC138(7);
    P0 = dat;
}
//------------------------------------设置温度界面显示---------------------
void Display1(unsigned char yi,unsigned char  er)
{
      SMG_DisplayBit(0,SMG_Duan_num[yi]); //-
     Delay_ms(100);
     SMG_DisplayBit(1,SMG_Duan_num[er]); //
     Delay_ms(100);
}

void Display2(unsigned char san,unsigned char  si)
{
      SMG_DisplayBit(2,SMG_Duan_num[san]); //-
     Delay_ms(100);
     SMG_DisplayBit(3,SMG_Duan_num[si]); //
     Delay_ms(100);
}

void Display3(unsigned char wu,unsigned char  liu)
{
      SMG_DisplayBit(4,SMG_Duan_num[wu]); //-
     Delay_ms(100);
     SMG_DisplayBit(5,SMG_Duan_num[liu]); //
     Delay_ms(100);
}

void Display4(unsigned char qi,unsigned char  ba)
{
      SMG_DisplayBit(6,SMG_Duan_num[qi]); //-
     Delay_ms(100);
     SMG_DisplayBit(7,SMG_Duan_num[ba]); //
     Delay_ms(100);
}
//---------------------------------按键初始化-------------------------------
void Init_Keys(void)
{
        H1 = 0;
        H2 = H3 = H4 = 1;
        L1 = L2 = L3 = L4 = 1;
        if(L2 == 0)
        {
             Delay_ms(20);
            if(L2 == 0)
            {
                while(L2 == 0);
                key_value = 2;
            //    S15_Flag = 1;
            flag = 1;
                //SMG_DisplayBit(0,SMG_Duan_num[key_value]);
            }
        }
        else if(L3 == 0)
        {
             Delay_ms(20);
            if(L3 == 0)
            {
                while(L3 == 0);
                key_value = 1;
            //    S11_Flag = 1;
            flag = 1;
                //SMG_DisplayBit(0,SMG_Duan_num[key_value]);
            }
        }
        else if(L4 == 0)
        {
             Delay_ms(20);
            if(L4 == 0)
            {
                while(L4 == 0);
                key_value = 0;
                //S7_Flag = 1;
                flag = 1;
                //SMG_DisplayBit(0,SMG_Duan_num[key_value]);
            }
        }

        H2 = 0;
        H1 = H3 = H4 = 1;
        L1 = L2 = L3 = L4 = 1;
        if(L2 == 0)
        {
             Delay_ms(20);
            if(L2 == 0)
            {
                while(L2 == 0);
                key_value = 5;
                 //S15_Flag = 14;
                 flag = 1;
                //SMG_DisplayBit(0,SMG_Duan_num[key_value]);
            }
        }
        else if(L3 == 0)
        {
             Delay_ms(20);
            if(L3 == 0)
            {
                while(L3 == 0);
                key_value = 4;
                //S10_Flag = 1;
                flag = 1;
                //SMG_DisplayBit(0,SMG_Duan_num[key_value]);
            }
        }
        else if(L4 == 0)
        {
             Delay_ms(20);
            if(L4 == 0)
            {
                while(L4 == 0);
                key_value = 3;
                //S6_Flag = 1;
                flag = 1;
                //SMG_DisplayBit(0,SMG_Duan_num[key_value]);
            }
        }

        H3 = 0;
        H2 = H1 = H4 = 1;
        L1 = L2 = L3 = L4 = 1;
        if(L2 == 0)
        {
             Delay_ms(20);
            if(L2 == 0)
            {
                while(L2 == 0);
                key_value = 8;
                //S13_Flag = 1;
                flag = 1;
                //SMG_DisplayBit(0,SMG_Duan_num[key_value]);
            }
        }
        else if(L3 == 0)
        {
             Delay_ms(20);
            if(L3 == 0)
            {
                while(L3 == 0);
                key_value = 7;
                //S9_Flag = 1;
                flag = 1;
            }
        }
        else if(L4 == 0)
        {
             Delay_ms(20);
            if(L4 == 0)
            {
                while(L4 == 0);
                key_value= 6 ;
                //S5_Flag = 1;
                flag = 1;
            }
        }

        H4 = 0;
        H2 = H3 = H1 = 1;
        L1 = L2 = L3 = L4 = 1;
        if(L2 == 0)
        {
             Delay_ms(20);
            if(L2 == 0)
            {
            
                    while(L2 == 0);
                         if(clr == 0)
                        {
                            clr = 1;
                            yi = 10,er = 11,san = 11,si = 11,wu = 11,liu = 10,qi = 11,ba = 11;
                             
                        }
                        else if(clr == 1)
                        {
                             clr = 0;
                            yi = 10,er = 11,san = 11,si = 11,wu = 11,liu = 10,qi = 11,ba = 11;
                        }
                //SMG_DisplayBit(0,SMG_Duan_num[clr]);
            }
        }
        else if(L3 == 0)
        {
             Delay_ms(20);
            if(L3 == 0)
            {
                    while(L3 == 0);
                    //    S8_Flag = 1;
                        if(setmode == 0)
                        {
                             setmode = 1;                  //按键按下进入温度设置界面
                            Init_74HC138(5);
                            P0 = 0x00; //设置界面下时关闭继电器
                            yi = 10,er = 11,san = 11,si = 11,wu = 11,liu = 10,qi =11,ba = 11;
                        }
                        else if(setmode == 1)
                        {
                                 setmode = 0; //按键按下进入温度显示界面
                                EA = 1,ET0 = 1;
                            //    yi = 10,er = T_Mode,san = 10,si = 11,wu = 11,liu = 11,qi = Current_Temp/10,ba = Current_Temp%10;
                        } 
            }
        }
        else if(L4 == 0)
        {
             Delay_ms(20);
            if(L4 == 0)
            {
                while(L4 == 0);
                key_value = 9;
            //    S9_Flag = 1;
            flag = 1;
            }
        }
}
//--------------------------------------温度获取-----------------------------
void Read_DS18B20_T(void)
{
    unsigned char LSB ,MSB;         //分别存储低第0字节和第一字节
     init_ds18b20();     //DS18B20复位初始化
    Write_DS18B20(0xCC);  //跳过ROM指令
    Write_DS18B20(0x44);  //开始温度转换
    Delay_ms(800);     //延时700-900ms

    init_ds18b20();    //DS18B20复位初始化
    Write_DS18B20(0xCC);  //跳过ROM指令
    Write_DS18B20(0xBE);     //读取高速暂存器

    LSB = Read_DS18B20(); //暂存器第0字节
    MSB = Read_DS18B20();//暂存器第1字节
    Current_Temp = MSB;
    Current_Temp = (Current_Temp << 8) | LSB;            //整体16字节数据
    Current_Temp = Current_Temp >> 4;     //移除小数部分
    //下面为显示小数处理
 /*
    if((temp & 0xf800) == 0x0000)
    {
         temp >>= 4; //将小数移除
        temp = temp *10;
        temp = temp + (LSB & 0x0f)*0.625;
    }
    */
    if(Current_Temp < T_Min )    //温度区间0 继电器关闭
    {
         T_Mode = 0;
        Init_74HC138(5); //选通Y5控制继电器
        P0 = 0x00;//关闭继电器
        
    }
    //温度区间1 继电器关闭     
    else if(Current_Temp >= T_Min && Current_Temp <= T_Max)
    {
         T_Mode = 1;    
        Init_74HC138(5); //选通Y5控制继电器
        P0 = 0x00;//关闭继电器    
    }
    //温度区间2 继电器打开 
    else if(Current_Temp > T_Max)
    {
         T_Mode = 2;    
        Init_74HC138(5); //选通Y5控制继电器
        P0 = 0x10;//打开继电器    
    }
}    
//------------------------------定时器初始化----------------------------
void Init_Timer0(void)
{
    TMOD = 0x01;
    TH0  = (65535-20000)/256;
    TL0  = (65535-20000)%256;
    ET0  = 1;
    TR0  = 1;
    EA   = 1;
}
//-------------------------------主函数--------------------------------
void main(void)
{
    InitSystem();
    Init_Timer0();
    yi = 1,er = 2,san = 3,si = 4,wu = 5,liu = 6,qi = 7,ba = 8;//检测数码管是否正常
     while(1)
    {
         Init_Keys();
         if(setmode == 0) //非设置模式 显示实时温度
         {
                //温度获取
                Read_DS18B20_T();
                Delay_ms(20);
                yi = 10,er = T_Mode,san = 10,si = 11,wu = 11,liu = 11,qi = Current_Temp/10,ba = Current_Temp%10;
            
         }     
         else if(setmode == 1) //判断是否在设置状态下
         {
                 EA = 0,ET0 = 0;
                 if (er == 11 && flag == 1)
                    {
                        flag = 0;
                        er = key_value;
                    }
                    else if(san == 11 && flag == 1)
                    {
                         san = key_value;
                        flag = 0;
                    } 
                    else if(qi == 11 && flag == 1)
                    {
                         qi = key_value;
                        flag = 0;
                    }
                    else if(ba == 11 && flag == 1)
                    {
                         ba = key_value;
                        flag = 0;
                        if((er * 10 + san) < (qi * 10 + ba))//最大值小于最小值L2点亮
                        {
                            Init_74HC138(4);
                            P0 = 0xfd;
                        } 
                        else if((er * 10 + san) >= (qi * 10 + ba))
                        {
                             T_Max = (er * 10 + san);
                            T_Min = (qi * 10 + ba);
                            Init_74HC138(4);
                            P0 = 0xff;
                        }
                    }
         }         
         Display1(yi,er);
         Display2(san,si);
         Display3(wu,liu);
         Display4(qi,ba);
         //消影处理
         Init_74HC138(6);
         P0 = 0xff;
         Init_74HC138(7);
         P0 = 0xff;
    }
}

//-----------------------------中断服务函数-------------------------------
void Server_Timer0() interrupt 1
{
    TH0  = (65535-20000)/256;     //20ms
    TL0  = (65535-20000)%256;
    t_count++;
    if(t_count == 40 && T_Mode == 0)//温度区间0,继电器关闭,指示灯L1以0.8秒为间隔闪烁
    {
            t_count = 0;
            if(Led_flag == 0)
            {
             Led_flag = 1;
              Init_74HC138(4); //选通Y4控制Led
             P0 = 0xfe;
            }
            else if(Led_flag == 1)
            {
                 Led_flag = 0;
                Init_74HC138(4);
                P0 = 0xff;
            }
    }
    //温度区间1,继电器关闭,指示灯L1以0.4秒为间隔闪烁;
    else if(t_count ==  20 && T_Mode == 1)
    {
         t_count = 0;
         if(Led_flag == 0)
         {
                Led_flag = 1;
                Init_74HC138(4);
                P0 = 0xfe;
         }
         else if(Led_flag == 1)
         {
                 Led_flag = 0;
                Init_74HC138(4);
                P0 = 0xff;
         }
    }
    //温度区间2,继电器打开,指示灯L1以0.2秒为间隔闪烁。
    else if(t_count == 10 && T_Mode == 2)
    {
         t_count = 0;
        if(Led_flag == 0)
        {
            Led_flag = 1;
             Init_74HC138(4);
            P0 = 0xfe;
        }
        else if(Led_flag == 1)
        {
             Led_flag = 0;
            Init_74HC138(4);
            P0 = 0xff;
        }
    }  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值