欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4364|回復: 9
收起左側

單片機多級菜單+按鍵,子函數中有按鍵如何處理?

[復制鏈接]
ID:743654 發表于 2021-1-5 17:32 | 顯示全部樓層 |閱讀模式
50黑幣
本帖最后由 cheney03 于 2021-1-5 19:48 編輯

程序是網上的例程,已實現多級菜單顯示。現在有個問題:當進入函數fun1中,fun1函數中也有按鍵需要處理(通過up down鍵對變量temp實現加 減),這樣按鍵有沖突,要怎么實現不沖突呢?按鍵為4*4矩陣按鍵,通過行列掃描獲取鍵值判斷哪個鍵按下。



#include <reg52.h>
#include "fun.h"
#include "lcd12864.h"
#include "delay.h"
#define uchar unsigned char
uchar func_index=0;
void (*current_operation_index)();
typedef struct
   {
         uchar current;
         uchar up;//向上翻索引號
         uchar down;//向下翻索引號
         uchar enter;//確認索引號
         void (*current_operation)();
         } key_table;
key_table code table[3]=
{
        {0,3,1,3,(*fun1)},
         {1,0,2,2,(*fun2)},
         {2,1,3,1,(*fun3)} ,
         {3,2,0,0,(*fun3)}

void main()
{  
    init_lcd(); //初始化LCD模塊  
    while(1)
       
  {  
         Key_scan();
         if(KeyState)
          {
           KeyState=0;
           if(KEY==KEY_OK)
           {
             func_index=table[func_index].enter;
           }
           if(KEY==KEY_DOWN)
           {
             func_index=table[func_index].down;
           }
           if(KEY==KEY_UP)
           {
             func_index=table[func_index].up;
           }  
                   current_operation_index=table[func_index].current_operation;
           (*current_operation_index)();//執行當前操作函數
          
          
//           flag=0;
          }
                
        }
}      

回復

使用道具 舉報

ID:739545 發表于 2021-1-5 17:55 | 顯示全部樓層
利用標志位進行操作,例如在一級菜單中用標志位F1,按鍵操作F1中的函數,進入二級菜單設置為F2,按鍵操作F2中的函數

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:517466 發表于 2021-1-5 18:57 | 顯示全部樓層
怎么會有沖突呢?主函數中的按鍵處理和子函數中的按鍵處理完全不需要特殊處理啊。他們在各自的函數中正常判斷就行。
main() {
    while(1) {
        if (KeyUp按下) {
            延遲20ms,消抖動;
            if (KeyUp按下) {
                while(KeyUp仍處于按下狀態) ;
                調用子函數1的處理;
            }
        }
    }
}

void 子函數1() {
        if (KeyUp按下) {
            延遲20ms,消抖動;
            if (KeyUp按下) {
                while(KeyUp仍處于按下狀態) ;
                調用子函數2的處理;
            }
}

你看,KeyUp鍵在主函數和子函數中,互相不影響,是可以正常工作的。
就像windows操作系統里F1是獲得幫助,在Windows的應用程序里一樣可以使用F1,獲得應用程序的幫助。道理是一樣的。

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:743654 發表于 2021-1-5 19:20 | 顯示全部樓層
lovezjf234 發表于 2021-1-5 17:55
利用標志位進行操作,例如在一級菜單中用標志位F1,按鍵操作F1中的函數,進入二級菜單設置為F2,按鍵操作F2 ...

謝謝,這個有想過
回復

使用道具 舉報

ID:743654 發表于 2021-1-5 19:25 | 顯示全部樓層
本帖最后由 cheney03 于 2021-1-5 19:39 編輯
suncat0504 發表于 2021-1-5 18:57
怎么會有沖突呢?主函數中的按鍵處理和子函數中的按鍵處理完全不需要特殊處理啊。他們在各自的函數中正常判 ...

我用的是行列掃描按鍵,通過鍵值來判斷哪個鍵按下。若要按鍵操作子函數,每次都要重新掃描按鍵,并且要放在while(1)函數中,不然按鍵操作無效,不知道怎么退出回到主程序中。
回復

使用道具 舉報

ID:743654 發表于 2021-1-5 19:26 | 顯示全部樓層
按鍵掃描函數
void Key_scan(void)
{
        char a;
        GPIO_KEY=0x0f;
        if(GPIO_KEY!=0x0f)
        {
                Delay10ms();
                if(GPIO_KEY!=0x0f)
                {
                        KeyState=1;
                        //測試列
                        GPIO_KEY=0X0F;
                        Delay10ms();
                        switch(GPIO_KEY)
                        {
                                case(0X07):        KEY=1;break;
                                case(0X0b):        KEY=2;break;
                                case(0X0d): KEY=3;break;
                                case(0X0e):        KEY=4;break;

                        }
                        //測試行
                        GPIO_KEY=0XF0;
                        Delay10ms();
                        switch(GPIO_KEY)
                        {
                                case(0X70):KEY=KEY;break;
                                case(0Xb0):KEY=KEY+4;break;
                                case(0Xd0):KEY=KEY+8;break;
                                case(0Xe0):KEY=KEY+12;break;

                        }
                        while((a<50)&&(GPIO_KEY!=0xf0))         //檢測按鍵松手檢測
                        {
                                Delay10ms();
                                a++;
                        }
                       
                }
        }
}
回復

使用道具 舉報

ID:743654 發表于 2021-1-5 19:36 | 顯示全部樓層
本帖最后由 cheney03 于 2021-1-5 20:34 編輯

fun1()
{
  unsigned char temp;
  bit flag;
  while(1)        
   {  
          Key_scan();
          if(KeyState)
          {
           KeyState=0;
           if((KEY==KEY_UP)&&(temp<255))
           {
        
           temp++;Datapros(temp);//按一次up鍵 數值加1,并數據處理顯示

           }
           if((KEY==KEY_DOWN)&&(temp>0))
           {
         
            temp--;Datapros(temp);//按一次down鍵 數值減1,并數據處理顯示

           }  
            if((KEY==KEY_OK))
           {
            write24C02(0x01,temp);//數據保持到24C02存儲芯片
            這邊要怎么操作,才能回到main主函數中

           }
//           flag=0;
           
          }
         
   }
回復

使用道具 舉報

ID:213173 發表于 2021-1-6 13:38 | 顯示全部樓層
cheney03 發表于 2021-1-5 19:36
fun1()
{
  unsigned char temp;

按鍵掃描函數只負責輸出鍵值,由按鍵服務函數根據目前所處工作狀態對鍵值做相應的響應。簡單的說,同一個鍵值在不同的工作狀態所執行的任務完全不同,不存在有沖突問題。你在fun1()中不恰當使用while(1) 會玩死的。
回復

使用道具 舉報

ID:235954 發表于 2021-1-6 13:48 | 顯示全部樓層
按下設置相應的標志位,根據標志位顯示不同的內容
回復

使用道具 舉報

ID:517466 發表于 2021-1-8 11:12 | 顯示全部樓層
cheney03 發表于 2021-1-5 19:25
我用的是行列掃描按鍵,通過鍵值來判斷哪個鍵按下。若要按鍵操作子函數,每次都要重新掃描按鍵,并且要放 ...

我做的一個簡單控制系統中,對鍵盤有一個默認的設置。比如某些鍵是作為上下調節數據用的,有的當做“確認”鍵,有的當做“取消”鍵。在子函數中的鍵盤掃描處理中,檢測到“確認鍵”,相當于保存當前設置數據,并退出子函數,返回主函數。如果掃描到“取消鍵”,表示拋棄當前設置數據,返回主函數。
某個按鍵,在主程序中可以作為“菜單鍵”處理,而在子函數中當做“返回上級菜單”、“返回上級父函數”處理,既然程序是你自己編的,怎么定,自由度很大。想統一安排,也可以固定設定某個鍵為固定功能,比如固定當做“退出當前函數”的按鍵。
常見的電腦顯示器中,一般都有幾個按鈕。你做程序時 ,完全可以參照顯示器按鈕的使用方式。道理是一樣的。
又比如,在操作系統的資源管理器中,“A”可以用于快速查找打頭字母為“A”的文件。在文字編輯軟件中,“A”表示輸的文字。而在CS游戲中,“A”默認是角色左移。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表