找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机EC11编码器数码管菜单程序算法问题

[复制链接]
跳转到指定楼层
楼主
小弟初学单片机,正在写一个EC11数码管菜单的程序,遇到问题搞不定,特来发帖请教。

实现功能:EC11数码管菜单的子功能,上电后左右旋转增减数值。按钮长按三秒后,个位闪动,进入调整状态。旋转按钮,数值加减1,可自动进位;短按一次,十位闪动,数值加减10,逢100自动进位;再短按一次,百位闪动,数值加减100。

加值时候正常,问题出在对百位减值的时候。假如现在值是134,百位闪动。这时旋钮左转一格,百位应该变成0,同时改成十位闪动;若旋钮再左旋3格,十位变成0,同时改成个位闪动。在十位或个位闪动的时候,短按按钮,闪动的位数应该自由升位,但是现在不行。

(就是说在百位变成0时,闪动标记n应该由1变成2,但是只变一次就行了,不要再被while循环扫描。现在是一直被while扫描,导致短按按钮时数值2降不下来)我这块代码肯定是写错了,但我搞了好几天,能力有限,实在想不出来解决方法,故此发帖求助。

减值这块有点绕,但愿我上面说清楚了。下面贴出单片机代码,请大佬不吝指导。

#include  "STC8G.h"
#include  "TM1650.h"

char n=3;                        //闪动位数
unsigned char flag_1ms=0;  //时间基线1ms
unsigned int flag_300ms=0; //闪动间隔时长
bit Active_Menu=0;       //激活设置标志
bit flag=0;                //闪动标志

//sbit LED=P1^1;            //按钮测试

sbit EC11_A=P3^2;          //加值
sbit EC11_B=P3^3;          //减值
sbit K3 = P3^4;            //设置键


int number=134;//显示数值初始化
//-----------------------------------------------------------------
unsigned char code SEG7[] = {0x3F,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
unsigned char LedBuff[] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned char ucDigDot[8];//要显示的8个小数点
int num[] = {0, 0, 0, 0};

void display();
void EC11_K3_Scan();
int Jia_jian(int Value);
int EC11_Scan(int EC11_value);


void EC11_K3_Scan()    //EC11按键功能
{
static unsigned int K3_press_time=0;     //按键计时变量
static bit K3_sign=0;  //按键状态标志
   
                    if(K3==0)  //按键按下
                    {
                K3_press_time++;
                        
                if(K3_press_time>3000)
                                    
                      K3_press_time=3001; //防止溢出
                                
                if(K3_press_time>10 && K3_sign==0) //10ms消抖
                                    
                      K3_sign=1; //确认按键按下
                                
                if(K3_press_time==3000)  //判断按下3s有效
                            {
                                                            
                                Active_Menu=~Active_Menu;
                           
                                if(Active_Menu==0) flag=0;
                                
                            //LED=!LED;  //按键测试
                            }     
                    }
        else        //短按或按下后松手
        {
                if(K3_sign==1)//判断是按键按下后松手
                {
                                    K3_sign=0;
                        
                                            if(K3_press_time<1000)//小于1s判断短按
                       
                                          
                                                if(Active_Menu==1)     
                    
                                                {
                                                    n--;                 //个位、十位、百位切换
                                                if (n <0) n = 3;
                                                }
                    
                            //LED=!LED; //任务按键测试
                        if(K3_press_time>=1000 && K3_press_time<3000);//大于1s有效
                    
                               //任务
                }
                K3_press_time=0;

        }
}


int Jia_jian( int Value)  //加减值函数

{

     {num[0]=Value/1000;
        num[1]=(Value/100)%10;
        num[2]=(Value/10)%10;
        num[3]=Value%10;}

        Value=EC11_Scan(Value);

                          if (Value<100&&Value>10)   //有问题的代码
                                      n=2;                       //有问题的代码
                            else if (Value<10&&Value>0)//有问题的代码
                                      n=3;                       //有问题的代码

                           
                           
                            if (Value<0)
                            Value=0;
        
                            if (Value>9999) Value=0;
                           
                           

        display();

return Value;
    }

void display()//1650显示
{
    unsigned char i;
    unsigned char j;
   
        for(i = 0; i < 4; i++)
   
                LedBuff[ i] = num[ i];
   
        if (flag)
                LedBuff[n] = 10;
        
   for(j=0;j<4;j++)
   Set1650(DIG_BIT_CODE[j],SEG7[LedBuff[j]]);               
}

void Timer1Init(void)        //1毫秒@11.0592MHz
{
    AUXR &= 0xBF;        //定时器时钟12T模式
    TMOD &= 0x0F;        //设置定时器模式
    TL1 = 0x66;            //设置定时初始值
    TH1 = 0xFC;            //设置定时初始值
    TF1 = 0;                //清除TF1标志
    TR1 = 1;                //定时器1开始计时
   
    EA=1;                //开总中断
  ET1=1;            //开定时器T1中断
}
//---------------------------------------

void main()
{
   
    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
  P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
  P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
  P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
  P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
  P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
  P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
  P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
        
  P_SW2 |= 0x80;     //准双向口(或开漏模式) + 内部上拉
    P3PU=0xc0;
   
    Timer1Init();//定时器1初始化
    Init1650();//1650初始化
   
while(1)
    {
        if(flag_1ms==1)
        {
                flag_1ms=0;
                number=Jia_jian(number);
                EC11_K3_Scan();         
        }
}
}

//---------------------------------------

void T1_time() interrupt 3   //定时器T1的中断序号为3,T1的中断服务函数
{
   
    flag_1ms=1;
    if(Active_Menu==1)
    flag_300ms++;
    if(flag_300ms==300)
    {
            flag_300ms=0;
            flag = ~flag;//闪动标志
    }
}

/*********************************

* @函数名:EC11_Scan

* @描  述:判断方向,计算旋转的值。个位闪动+/-1;十位闪动+/-10;百位闪动+/-100。

* @参  数:EC11_value

* @返回值:EC11_value

*********************************/

int EC11_Scan(int EC11_value)

{
      static bit EC11_Flag=0,Left_Flag=0,Right_Flag=0;
    if((EC11_A)&&(EC11_B))  //两个都是1,表示开始第一个脉冲
    {
  EC11_Flag =1 ;//标记为第一个信号收到,可以进行下一个信号
    }
    if(EC11_A!=EC11_B)//第二个信号
    {
   Left_Flag = EC11_A ; //记录AB的信号状态
   Right_Flag = EC11_B ;
    }
    if(EC11_Flag)  
        {
   if((EC11_A==0)&&(EC11_B==0))  // 第三个信号,处理第二个信号的值
           {
      if(Left_Flag)  //左转
                        {
                 if (n==1)            //百位闪动
                            EC11_value-=100;    //百位闪动-100
                     else if (n==2)       //十位闪动
                          EC11_value-=10;        //十位闪动-10
                     else if (n==3)          //个位闪动
                       EC11_value--;            //个位闪动-1
                        }
                    else if(Right_Flag)
                        {
                 if (n==1)            //百位闪动
                            EC11_value+=100;  //百位闪动+100
                     else if (n==2)       //十位闪动
                          EC11_value+=10;   //十位闪动+10
                     else if (n==3)          //个位闪动
                            EC11_value++;          //个位闪动+1            
                        }
             EC11_Flag = 0; //把标志位清零,等待下一个周期            
           }
        }   
    return EC11_value;
}


EC11数码管闪动.rar

6.75 KB, 下载次数: 17

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

使用道具 举报

沙发
ID:161164 发表于 2022-11-13 22:19 | 只看该作者
n的值被if (Value<100&&Value>10)和else if (Value<10&&Value>0)定死了
建议修改如下,n只会在value有改变时才赋值


回复

使用道具 举报

板凳
ID:1044091 发表于 2022-11-14 16:55 | 只看该作者
lkc8210 发表于 2022-11-13 22:19
n的值被if (Value10)和else if (Value0)定死了
建议修改如下,n只会在value有改变时才赋值

感谢大佬指导!在你的思路基础上结合整个程序我又补充了一些代码,从执行结果上看是对的,不过我自己已经彻底晕了全靠仿真一步步验证出来的。等头脑清醒的时候再优化下吧!




回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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