找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4314|回復(fù): 17
收起左側(cè)

C51單片機(jī)問題請教,通過按鍵操作控制LCD1602的顯示循環(huán)顯示兩個(gè)頁面[已解決]

[復(fù)制鏈接]
ID:888259 發(fā)表于 2021-3-4 11:11 | 顯示全部樓層 |閱讀模式
這個(gè)問題困擾了我很久,十幾天都沒有解決,希望有站內(nèi)大佬幫我一下。
1.問題描述:
通過按鍵操作控制LCD1602的顯示循環(huán)顯示兩個(gè)頁面,F(xiàn)有的現(xiàn)象是程序開始時(shí),LCD屏保持在第一個(gè)頁面不變,但是按動(dòng)(按下再抬起)按鈕后,LCD就自己不停的在兩個(gè)頁面之間循環(huán)跳變。只有在按下按鈕不抬起來的時(shí)候LCD屏幕才能一直顯示一個(gè)頁面。PS:按鍵和LCD顯示單獨(dú)測試均正常,且引腳定義也已確定無誤。
2.問題代碼:#include<REG52.h>
#include"LCD1602.h"
#include"delay.h"
#include"Level_1Menu.h"
#include"Level_2Menu.h"
#include"Level_3Menu.h"
#include"Level_4Menu.h"
#include"EC11.h"
#include"PowerMode.h"
#include"interrupt.h"
#include"relay.h"


unsigned char menu = 0;

unsigned char  key_num = 0;

unsigned char EC11_Action()
{
        if(ENTER == 0)//判斷ENTER鍵是否按下
                {
                        DelayXms(5);//延時(shí)消抖,時(shí)間一般為5-10ms
                        if(ENTER == 0)
                        {                        
                                key_num = 1;//分配ENTER的鍵值為“1”
                                while(ENTER == 0);//等待松手
                                LCDWriteCmd(LCD_SCREEN_CLR); //清屏
                        }

                }

        return key_num;        
}

unsigned char EC11_Scan()
{

        switch(EC11_Action())
        {
                case 0:break;
                case 1:menu++;if(menu>1) menu = 0;break;
                default:break;
        }
        return menu;
}


void LCDShowService()
{
                switch(EC11_Scan())
                {
                        case 0:BAIC_C62X();break;
                        case 1:BAIC_B40();break;
                        default:break;
                }        
}


void T0_Service() interrupt 1 using 0
{
        TR0=0;                 //關(guān)閉定時(shí)器
        TL0=0x33;    //低八位賦初值
        TH0=0XFE;    //高八位賦初值
        
        LCDShowService();

        TR0=1;//重新開啟定時(shí)器        
}


void main()
{        
        LCDInit();
        T0_Init();
        while(1);
}



捕獲.PNG

DVP_MENU.rar

66.54 KB, 下載次數(shù): 5

LCD驅(qū)動(dòng)及相關(guān)模塊

回復(fù)

使用道具 舉報(bào)

ID:798631 發(fā)表于 2021-3-4 11:38 | 顯示全部樓層
menu 的反轉(zhuǎn)太快了   把反轉(zhuǎn)速度降下來啊
回復(fù)

使用道具 舉報(bào)

ID:888259 發(fā)表于 2021-3-4 11:40 | 顯示全部樓層
問題補(bǔ)充:如果直接在EC11_Action()函數(shù)直接中做menu變量的增減操作,然后再中斷函數(shù)中用switch函數(shù)處理menu的值,程序就沒有問題。
回復(fù)

使用道具 舉報(bào)

ID:888259 發(fā)表于 2021-3-4 11:43 | 顯示全部樓層
15830266185 發(fā)表于 2021-3-4 11:38
menu 的反轉(zhuǎn)太快了   把反轉(zhuǎn)速度降下來啊

您的意思是中斷的時(shí)間太短了嗎?我這邊中斷是5ms一次的,能否具體指明一下呢?謝謝啦
回復(fù)

使用道具 舉報(bào)

ID:798631 發(fā)表于 2021-3-4 11:51 | 顯示全部樓層
中斷是5ms一次             case 1:menu++;if(menu>1) menu = 0;break;  這句   menu反轉(zhuǎn)就是10ms   
回復(fù)

使用道具 舉報(bào)

ID:888259 發(fā)表于 2021-3-4 11:54 | 顯示全部樓層
15830266185 發(fā)表于 2021-3-4 11:51
中斷是5ms一次             case 1:menu++;if(menu>1) menu = 0;break;  這句   menu反轉(zhuǎn)就是10ms

我剛調(diào)整的定時(shí)中斷時(shí)間為50ms,現(xiàn)象還是一樣的。只是頁面切換的沒有那么快了。
回復(fù)

使用道具 舉報(bào)

ID:798631 發(fā)表于 2021-3-4 11:59 | 顯示全部樓層
做成0.5秒切換啊      比方說  menu低于50顯示 1界面  高于50顯示2界面  =100 歸0  調(diào)好計(jì)數(shù)就好
回復(fù)

使用道具 舉報(bào)

ID:451718 發(fā)表于 2021-3-4 12:03 | 顯示全部樓層
定時(shí)器中斷處理里面去操作定時(shí)器的開關(guān),這不是一種好的程序結(jié)構(gòu)思維。  你所預(yù)想的結(jié)果,并不一定是你希望得到的。  這樣搞,不可預(yù)料的狀態(tài)太多了,不是定時(shí)器的正確用法
回復(fù)

使用道具 舉報(bào)

ID:858964 發(fā)表于 2021-3-4 13:33 | 顯示全部樓層
建議在按鍵處理函數(shù)中添加消除抖動(dòng)的代碼。
回復(fù)

使用道具 舉報(bào)

ID:888259 發(fā)表于 2021-3-4 13:38 | 顯示全部樓層
robinsonlin 發(fā)表于 2021-3-4 12:03
定時(shí)器中斷處理里面去操作定時(shí)器的開關(guān),這不是一種好的程序結(jié)構(gòu)思維。  你所預(yù)想的結(jié)果,并不一定是你希望 ...

的確在中斷函數(shù)里不應(yīng)該進(jìn)行過多操作,所以我在進(jìn)入定時(shí)器中斷函數(shù)中就把中斷給關(guān)閉了,等待按鍵處理完成后再把中斷打開。這個(gè)是不是不會(huì)對程序有什么影響呢?
回復(fù)

使用道具 舉報(bào)

ID:888259 發(fā)表于 2021-3-4 13:42 | 顯示全部樓層
15830266185 發(fā)表于 2021-3-4 11:59
做成0.5秒切換啊      比方說  menu低于50顯示 1界面  高于50顯示2界面  =100 歸0  調(diào)好計(jì)數(shù)就好

您可能沒有完全明白我的描述,我的按鍵處理是在定時(shí)器中斷中做的操作,EC11_Action()這個(gè)函數(shù)僅是檢測按鍵操作并分配一個(gè)key_num(鍵值),之后通過EC11_Scan()函數(shù)來捕獲鍵值,通過判斷鍵值來做menu的增減,menu的值實(shí)際是代表了所顯示頁面的索引。
回復(fù)

使用道具 舉報(bào)

ID:888259 發(fā)表于 2021-3-4 13:44 | 顯示全部樓層
Kxuan163 發(fā)表于 2021-3-4 13:33
建議在按鍵處理函數(shù)中添加消除抖動(dòng)的代碼。

在EC11_Action()函數(shù)中已經(jīng)做了DelayXms(5) 【5ms】的消抖了
回復(fù)

使用道具 舉報(bào)

ID:451718 發(fā)表于 2021-3-4 14:03 | 顯示全部樓層
17826075805 發(fā)表于 2021-3-4 13:38
的確在中斷函數(shù)里不應(yīng)該進(jìn)行過多操作,所以我在進(jìn)入定時(shí)器中斷函數(shù)中就把中斷給關(guān)閉了,等待按鍵處理完成 ...

定時(shí)中斷是有很高優(yōu)先級的,你在高優(yōu)先級的響應(yīng)中,處理按鍵,也就是讓主程序的都停下來,等著執(zhí)行按鍵響應(yīng),而且是一直在循環(huán)執(zhí)行。你的程序一直都在執(zhí)行中斷響應(yīng)中,還有多少資源去響應(yīng)主程序?
回復(fù)

使用道具 舉報(bào)

ID:888259 發(fā)表于 2021-3-4 14:06 | 顯示全部樓層
17826075805 發(fā)表于 2021-3-4 13:38
的確在中斷函數(shù)里不應(yīng)該進(jìn)行過多操作,所以我在進(jìn)入定時(shí)器中斷函數(shù)中就把中斷給關(guān)閉了,等待按鍵處理完成 ...

如果不采用按鍵分配鍵值的辦法,直接在EC11_Action()函數(shù)中做menu的增減操作,同樣在中斷函數(shù)中檢測,其結(jié)果就表現(xiàn)正常了。只是這樣做會(huì)影響代碼結(jié)構(gòu),在多級菜單編程時(shí)會(huì)操作會(huì)十分繁瑣。
回復(fù)

使用道具 舉報(bào)

ID:798631 發(fā)表于 2021-3-4 14:08 | 顯示全部樓層
你的 key_num 沒有歸零處理  不就是menu一直自加么
回復(fù)

使用道具 舉報(bào)

ID:888259 發(fā)表于 2021-3-4 14:16 | 顯示全部樓層
robinsonlin 發(fā)表于 2021-3-4 14:03
定時(shí)中斷是有很高優(yōu)先級的,你在高優(yōu)先級的響應(yīng)中,處理按鍵,也就是讓主程序的都停下來,等著執(zhí)行按鍵響 ...

進(jìn)入定時(shí)器中斷后,定時(shí)器關(guān)閉不再計(jì)時(shí),中斷函數(shù)可以安心處理其內(nèi)部的操作,包含按鍵檢測,LCD顯示。待處理完成后定時(shí)器再次打開,準(zhǔn)備進(jìn)入下一次中斷。main函數(shù)中的while(1)就是提供給中斷處理任務(wù)的。有中斷任務(wù)就處理,沒有的話主程序也是一直等待呀。
回復(fù)

使用道具 舉報(bào)

ID:888259 發(fā)表于 2021-3-4 14:21 | 顯示全部樓層
15830266185 發(fā)表于 2021-3-4 14:08
你的 key_num 沒有歸零處理  不就是menu一直自加么

強(qiáng)!剛試了一下,問題解決了,多謝啦。今后還請多指教。
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2021-3-4 20:51 | 顯示全部樓層
#include <REG52.h>
#include"LCD1602.h"
#include"delay.h"
#include"Level_1Menu.h"
#include"Level_2Menu.h"
#include"Level_3Menu.h"
#include"Level_4Menu.h"
#include"EC11.h"
#include"PowerMode.h"
#include"interrupt.h"
#include"relay.h"


//unsigned char menu = 0;

unsigned char  key_num = 0;

unsigned char EC11_Action()
{
        if(ENTER == 0)//判斷ENTER鍵是否按下
        {
                DelayXms(5);//延時(shí)消抖,時(shí)間一般為5-10ms
                if(ENTER == 0)
                {                       
//                        key_num = 1;//分配ENTER的鍵值為“1”
                        key_num=++key_num%2;
                        while(ENTER == 0);//等待松手
                        LCDWriteCmd(LCD_SCREEN_CLR); //清屏
                }
        }
        return key_num;       
}
/*
unsigned char EC11_Scan()
{

        switch(EC11_Action())
        {
                case 0:break;
                case 1:menu++;if(menu>1) menu = 0;break;
                default:break;
        }
        return menu;
}
*/

void LCDShowService()
{
//        switch(EC11_Scan())
        switch(EC11_Action())
        {
                case 0:BAIC_C62X();break;
                case 1:BAIC_B40();break;
                default:break;
        }       
}

void T0_Service() interrupt 1 using 0
{
        TR0=0;                 //關(guān)閉定時(shí)器
        TH0=0XFE;    //高八位賦初值500
        TL0=0x33;    //低八位賦初值
        LCDShowService();
        TR0=1;//重新開啟定時(shí)器       
}

void main()
{       
        LCDInit();
        T0_Init();
        while(1);
}

回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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