搜索
bottom↓
回复: 0

怎么使用状态机?

[复制链接]

出0入0汤圆

发表于 2012-11-17 19:24:27 | 显示全部楼层 |阅读模式

系统有三个按键,功能分别是调整,加,减。我已经用状态机实现在第一次按下调整键时候,停止走时,显示秒的两位数码管以1 Hz 频率闪烁;如果第二次按下调整键,则分开始闪烁,秒恢复正常显示;如果第三次按下调整键,则时开始闪烁,分恢复正常显示;如果第四次按下调整键,时恢复正常显示,开始走时。怎么用状态机实现在数码管闪烁的时候,按下加或者减键可以调整相应的显示内容,
/************
作者:liyang
日期:2012年11月17日
目标MCU:STC89C51  晶振:11.0592M
******************************/
#include<reg51.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
uint8 LedBitCnt; //LedBitCnt控制数码管的位选
uint8 flagm=0,flagf=0,flags=0;//时分秒闪烁的控制标志位
uint8 ms2_flag; //2ms数码管动态扫描时标消息
uint8 ms10_flag,ms500_flag,s1num;
uint8 ms2_cnt,ms10_cnt,count,s1num;
uint8 dis_buff[8]={0};
uint8 shi=12,fen=23,miao=56;
uint8 code SegTab[]={0x3f,0x06,0x5b,0x4f,
                                        0x66,0x6d,0x7d,0x07,
                                        0x7f,0x6f,0x40,0x00};
sbit ADDR0 = P2^0;//74hc138的输入控制端A
sbit ADDR1 = P2^1;//74hc138的输入控制端B
sbit ADDR2 = P2^2;//74hc138的输入控制端C
sbit adjust=P3^2;
sbit add=P3^3;
sbit sub=P3^4;
#define key_state_0  0
#define key_state_1  1
#define key_state_2  2
void disp()
{
        P0=SegTab[dis_buff[LedBitCnt]];
        switch(LedBitCnt)
        {
                case 0:
                ADDR0=0;ADDR1=0;ADDR2=0;
                break;
                case 1:
                ADDR0=1;ADDR1=0;ADDR2=0;
                break;
                case 2:
                ADDR0=0;ADDR1=1;ADDR2=0;
                break;
                case 3:
                ADDR0=1;ADDR1=1;ADDR2=0;
                break;
                case 4:
                ADDR0=0;ADDR1=0;ADDR2=1;
                break;
                case 5:
                ADDR0=1;ADDR1=0;ADDR2=1;
                break;
                case 6:
                ADDR0=0;ADDR1=1;ADDR2=1;
                break;
                case 7:
                ADDR0=1;ADDR1=1;ADDR2=1;
                break;
        }

}
void time_to_disbuff(void)
{
        if(flagm&(!ms500_flag))
        {   
                dis_buff[7]=11;
                dis_buff[6]=11;
          }
          else
        {
                dis_buff[7]=miao%10;
                dis_buff[6]=miao/10;
        }
        dis_buff[5]=10;
        if(flagf&(!ms500_flag))
        {   
                dis_buff[4]=11;
                dis_buff[3]=11;
          }
        else
        {
                dis_buff[4]=fen%10;
                dis_buff[3]=fen/10;
        }
        dis_buff[2]=10;
        if(flags&(!ms500_flag))
        {   
                dis_buff[1]=11;
                dis_buff[0]=11;
          }
        else
        {
                dis_buff[1]=shi%10;
                dis_buff[0]=shi/10;
          }
}
void init()
{
        TMOD=0x11;
        TH1=0xf8;
        TL1=0xcd;
        TH0=0x4c;
        TL0=0x00;
        TR0=1;
        ET0=1;
        TR1=1;
        ET1=1;                       
}
char read_key(void)
{
   static char key_state=0;
   char key_press,key_return=0;
   key_press = adjust;  // 读按键 I/O电平
   switch (key_state)
   {
     case key_state_0:// 按键初始态
             if (!key_press)
                        key_state = key_state_1;//键被按下,状态转换到键确认态
                break;
     case key_state_1:// 按键确认态
             if (!key_press)
             {
                 s1num++;
                        key_return = 1;// 按键仍按下,按键确认输出为“1”
                 key_state = key_state_2;// 状态转换到键释放态
             }
              else
                key_state = key_state_0;// 按键已抬起,转换到按键初始态
               break;
      case key_state_2:
              if(key_press)
                        key_state = key_state_0;//按键已释放,转换到按键初始态
               break;
   }  
             return key_return;
}

void main()
{
        init();
        EA=1;
        time_to_disbuff();
        P0=0x00;
        while(1)
        {               
               
                if(ms2_flag)
                        {
                                ms2_flag=0;
                            LedBitCnt++;
                                if(LedBitCnt>7)
                                {
                                        LedBitCnt=0;
                                }
                                time_to_disbuff();
                                disp();
                       
                        }       
                if(ms10_flag)
                        {
                                ms10_flag=0;
                                if(read_key())
                                {
                                        if(s1num==1)
                                        {
                                                flagm=1;
                                                TR0=0;
                                        }
                               
                            }
                           if(s1num==2)
                             {
                                    flagm=0;
                                    flagf=1;
                            }
                   if(s1num==3)
                           {
                                    flagm=0;
                                    flagf=0;
                                     flags=1;
                            }
                          if(s1num==4)
                           {
                                TR0=1;
                                flags=0;
                                 s1num=0;
                        }
                       
                        }
       
        }
       
}
void timer0() interrupt 1
{
        TH0=0x4c;
        TL0=0x00;
        count++;
        if(count==20)
        {
                count=0;
                miao++;
                if(miao==60)
                {
                        miao=0;
                        fen++;
                        if(fen==60)
                        {
                                fen=0;
                                shi++;
                                if(shi==24)
                                {
                                        shi=0;
                                }
                        }
                }
        }

}
void timer1() interrupt 3  //定时1ms
{
        TH1=0xf8;
        TL1=0xcd;
        ms2_flag=1;   //用于数码管显示
        ms2_cnt++;
        if(ms2_cnt>=5)
        {
                ms2_cnt=0;  
                ms10_flag=1;//用于键扫描
                if(++ms10_cnt>=50)
                        {
                                ms10_cnt=0;
                                ms500_flag=~ms500_flag;
                        }
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-15 10:58

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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