第五周学习笔记

过渡模拟二与Led模块

过渡模拟二

设计思路

  1. 小数点输入

     case 11://小数点输入
         if(Seg_Disp_Mode == 0 && Point_Flag == 0 && Seg_Input[0] != 11)//处于温度采集界面、标志位为0、输入数组第一位有数据
         {
             Seg_Point[2+Seg_Input_Index] = 1;
             Point_Wela = Seg_Input_Index;//记录此时指针状态 便于后期数据处理
             Point_Flag = 1;//拉高标志位 保证一次输入周期小数点只能使能一次
         }
     break;
    
  2. 小数点位置(数据显示时候)

     Temperature = Seg_Input[0] * 100 + Seg_Input[1] * 10 + Seg_Input[2] + 5;
     while(3 - Point_Wela)
     {
         Temperature /= 10.0;
         Point_Wela++;
     }
    
  3. 长按与短按区分

     if(Seg_Disp_Mode == 2)//处于参数设置界面
     {
         if(Key_Down == 14)//S14按下
             Time_Flag = 1;//计时开始
     }
     if(Count_500Ms < 500)//短按
     {
         if(Key_Up == 14)//S14抬起
         {
             Time_Flag = Count_500Ms = 0;//状态复位
             if(++Parameter[Parameter_Index] > 70)//超过上限值
                 Parameter[Parameter_Index] = 10;
         }
     }
     else//长按
     {
         if(Key_Old == 14)//S14长按
         {
             if(++Parameter[Parameter_Index] > 70)//超过上限值
                 Parameter[Parameter_Index] = 10;
         }
         if(Key_Up == 14)//S14抬起
             Time_Flag = Count_500Ms = 0;//状态复位
     }
    

    计时器里的操作

     if(Time_Flag == 1)
     {
         if(++Count_500Ms == 600)//自加到五百毫秒以上就可以限制住 防止一直按下自加的时候数值越界
             Count_500Ms = 600;
     }
    
  4. 亮度等级

     if(Temperature > Parameter_Ctrol[0])
         Led_Pwm = 3;
     else if(Temperature < Parameter_Ctrol[0] && Temperature > Parameter_Ctrol[1])
         Led_Pwm = 6;
     else
         Led_Pwm = 9;
    

    计时器里的操作(周期内的亮度闪烁,周期极短时,肉眼分辨不出来)

     if(++Led_Num == 10) Led_Num = 0;
     if(Led_Num < Led_Pwm)
         Led_Disp(Led_Pos,ucLed[Led_Pos]);
     else
         Led_Disp(Led_Pos,0);
    

    总程序

     /*头文件声明区域*/
     #include <REGX52.H>
     #include "key.h"
     #include "Seg.h"
     #include "Led.h"
     ​
     /*变量声明区域*/
     unsigned char Key_Slow_Down;//按键减速专业变量
     unsigned int Seg_Slow_Down;//数码管减速专业变量
     unsigned char Key_Val,Key_Up,Key_Down,Key_Old;//按键扫描专业变量
     unsigned char Seg_Pos;//数码管扫描变量
     unsigned char Seg_Buf[6] = {10,10,10,10,10,10};//数码管显示数据存放数组
     unsigned char Seg_Point[6] = {0,0,0,0,0,0};//小数点点亮存放数组
     unsigned char Led_Pos;//Led扫描变量
     unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};//Led点亮存放数组
     unsigned char Seg_Mode;//数码管显示模式 0-温度采集界面 1-数据显示界面 2-参数设置界面
     unsigned char Seg_Input[3] = {11,11,11};//温度采集数组
     unsigned char Seg_Input_Index;
     unsigned int Timer_500ms;//0.5s
     unsigned char Point_Wela;//小数点位置变量
     unsigned char Parameter[2] = {30,20};//参数设置数组
     unsigned char Parameter_Ctrol[2] = {30,20};//参数控制数组
     unsigned int Count_500ms;//长按计时变量
     unsigned char Led_Num;//Led亮度等级计时变量
     unsigned char Led_Pwm;//Led亮度等级
     float Temperature;//实际温度数据
     bit Seg_Flag;//闪烁标志位
     bit Point_Flag;//小数点标志位 0-输入 1-输入完成
     bit Parameter_Flag;//参数标志为位
     bit Time_Flag;//长按计时标志位 
     bit Error_Flag;//错误标志位
     ​
     /*按键处理函数*/
     void Key_Proc()
     {
         unsigned char i;//循环变量
         if(Key_Slow_Down)return;
         Key_Slow_Down = 1;//按键减速程序
         
         Key_Val = Key_Read();//读取键码值
         Key_Down = Key_Val & (Key_Val ^ Key_Old);//检测下降沿
         Key_Up = ~Key_Val & (Key_Val ^ Key_Old);//检测上升沿
         Key_Old = Key_Val;//扫描辅助沿
         
         if(Key_Down >= 1 && Key_Down <= 10)//0到9输入
         {
             if(Seg_Mode == 0)//温度采集界面
             {
                 if(Seg_Input_Index < 3)
                 {
                     Seg_Input[Seg_Input_Index] = Key_Down - 1;
                     Seg_Input_Index++;          
                 }
             }
         }
         
         if(Seg_Mode == 2)
         {
             if(Key_Down == 14)
                 Time_Flag = 1;//开始计时
         }
         if(Count_500ms < 500)//短按
         {
             if(Key_Up == 14)//抬起
             {
                 Time_Flag = Count_500ms = 0;
                 if(++Parameter[Parameter_Flag] > 70)
                     Parameter[Parameter_Flag] = 10;
             }
         }
         else//长按
         {
             if(Key_Old == 14)
             {
                 if(++Parameter[Parameter_Flag] > 70)
                     Parameter[Parameter_Flag] = 10;
             }
             if(Key_Up == 14)
                 Time_Flag = Count_500ms = 0;
         }
         if(Seg_Mode == 2)
         {
             if(Key_Down == 15)
                 Time_Flag = 1;//开始计时
         }
         if(Count_500ms < 500)//短按
         {
             if(Key_Up == 15)//抬起
             {
                 Time_Flag = Count_500ms = 0;
                 if(--Parameter[Parameter_Flag] == 255)
                     Parameter[Parameter_Flag] = 70;
             }
         }
         else//长按
         {
             if(Key_Old == 15)
             {
                 if(--Parameter[Parameter_Flag] == 255)
                     Parameter[Parameter_Flag] = 70;
             }
             if(Key_Up == 15)
                 Time_Flag = Count_500ms = 0;
         }
             
         switch(Key_Down)
         {
             case 11://小数点输入
                 if(Seg_Mode == 0 && Point_Flag == 0 && Seg_Input[0] != 11)//小数点输入的条件,确保第一位输入
                 {
                     Seg_Point[2+Seg_Input_Index] = 1;//!!!不是3+Seg_Input_Index
                     Point_Wela = Seg_Input_Index;//记录小数点的位置,方便数据显示
                     Point_Flag = 1;
                 }
             break;
             case 12:
                 if(Seg_Mode != 0)//非温度采集界面
                     Seg_Mode = (Seg_Mode == 1)?2:1;
                 if(Seg_Mode == 2)//切换到参数设置界面  由1到2
                 {
                     Parameter_Flag = 0;
                     Parameter[0] = Parameter_Ctrol[0];
                     Parameter[1] = Parameter_Ctrol[1];  
                 }
                 else//切换到数据显示界面时候
                 {
                     if(Parameter[0] >= Parameter[1] && Parameter[0] < 70 && Parameter[1] > 10)
                     {
                         Error_Flag = 0;
                         Parameter_Ctrol[0] = Parameter[0];
                         Parameter_Ctrol[1] = Parameter[1];
                     }
                     else
                         Error_Flag = 1;
                 }
             break;
             case 13:
                 if(Seg_Mode == 2)
                 {
                     Parameter_Flag ^= 1;
                 }
             break;
             case 16://进入温度采集界面
                 if(Seg_Mode != 0)//非温度采集界面
                 {
                     Seg_Input_Index = 0;//指针复位
                     Point_Flag = 0;//小数点使能
                     Seg_Point[3] = Seg_Point[4] = 0;//小数点复位
                     for(i = 0;i < 3;i++)//数组复位
                         Seg_Input[i] = 11;
                 }
                 else//处于温度采集界面
                 {
                     if(Point_Flag == 0 || Seg_Input_Index < 3)//数据无效
                     {
                         Seg_Input_Index = 0;//指针复位
                         Point_Flag = 0;//小数点使能
                         Seg_Point[3] = Seg_Point[4] = 0;//小数点复位
                         for(i = 0;i < 3;i++)//数组复位
                             Seg_Input[i] = 11;
                     }
                     else//小数点使能
                     {
                         Temperature = Seg_Input[0]*100 + Seg_Input[1]*10 + Seg_Input[2] + 5;
                         while(3-Point_Wela)//根据小数点位置,判断数据的大小
                         {
                             Temperature /= 10.0;
                             Point_Wela++;
                         }
                         if((unsigned int)Temperature > 85)//超出上限
                         {
                             Seg_Input_Index = 0;//指针复位
                             Point_Flag = 0;//小数点使能
                             Seg_Point[3] = Seg_Point[4] = 0;//小数点复位
                             for(i = 0;i < 3;i++)//数组复位
                                 Seg_Input[i] = 11;
                         }
                         else//数据合理
                         {
                             Seg_Input_Index = 0;//指针复位
                             Point_Flag = 0;//小数点使能
                             Seg_Point[3] = Seg_Point[4] = 0;//小数点复位
                             Seg_Mode = 1;
                         }
                     }
                 }
                 
                 
             break;
         }
     }
     ​
     /*信息处理函数*/
     void Seg_Proc()
     {
         if(Seg_Slow_Down)return;
         Seg_Slow_Down = 1;//按键减速程序
         
         switch(Seg_Mode)
         {
             case 0://温度采集界面
                 Seg_Buf[0] = 12;//A
                 Seg_Buf[1] = Seg_Buf[2] = 10;
                 Seg_Buf[3] = Seg_Input[0];
                 Seg_Buf[4] = Seg_Input[1];
                 Seg_Buf[5] = Seg_Input[2];
                 if(Seg_Buf[5] == 11)
                     Seg_Buf[3+Seg_Input_Index] = Seg_Flag?Seg_Input[Seg_Input_Index]:10;
             break;
             case 1:
                 Seg_Buf[0] = 13;//C
                 Seg_Buf[1] = Seg_Buf[2] = Seg_Buf[3] = 10;
                 Seg_Buf[4] = (unsigned char)Temperature / 10;
                 Seg_Buf[5] = (unsigned char)Temperature % 10;
                 if(Seg_Buf[4] == 0)Seg_Buf[4] = 10;
             break;
             case 2:
                 Seg_Buf[0] = 14;//P
                 Seg_Buf[1] = 10;
                 Seg_Buf[2] = Parameter[0] / 10;
                 Seg_Buf[3] = Parameter[0] % 10;
                 Seg_Buf[4] = Parameter[1] / 10;
                 Seg_Buf[5] = Parameter[1] % 10;
                 Seg_Buf[2+2*Parameter_Flag] = Seg_Flag?Parameter[Parameter_Flag]/10:10;
                 Seg_Buf[3+2*Parameter_Flag] = Seg_Flag?Parameter[Parameter_Flag]%10:10;
             break;
         }
     }
     ​
     /*其他显示函数*/
     void Led_Proc()
     {
         if(Temperature > Parameter_Ctrol[0])
             Led_Pwm = 3;
         else if(Temperature < Parameter_Ctrol[0] && Temperature > Parameter_Ctrol[1])
             Led_Pwm = 6;
         else
             Led_Pwm = 9;
         ucLed[0] = (int)Temperature/Parameter_Ctrol[0];
         ucLed[1] = (!((int)Temperature/Parameter_Ctrol[0])) & ((int)Temperature/Parameter_Ctrol[1]);
         ucLed[2] = !((int)Temperature/Parameter_Ctrol[1]);
         ucLed[3] = Error_Flag;
     }
     ​
     /*定时器0初始化函数*/
     void Timer0_Init(void)      //1毫秒@12.000MHz
     {
         TMOD &= 0xF0;           //设置定时器模式
         TMOD |= 0x01;           //设置定时器模式
         TL0 = 0x18;             //设置定时初始值
         TH0 = 0xFC;             //设置定时初始值
         TF0 = 0;                //清除TF0标志
         TR0 = 1;                //定时器0开始计时
         ET0 = 1;
         EA = 1;
     }
     ​
     /*定时器0中断服务函数*/
     void Timer0Sever() interrupt 1
     {
         TL0 = 0x18;             //设置定时初始值
         TH0 = 0xFC;             //设置定时初始值
         if(++Key_Slow_Down == 10)Key_Slow_Down = 0;
         if(++Seg_Slow_Down == 10)Seg_Slow_Down = 0;
         if(++Seg_Pos == 6)Seg_Pos = 0;
         if(++Led_Pos == 8)Led_Pos = 0;
         Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
         if(++Timer_500ms == 500)
         {
             Timer_500ms = 0;
             Seg_Flag ^= 1;
         }
         if(Time_Flag == 1)
         {
             if(++Count_500ms == 600)
                 Count_500ms = 600;//限制最大值,以防超越
         }
         /*亮度等级*/
         if(++Led_Num == 10) Led_Num = 0;
         if(Led_Num < Led_Pwm)
             Led_Disp(Led_Pos,ucLed[Led_Pos]);
         else
             Led_Disp(Led_Pos,0);
         
     }
     ​
     /*Main*/
     void main()
     {
         Timer0_Init();
         while(1)
         {
             Key_Proc();
             Seg_Proc();
             Led_Proc();
         
         }
     ​
     }
    

    Led模块

    译码器控制锁存器的使能端(8421码)

    P2_7,P2_6,P2_5控制Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7

 P0 = 0xff;
 P2 = P2 & 0x1f | 0x80;//先把高三位清0,保持后五位不变,然后再打开锁存器Y4
 P2 &= 0x1f;
 P0 = 0x00;
 P2 = P2 & 0x1f | 0xa0;//先把高三位清0,保持后五位不变,然后再打开锁存器Y5
 P2 &= 0x1f;

Led模块

 #include "Led.h"
 ​
 void Led_Disp(unsigned char addr,unsigned char enable)
 {
     static unsigned char temp = 0x00;
     static unsigned char temp_old = 0xff;
     if(enable)
         temp |= 0x01 << addr;
     else
         temp &= ~(0x01 << addr);
     if(temp != temp_old)
     {
         P0 = ~temp;
         P2 = P2 & 0x1f | 0x80;
         P2 &= 0x1f;
         temp_old = temp;
     }
 }