找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1621|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

單片機EC11編碼器數(shù)碼管菜單程序算法問題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1044091 發(fā)表于 2022-11-13 14:54 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
小弟初學(xué)單片機,正在寫一個EC11數(shù)碼管菜單的程序,遇到問題搞不定,特來發(fā)帖請教。

實現(xiàn)功能:EC11數(shù)碼管菜單的子功能,上電后左右旋轉(zhuǎn)增減數(shù)值。按鈕長按三秒后,個位閃動,進入調(diào)整狀態(tài)。旋轉(zhuǎn)按鈕,數(shù)值加減1,可自動進位;短按一次,十位閃動,數(shù)值加減10,逢100自動進位;再短按一次,百位閃動,數(shù)值加減100。

加值時候正常,問題出在對百位減值的時候。假如現(xiàn)在值是134,百位閃動。這時旋鈕左轉(zhuǎn)一格,百位應(yīng)該變成0,同時改成十位閃動;若旋鈕再左旋3格,十位變成0,同時改成個位閃動。在十位或個位閃動的時候,短按按鈕,閃動的位數(shù)應(yīng)該自由升位,但是現(xiàn)在不行。

(就是說在百位變成0時,閃動標記n應(yīng)該由1變成2,但是只變一次就行了,不要再被while循環(huán)掃描。現(xiàn)在是一直被while掃描,導(dǎo)致短按按鈕時數(shù)值2降不下來)我這塊代碼肯定是寫錯了,但我搞了好幾天,能力有限,實在想不出來解決方法,故此發(fā)帖求助。

減值這塊有點繞,但愿我上面說清楚了。下面貼出單片機代碼,請大佬不吝指導(dǎo)。

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

char n=3;                        //閃動位數(shù)
unsigned char flag_1ms=0;  //時間基線1ms
unsigned int flag_300ms=0; //閃動間隔時長
bit Active_Menu=0;       //激活設(shè)置標志
bit flag=0;                //閃動標志

//sbit LED=P1^1;            //按鈕測試

sbit EC11_A=P3^2;          //加值
sbit EC11_B=P3^3;          //減值
sbit K3 = P3^4;            //設(shè)置鍵


int number=134;//顯示數(shù)值初始化
//-----------------------------------------------------------------
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個小數(shù)點
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;  //按鍵狀態(tài)標志
   
                    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; //任務(wù)按鍵測試
                        if(K3_press_time>=1000 && K3_press_time<3000);//大于1s有效
                    
                               //任務(wù)
                }
                K3_press_time=0;

        }
}


int Jia_jian( int Value)  //加減值函數(shù)

{

     {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;        //設(shè)置定時器模式
    TL1 = 0x66;            //設(shè)置定時初始值
    TH1 = 0xFC;            //設(shè)置定時初始值
    TF1 = 0;                //清除TF1標志
    TR1 = 1;                //定時器1開始計時
   
    EA=1;                //開總中斷
  ET1=1;            //開定時器T1中斷
}
//---------------------------------------

void main()
{
   
    P0M1 = 0x00;   P0M0 = 0x00;   //設(shè)置為準雙向口
  P1M1 = 0x00;   P1M0 = 0x00;   //設(shè)置為準雙向口
  P2M1 = 0x00;   P2M0 = 0x00;   //設(shè)置為準雙向口
  P3M1 = 0x00;   P3M0 = 0x00;   //設(shè)置為準雙向口
  P4M1 = 0x00;   P4M0 = 0x00;   //設(shè)置為準雙向口
  P5M1 = 0x00;   P5M0 = 0x00;   //設(shè)置為準雙向口
  P6M1 = 0x00;   P6M0 = 0x00;   //設(shè)置為準雙向口
  P7M1 = 0x00;   P7M0 = 0x00;   //設(shè)置為準雙向口
        
  P_SW2 |= 0x80;     //準雙向口(或開漏模式) + 內(nèi)部上拉
    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的中斷服務(wù)函數(shù)
{
   
    flag_1ms=1;
    if(Active_Menu==1)
    flag_300ms++;
    if(flag_300ms==300)
    {
            flag_300ms=0;
            flag = ~flag;//閃動標志
    }
}

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

* @函數(shù)名:EC11_Scan

* @描  述:判斷方向,計算旋轉(zhuǎn)的值。個位閃動+/-1;十位閃動+/-10;百位閃動+/-100。

* @參  數(shù):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的信號狀態(tài)
   Right_Flag = EC11_B ;
    }
    if(EC11_Flag)  
        {
   if((EC11_A==0)&&(EC11_B==0))  // 第三個信號,處理第二個信號的值
           {
      if(Left_Flag)  //左轉(zhuǎn)
                        {
                 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數(shù)碼管閃動.rar

6.75 KB, 下載次數(shù): 21

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:161164 發(fā)表于 2022-11-13 22:19 | 只看該作者
n的值被if (Value<100&&Value>10)和else if (Value<10&&Value>0)定死了
建議修改如下,n只會在value有改變時才賦值


回復(fù)

使用道具 舉報

板凳
ID:1044091 發(fā)表于 2022-11-14 16:55 | 只看該作者
lkc8210 發(fā)表于 2022-11-13 22:19
n的值被if (Value10)和else if (Value0)定死了
建議修改如下,n只會在value有改變時才賦值

感謝大佬指導(dǎo)!在你的思路基礎(chǔ)上結(jié)合整個程序我又補充了一些代碼,從執(zhí)行結(jié)果上看是對的,不過我自己已經(jīng)徹底暈了全靠仿真一步步驗證出來的。等頭腦清醒的時候再優(yōu)化下吧!




回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表