久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2440|回復: 13
打印 上一主題 下一主題
收起左側

求助單片機菜單程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:579174 發表于 2024-7-25 21:23 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
200黑幣
51單片機初學者,想用4個按鍵實現菜單設置,K1為菜單翻頁,K2/K3為數值的加減,K4為保存退出,2個數碼管顯示,一個數碼管顯示菜單頁面如P01,另一個數碼管顯示菜單對應的值,如數字123或ON和OFF。困惑的是  進入對應頁面如何獲取菜單對應的初值,求大神指導!

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

使用道具 舉報

沙發
ID:404160 發表于 2024-7-26 11:20 | 只看該作者
編寫一個使用C51單片機的程序,實現按鍵控制菜單設置的功能,需要考慮以下幾個方面:

1. 按鍵的初始化和防抖動處理。
2. 數碼管的驅動和顯示。
3. 菜單邏輯的設計,包括翻頁、數值加減和保存退出。
4. 程序結構的安排,確保代碼的可讀性和可維護性。

下面是一個簡單的示例代碼,用于實現上述功能。請注意,這只是一個基礎示例,實際應用中可能需要根據具體的硬件連接和需求進行調整。

```c
#include <reg51.h>

#define KEY1 P3_0
#define KEY2 P3_1
#define KEY3 P3_2
#define KEY4 P3_3

#define SEGMENT_PORT P0 // 數碼管的段選端口
#define DIGIT_PORT P1  // 數碼管的位選端口

// 假設菜單有3個頁面,每個頁面有2個可設置的值
#define MAX_PAGE 3
#define MAX_VALUE 2

unsigned char currentPage = 0;
unsigned char currentValIndex = 0;
unsigned int values[MAX_PAGE][MAX_VALUE] = {
    {100, 200}, // 第一個頁面的兩個值
    {300, 400}, // 第二個頁面的兩個值
    {500, 600}  // 第三個頁面的兩個值
};

// 延時函數
void delay(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 123; j++);
}

// 按鍵掃描函數
unsigned char keyScan() {
    if (KEY1 == 0) {
        delay(20); // 簡單的消抖
        if (KEY1 == 0) {
            currentPage = (currentPage + 1) % MAX_PAGE; // 翻頁
            return 1;
        }
    }
    if (KEY2 == 0) {
        delay(20);
        if (KEY2 == 0) {
            values[currentPage][currentValIndex]++; // 增加數值
            return 2;
        }
    }
    if (KEY3 == 0) {
        delay(20);
        if (KEY3 == 0) {
            values[currentPage][currentValIndex]--; // 減少數值
            return 3;
        }
    }
    if (KEY4 == 0) {
        delay(20);
        if (KEY4 == 0) {
            return 4; // 保存退出
        }
    }
    return 0;
}

// 數碼管顯示函數
void display(unsigned char page, unsigned int value) {
    // 這里需要根據實際的數碼管硬件連接來編寫顯示邏輯
    // 以下代碼僅為示例
    SEGMENT_PORT = 0xFF; // 關閉所有段
    DIGIT_PORT = ~(1 << page); // 選擇當前顯示的數碼管

    // 將數值轉換為數碼管可以顯示的格式
    // 這里需要編寫轉換邏輯,例如將數值轉換為BCD碼等
    unsigned char displayValue = value % 10; // 僅顯示個位數作為示例

    SEGMENT_PORT = ~displayValue; // 打開相應的段
}

void main() {
    while (1) {
        unsigned char key = keyScan();
        if (key == 1) {
            // 翻頁
            display(0, currentPage + 1); // 顯示頁面號
        } else if (key == 2 || key == 3) {
            // 數值加減
            display(1, values[currentPage][currentValIndex]); // 顯示當前值
        } else if (key == 4) {
            // 保存退出
            // 這里可以添加保存邏輯,例如寫入EEPROM等
            break;
        }
    }
}
```

請注意,這個示例代碼沒有包含所有的硬件細節,例如數碼管的驅動邏輯和按鍵的防抖動處理。在實際應用中,你可能需要根據具體的硬件連接和需求來編寫相應的驅動代碼。此外,對于數值的顯示,你可能需要將數值轉換為BCD碼或其他格式,以便數碼管可以正確顯示。
回復

使用道具 舉報

板凳
ID:548322 發表于 2024-7-26 15:00 | 只看該作者
樓上用chatgpt回復也挺⑥的,不過這邊建議作為51單片機初學者,可以先嘗試兩個界面如何顯示不同數據,再做菜單界面,一般STM32的菜單界面都是通過鏈表的方式實現,可以用stc試試枚舉+結構體的方式去做。如果等人給你一個開源工程,基本上很難。
回復

使用道具 舉報

地板
ID:1116913 發表于 2024-7-26 15:31 | 只看該作者
回復

使用道具 舉報

5#
ID:579174 發表于 2024-7-26 19:48 | 只看該作者
2300606886 發表于 2024-7-26 15:31
http://www.zg4o1577.cn/bbs/dpj-232305-1.html可以看看他的程序

感謝!
回復

使用道具 舉報

6#
ID:579174 發表于 2024-7-26 19:48 | 只看該作者
小盼666 發表于 2024-7-26 15:00
樓上用chatgpt回復也挺⑥的,不過這邊建議作為51單片機初學者,可以先嘗試兩個界面如何顯示不同數據,再做 ...

非常感謝!
回復

使用道具 舉報

7#
ID:1129675 發表于 2024-7-27 00:07 | 只看該作者
可以用狀態機做
回復

使用道具 舉報

8#
ID:982617 發表于 2024-8-7 17:13 | 只看該作者
要實現這個功能,你需要構建一個狀態機以管理不同菜單頁面的控制流程。下面是一個基于51單片機的簡單實現思路:

### 步驟分解:

#### 1. 定義菜單頁面和狀態:

- **菜單頁面**:假設你有3個主要菜單頁面,可以是:
  - 頁面1:初值為0的數值設置。
  - 頁面2:初值為ON或OFF的狀態設置。
  - 頁面3:初值為123的數值設置。
  
- **狀態**:需要的狀態包括但不限于:
  - 狀態1:顯示頁面1,并顯示對應的數值或狀態。
  - 狀態2:顯示頁面2,并顯示ON或OFF狀態。
  - 狀態3:顯示頁面3,并顯示數值123。

#### 2. 初始化:

- 設置數碼管顯示模式,如使用動態掃描顯示。
- 初始化按鍵輸入,如使用中斷或循環檢查按鍵狀態。
- 將所有菜單頁的初始值存儲在存儲器中,例如在特殊功能寄存器(SFR)或程序存儲器中。

#### 3. 狀態機設計:

- **狀態機**使用狀態寄存器來跟蹤當前的菜單頁面和狀態。
- **狀態轉移**通過按鍵輸入來觸發,例如,K1按鍵用于翻頁,K2/K3按鍵用于數值加減,K4按鍵用于保存設置并退出當前頁面或保存設置后返回上一頁。

#### 4. 編寫程序:

以下是一個基于簡單假設的偽代碼示例:

```c
#include <reg51.h> // 51單片機頭文件

#define LCD_DATA_PORT P0 // LCD數據端口
#define LCD_CMD_PORT P2 // LCD命令端口
#define SENSOR_PORT P1 // 按鍵端口
#define PAGE1_INIT_VALUE 0 // 初始值為0
#define PAGE2_INIT_VALUE "ON" // 初始狀態為ON
#define PAGE3_INIT_VALUE 123 // 初始值為123
#define PAGE_COUNT 3 // 3個菜單頁面

void setup() {
    // 初始化數碼管,按鍵,和LCD
}

unsigned char currentState = 1; // 菜單頁面狀態
unsigned char currentValue = PAGE1_INIT_VALUE; // 當前菜單的值
unsigned char currentDisplay = PAGE1_INIT_VALUE; // 當前顯示的值
char displayValue[2]; // 用于顯示的數值字符串

void loop() {
    // 檢查按鍵狀態并根據狀態機更新
    if (K1) {
        // 翻頁操作
    } else if (K2) {
        // 數值加操作
    } else if (K3) {
        // 數值減操作
    } else if (K4) {
        // 保存退出操作
    }

    // 顯示操作
    displayCurrentPage();
   
    // 根據狀態更改顯示
    if (currentState == 1) {
        // 顯示頁面1
    } else if (currentState == 2) {
        // 顯示頁面2
    } else if (currentState == 3) {
        // 顯示頁面3
    }
}

void displayCurrentPage() {
    // 顯示當前值或狀態到數碼管
}

// 更多細節和邏輯填充...
```

### 實現細節:

- **按鍵輸入**:使用中斷或者循環檢查按鍵狀態。
- **數碼管顯示**:使用動態掃描或靜態顯示方法更新數碼管顯示。
- **狀態機邏輯**:根據按鍵輸入更新狀態寄存器,從而控制數碼管顯示的內容和執行相應的操作。

這個框架提供了基本的思路和結構,你需要根據實際的硬件和軟件環境進一步完善代碼。特別是按鍵的處理和數碼管顯示的具體實現,可能需要參考具體硬件的驅動庫或參考資料。
回復

使用道具 舉報

9#
ID:579174 發表于 2024-8-12 10:04 | 只看該作者
hezezeze 發表于 2024-8-7 17:13
要實現這個功能,你需要構建一個狀態機以管理不同菜單頁面的控制流程。下面是一個基于51單片機的簡單實現思 ...

受教!
回復

使用道具 舉報

10#
ID:123917 發表于 2024-8-12 19:16 | 只看該作者
思路,R0的值對應菜單號碼,比如R0=1,顯示P01,R0=2,顯示P02
回復

使用道具 舉報

11#
ID:309610 發表于 2024-8-18 09:46 | 只看該作者
先做一個按鍵掃描函數返回值 0,無按鍵,1菜單按鍵、2上翻、3下翻、4確定保存、5超時60s無按鍵.具體程序很多可以參考其他
做一個顯示函數,disp_menu(u8 menu)顯示菜單,disp_datp(u8 data)顯示菜單內容
如果菜單參數是同類型,定義菜單數組就行。不同類型要定義結構體。
#define XX  10      //XX菜單數目
u8 menu=0; //菜單號   0為運行顯示內容,非0菜單調整
u8 menu_last=0; //歷史菜單號
u8 datp_temp=0;// 菜單臨時寄存
u8 datp_menu[XX];//菜單參數表

void main()
{
  while(1)
  {
    u8 key=keyscan();//讀取按鍵
       
    if(key==1)                      //菜單鍵 循環菜單
          { menu++; if(menu>XX)menu=0;}
        else if(key==2)                //上翻 臨時參數加
          { datp_temp++;}         
    else if(key==3)                //下翻 臨時參數減
          { datp_temp--;}                
        else if(key==4)                //保存 臨時參數保存
                { if(menu>0)
                     {datp_menu[menu-1]=datp_temp;}         
                                 }
        else if(key==5)                 //超時退出菜單
                {menu=0;}         

        if ((menu!=menu_last)&&(menu>0)) //菜單改變讀取菜單保存到臨時寄存
            { datp_temp=datp_menu[menu-1]
        menu_last=menu;                   //菜單號寄存
               
         if (menu==0) { disp();}          //正常顯示程序
         else {  disp_menu( menu);       //顯示菜單號
                 disp_datp(datp_temp);    // 顯示菜單內容
                         }
        }
}
  此程序適合參數較少,參數不大的簡易菜單或調試學習。進一步上翻鍵改為移位鍵增加一轉換函數把指定參數
  整形拆分為個、 十、百、千、萬 、小數。存儲到臨時數組內,移位鍵修改指針地址。兼修改位的閃爍顯示標志、
  下翻修改制定臨時數組內容。這樣可以設定多種類型參數,可以設定較大數值。按保存鍵再把臨時數組內內容整合
  保存到所讀參數內。
回復

使用道具 舉報

12#
ID:1125252 發表于 2024-8-20 18:44 | 只看該作者
if(K1==0)
{
  num++;
  if(num>=4)
  {

  }
}
回復

使用道具 舉報

13#
ID:1125252 發表于 2024-8-20 18:52 | 只看該作者
if(k1==0)
{
num++;
if(num>=4){num=0;}
}
if(num==0){讀取eeprom的addr對應值作為初值;
                if(k2==0){addr++;}
                if(k3==0){addr--;}
                if(k4==0){addr值寫入eeprom;}
                display(addr);
}
if(num==1){同上操作,顯示和讀取eeprom值可以在c51教程找到}
if(num==2){同上操作}
if(num==3){同上操作}
回復

使用道具 舉報

14#
ID:982617 發表于 2024-8-23 14:30 | 只看該作者
在使用51單片機進行按鍵輸入和數碼管顯示時,可以設計一個簡單的狀態機來處理按鍵輸入和菜單的顯示。以下是一個基本的實現步驟:

### 1. 菜單結構與變量定義
首先,定義菜單的頁面和對應的參數值。假設你的菜單有以下頁面:
- **P01**: 設置為初始頁面,對應的值可能是0(或OFF)。
- **P02**: 設置為頁面2,對應的值可能是123或ON。
- **P03**: 設置為頁面3,對應的值可能是特定數字或狀態(如OFF)。
- **P04**: 設置為頁面4,對應的值可能是特定數字或狀態(如ON)。

定義菜單頁面和值的變量:
```c
#define MENU_PAGE_SIZE 4
#define OFF "OFF"
#define ON "ON"

char menuPage = P01;
char menuValue[MENU_PAGE_SIZE][10] = {"", "0", "123", "OFF", "ON"};
int currentValue = 0;
```

### 2. 初始化
在程序開始時,初始化數碼管LED顯示和LCD顯示模塊(如果使用)。

### 3. 狀態機
使用狀態機來處理按鍵輸入和菜單顯示。定義幾個狀態:
- **STATE_INIT**:初始狀態,用于初始化和顯示菜單頁面。
- **STATE_NUM_UP**:值增加狀態。
- **STATE_NUM_DOWN**:值減小狀態。
- **STATE_CONFIRM**:確認狀態,用于保存當前值并退出菜單。

狀態機可以通過一個變量(如`currentState`)來跟蹤當前狀態,并根據按鍵輸入改變狀態。

### 4. 按鍵處理函數
```c
void processK1() {
    if (currentState == STATE_INIT) {
        // 菜單翻頁
        if (menuPage < MENU_PAGE_SIZE) {
            menuPage++;
        } else {
            menuPage = P01;
        }
        displayMenuPage();
    }
}

void processK2() {
    switch (currentState) {
        case STATE_INIT:
            // 菜單值增加
            if (menuPage == 1) {
                currentValue++;
                if (currentValue > 9) {
                    currentValue = 0;
                }
                displayValue();
            }
            break;
        case STATE_NUM_UP:
            currentValue++;
            if (currentValue > 9) {
                currentValue = 0;
            }
            displayValue();
            break;
        case STATE_CONFIRM:
            // 保存值并退出
            displayValue();
            currentState = STATE_INIT;
        // 重置菜單值
        menuValue[menuPage] = menuValue[menuPage][0] + (char)(currentValue + '0');
        displayMenuValue();
        currentState = STATE_INIT;
    }
}

void processK3() {
    switch (currentState) {
        case STATE_INIT:
            // 菜單值減小
            if (menuPage == 1) {
                currentValue--;
                if (currentValue < 0) {
                    currentValue = 9;
                }
                displayValue();
            }
            break;
        case STATE_NUM_DOWN:
            currentValue--;
            if (currentValue < 0) {
                currentValue = 9;
            }
            displayValue();
            break;
        case STATE_CONFIRM:
            // 無需處理
            break;
    }
}

void processK4() {
    if (currentState == STATE_INIT) {
        currentState = STATE_CONFIRM;
        displayConfirmation();
    }
}
```

### 5. 顯示函數
定義函數來更新數碼管的顯示。這通常涉及到硬件接口的使用,如定時器、串行通信等。

### 6. 主循環
在主循環中調用上述函數,并根據當前狀態執行操作。

### 7. 運行流程
- 程序開始時,進入`STATE_INIT`狀態,數碼管顯示菜單頁面。
- 當按下K1時,切換菜單頁面。
- 按下K2或K3時,在對應菜單值上加減。
- 按下K4時,確認當前值并退出菜單。

通過這些步驟,你可以實現一個基本的菜單設置功能,從按鍵輸入到菜單頁面和值的顯示都有詳細的處理邏輯。根據實際硬件和環境調整上述代碼中的接口和細節部分。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一区二区三区视频免费看 | 国产精品一区二区三区久久 | 国产精品久久久久久久久久三级 | 精品国产一级片 | 国产98色在线 | 欧美日韩黄色一级片 | 在线观看亚洲精品 | 欧美一区二区三区久久精品 | 我想看一级黄色毛片 | 亚洲精品一区二区三区在线观看 | 最新中文字幕第一页视频 | 青青久视频 | 亚洲导航深夜福利涩涩屋 | 三级av在线 | 七七婷婷婷婷精品国产 | 国产日韩久久 | www.四虎.com | 91精品久久久久久久久 | 欧美视频成人 | 欧美日韩毛片 | 成人片免费看 | 国外成人免费视频 | 久久国产精99精产国高潮 | 91精品国产777在线观看 | 亚洲av一级毛片 | 亚洲视频一区 | 黄色网址免费在线观看 | 成人欧美一区二区三区 | 日韩伦理一区二区三区 | 国产一区二区三区在线观看免费 | 久久综合久色欧美综合狠狠 | 天天干天天爱天天操 | 国产精品精品3d动漫 | 国产精品久久久久久福利一牛影视 | 黑人成人网| 日日干干| 亚洲精品自拍视频 | 亚洲精品乱码久久久久久蜜桃91 | 日韩a视频 | 亚洲精品一区二区三区丝袜 | 中文字幕亚洲无线 |