找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

C51单片机问题请教,通过按键操作控制LCD1602的显示循环显示两个页面[已解决]

查看数: 4538 | 评论数: 17 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2021-3-4 11:11

正文摘要:

这个问题困扰了我很久,十几天都没有解决,希望有站内大佬帮我一下。 1.问题描述: 通过按键操作控制LCD1602的显示循环显示两个页面。现有的现象是程序开始时,LCD屏保持在第一个页面不变,但是按动(按下再抬起) ...

回复

ID:213173 发表于 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);//延时消抖,时间一般为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;                 //关闭定时器
        TH0=0XFE;    //高八位赋初值500
        TL0=0x33;    //低八位赋初值
        LCDShowService();
        TR0=1;//重新开启定时器       
}

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

ID:888259 发表于 2021-3-4 14:21
15830266185 发表于 2021-3-4 14:08
你的 key_num 没有归零处理  不就是menu一直自加么

强!刚试了一下,问题解决了,多谢啦。今后还请多指教。
ID:888259 发表于 2021-3-4 14:16
robinsonlin 发表于 2021-3-4 14:03
定时中断是有很高优先级的,你在高优先级的响应中,处理按键,也就是让主程序的都停下来,等着执行按键响 ...

进入定时器中断后,定时器关闭不再计时,中断函数可以安心处理其内部的操作,包含按键检测,LCD显示。待处理完成后定时器再次打开,准备进入下一次中断。main函数中的while(1)就是提供给中断处理任务的。有中断任务就处理,没有的话主程序也是一直等待呀。
ID:798631 发表于 2021-3-4 14:08
你的 key_num 没有归零处理  不就是menu一直自加么
ID:888259 发表于 2021-3-4 14:06
17826075805 发表于 2021-3-4 13:38
的确在中断函数里不应该进行过多操作,所以我在进入定时器中断函数中就把中断给关闭了,等待按键处理完成 ...

如果不采用按键分配键值的办法,直接在EC11_Action()函数中做menu的增减操作,同样在中断函数中检测,其结果就表现正常了。只是这样做会影响代码结构,在多级菜单编程时会操作会十分繁琐。
ID:451718 发表于 2021-3-4 14:03
17826075805 发表于 2021-3-4 13:38
的确在中断函数里不应该进行过多操作,所以我在进入定时器中断函数中就把中断给关闭了,等待按键处理完成 ...

定时中断是有很高优先级的,你在高优先级的响应中,处理按键,也就是让主程序的都停下来,等着执行按键响应,而且是一直在循环执行。你的程序一直都在执行中断响应中,还有多少资源去响应主程序?
ID:888259 发表于 2021-3-4 13:44
Kxuan163 发表于 2021-3-4 13:33
建议在按键处理函数中添加消除抖动的代码。

在EC11_Action()函数中已经做了DelayXms(5) 【5ms】的消抖了
ID:888259 发表于 2021-3-4 13:42
15830266185 发表于 2021-3-4 11:59
做成0.5秒切换啊      比方说  menu低于50显示 1界面  高于50显示2界面  =100 归0  调好计数就好

您可能没有完全明白我的描述,我的按键处理是在定时器中断中做的操作,EC11_Action()这个函数仅是检测按键操作并分配一个key_num(键值),之后通过EC11_Scan()函数来捕获键值,通过判断键值来做menu的增减,menu的值实际是代表了所显示页面的索引。
ID:888259 发表于 2021-3-4 13:38
robinsonlin 发表于 2021-3-4 12:03
定时器中断处理里面去操作定时器的开关,这不是一种好的程序结构思维。  你所预想的结果,并不一定是你希望 ...

的确在中断函数里不应该进行过多操作,所以我在进入定时器中断函数中就把中断给关闭了,等待按键处理完成后再把中断打开。这个是不是不会对程序有什么影响呢?
ID:858964 发表于 2021-3-4 13:33
建议在按键处理函数中添加消除抖动的代码。
ID:451718 发表于 2021-3-4 12:03
定时器中断处理里面去操作定时器的开关,这不是一种好的程序结构思维。  你所预想的结果,并不一定是你希望得到的。  这样搞,不可预料的状态太多了,不是定时器的正确用法
ID:798631 发表于 2021-3-4 11:59
做成0.5秒切换啊      比方说  menu低于50显示 1界面  高于50显示2界面  =100 归0  调好计数就好
ID:888259 发表于 2021-3-4 11:54
15830266185 发表于 2021-3-4 11:51
中断是5ms一次             case 1:menu++;if(menu>1) menu = 0;break;  这句   menu反转就是10ms

我刚调整的定时中断时间为50ms,现象还是一样的。只是页面切换的没有那么快了。
ID:798631 发表于 2021-3-4 11:51
中断是5ms一次             case 1:menu++;if(menu>1) menu = 0;break;  这句   menu反转就是10ms   
ID:888259 发表于 2021-3-4 11:43
15830266185 发表于 2021-3-4 11:38
menu 的反转太快了   把反转速度降下来啊

您的意思是中断的时间太短了吗?我这边中断是5ms一次的,能否具体指明一下呢?谢谢啦
ID:888259 发表于 2021-3-4 11:40
问题补充:如果直接在EC11_Action()函数直接中做menu变量的增减操作,然后再中断函数中用switch函数处理menu的值,程序就没有问题。
ID:798631 发表于 2021-3-4 11:38
menu 的反转太快了   把反转速度降下来啊

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

Powered by 单片机教程网

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