找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1946|回复: 7
收起左侧

为什么我的单片机按键松手检测没有效果?这个代码我在另外一个项目中是可以用的,...

[复制链接]
回帖奖励 15 黑币 回复本帖可获得 5 黑币奖励! 每人限 1 次
ID:602220 发表于 2020-1-15 17:37 | 显示全部楼层 |阅读模式
#include<reg52.h>
#include"key.h"

#define uchar unsigned char
#define uint unsigned int


/*******************************************************************************
* 函 数 名         : key
* 函数功能       : 扫描四个独立按键并消抖
* 输    入         : 无
* 输    出         : key_can
* 说    明         :
*******************************************************************************/
void key()
{
//key_new 通过消抖后得到的按键新值, key_old 按键旧值 ,key_value 按键标志位,用于消抖
if(key_new ==0) //检测按键是否已经松开
{
  if((key_io & 0x0f) == 0x0f)  //如果按键全为1,则按键与全部松开
   key_value ++;
   else
   key_value = 0;
  if(key_value >=5)
  {
   key_value = 0;
   key_new = 1;
  }
}
else
{
  if((key_io & 0x0f) != 0x0f)    //用于检测是否有按键按下,若消抖后确定存在则key_new 清零等待松手信号
   key_value ++;
  else
   key_value = 0;
  if(key_value >= 5)
  {
   key_value = 0;
   key_new = 0;
  }
}
  key_can = 0;
        if((key_new == 0) && (key_old == 1))//若原本是旧按键信号是松手,新按键信号是有按键按下则判断是那个键被按下
        {
                switch(key_io & 0x0f)
                {
                        case 0x0e: key_can = 1; break;          //得到按键值
                        case 0x0d: key_can = 2; break;          //得到按键值
                        case 0x0b: key_can = 3; break;   
            case 0x07: key_can = 4; break;//得到按键值
                }
        }                        
        key_old = key_new;         
}

********************************************************************************************************

#include<reg52.h>
#include<string.h>
#include"key.h"
#include"LCD1602.h"
#include"main.h"

void main(void)
{
unsigned char  j;
unsigned char  time[4]={'0','0','0','0'};
unsigned char weight[4]={'0','0','X','X'};

LcdInit();
Init_time0();

while(1)
{
  switch(flag_window)
  {
   case 0x00 :
   
   strcpy(first_line,"   Smart   Bin   ");
   strcpy(second_line," Please  Select ");   
   Lcd_first_line(first_line);
   Lcd_second_line(second_line) ;
  
   switch(key_can)
   {
   case 1:  
    flag_window = 0x01;break;
   case 2:
     flag_window = 0x02;break;
   case 3:
    flag_window = 0x03;break;
   case 4:flag_full=1;break;
   default :flag_window = 0x00  ;break;
   }  
   
   break;
   
   case 0x01:
   
   strcpy(first_line,"Open Speed:     ");
   strcpy(second_line,"+  -  Sure  Back");   
   Lcd_first_line(first_line);
   Lcd_second_line(second_line);
   j=1;

   while(j)
   {
    LcdWriteCom(0x8C);
    LcdWriteData(open_v_bf);
   
    switch(key_can)
    {
     case 1:if(open_v_bf<'9')LcdWriteData(++open_v_bf);
      flag_window = 0x01;break;
     case 2:
      if(open_v_bf>'0')LcdWriteData(--open_v_bf);
      flag_window = 0x01;break;
     case 3:
      open_v = (open_v_bf-30);LcdWriteCom(0x8E);LcdWriteData('O');LcdWriteCom(0x8F);LcdWriteData('K');
      flag_window = 0x01;break;
     case 4:flag_window = 0x00;j=0;break;
     default :flag_window = 0x01 ; break;
    }
         
   }
   
   break;
   
    case 0x02:
   strcpy(first_line,"Band up Standard");
    strcpy(second_line," H  T  W   Back ");
   Lcd_first_line(first_line);   
   Lcd_second_line(second_line);
  
   switch(key_can)
  {
   case 1:  
    flag_window = 0x04;break;
   case 2:
    flag_window = 0x05;break;
   case 3:
    flag_window = 0x06;break;
   case 4:flag_window = 0x00;break;
   default :flag_window = 0x02 ; break;         
  }

  
  break;  
  case 0x03 :
  strcpy(first_line,"Envelop Strength");
  strcpy(second_line," H  M  L Back   ");  
  Lcd_first_line(first_line);
  Lcd_second_line(second_line);
  
   switch(key_can)
   {
   case 1:rub_he =10 ;flag_window = 0x03;LcdWriteCom(0xCE);LcdWriteData('O');LcdWriteCom(0xCF);LcdWriteData('K');Delay();
    break;
   case 2:rub_he =20 ;flag_window = 0x03;LcdWriteCom(0xCE);LcdWriteData('O');LcdWriteCom(0xCF);LcdWriteData('K');Delay();
    break;
   case 3:rub_he =30 ;flag_window = 0x03;LcdWriteCom(0xCE);LcdWriteData('O');LcdWriteCom(0xCF);LcdWriteData('K');Delay();
    break;
   case 4:flag_window = 0x00;break;
   default :flag_window = 0x03 ; break;
   }
  
  
  break;
  
   case 0x04 :
  strcpy(first_line,"Garbage Height  ");
  strcpy(second_line,"Max Med Min Back");
  Lcd_first_line(first_line);
  Lcd_second_line(second_line);
  

  switch(key_can)
  {
  case 1:rub_he =10 ;flag_window = 0x04;LcdWriteCom(0x8E);LcdWriteData('O');LcdWriteCom(0x8F);LcdWriteData('K');Delay();
   break;
  case 2:rub_he =20 ;flag_window = 0x04;LcdWriteCom(0x8E);LcdWriteData('O');LcdWriteCom(0x8F);LcdWriteData('K');Delay();
   break;
  case 3:rub_he =30 ;flag_window = 0x04;LcdWriteCom(0x8E);LcdWriteData('O');LcdWriteCom(0x8F);LcdWriteData('K');Delay();
   break;
  case 4:flag_window = 0x02;break;
  default :flag_window = 0x04 ; break;
  }
   
  
  break;
  
  case 0x05 :
  strcpy(first_line,"Hour:  Min:     ");
  strcpy(second_line,"   +  -  OK Back");
  Lcd_first_line(first_line);
  Lcd_second_line(second_line);
  
  for(j=0;j<4&&j>=0;)
  {
   LcdWriteCom(0x85);LcdWriteData(time[0]);
   LcdWriteCom(0x86);LcdWriteData(time[1]);
   LcdWriteCom(0x8B);LcdWriteData(time[2]);
   LcdWriteCom(0x8C);LcdWriteData(time[3]);
   
   switch(j)
   {
    case 0:LcdWriteCom(0x85);break;
    case 1:LcdWriteCom(0x86);break;
    case 2:LcdWriteCom(0x8B);break;
    case 3:LcdWriteCom(0x8C);break;
    default:break;
   }
  
   switch(key_can)
   {
   case 1:
   if(j!=2){if(time[j]<'9')++time[j];}else{if(time[j]<'6')++time[j];}  
   flag_window = 0x05;break;                     
   case 2:if(time[j]>'0')--time[j];
   flag_window = 0x05;break;
   case 3:time_set[j]=time[j];j++;
   flag_window = 0x05;break;
   case 4:j--;
   flag_window = 0x05;break;
   default :flag_window = 0x05; break;
   }
   
  }
   if(j==4)
   {  
    LcdWriteCom(0x8E);LcdWriteData('O');LcdWriteCom(0x8F);LcdWriteData('K');
   }
   else
   {
   LcdWriteCom(0x8E);LcdWriteData('C');LcdWriteCom(0x8F);LcdWriteData('C');
   time_set[0]=time_set[1]=time_set[2]=time_set[3]='0';  
   }
  Delay();
   hour_set =  (time_set[0]-30)*10+(time_set[1]-30);
   min_set =  (time_set[2]-30)*10+(time_set[3]-30);
   flag_window = 0x02; break;
   
  case 0x06:
  strcpy(first_line," . <Weight< .   ");
  strcpy(second_line,"+  -  Sure  Back");   
  Lcd_first_line(first_line);
  Lcd_second_line(second_line);
  
  for(j=0;j<4&&j>=0;)
  {
   LcdWriteCom(0x80);LcdWriteData(weight[0]);
   LcdWriteCom(0x82);LcdWriteData(weight[1]);
   LcdWriteCom(0x8B);LcdWriteData(weight[2]);
   LcdWriteCom(0x8D);LcdWriteData(weight[3]);
   
  switch(j)
  {
   case 0:LcdWriteCom(0x80);break;
   case 1:LcdWriteCom(0x82);break;
   case 2:LcdWriteCom(0x8B);break;
   case 3:LcdWriteCom(0x8D);break;
   default:break;
  }
  
  switch(key_can)
   {
  case 1:if(weight[j]<'9')LcdWriteData(++weight[j]);else LcdWriteData(weight[j]='X');
  flag_window = 0x06;break;                     
  case 2:if(weight[j]>'0'&&weight[j]!='X')LcdWriteData(--weight[j]); if(weight[j]=='X') LcdWriteData(weight[j]='9');
  flag_window = 0x06;break;
  case 3:weight_set[j]=weight[j];j++;
  flag_window = 0x06;break;
  case 4:j--;
  flag_window = 0x06;break;
  default :flag_window = 0x06; break;
  }
   
  }
    if(j==4)
   {  
     LcdWriteCom(0x8E);LcdWriteData('O');LcdWriteCom(0x8F);LcdWriteData('K');
     if(weight_set[0]!='X'&&weight_set[1]!='X')
     weight_min = (weight_set[0]-30)+(weight_set[1]-30)/10;
    else
     weight_min = 10000;
    if(weight_set[2]!='X'&&weight_set[3]!='X')
     weight_max = (weight_set[2]-30)+(weight_set[3]-30)/10;
    else
     weight_max = 10000;
   }
   else
   {
    LcdWriteCom(0x8E);LcdWriteData('C');LcdWriteCom(0x8F);LcdWriteData('C');
    weight_set[0]=weight_set[1] ='0';weight_set[2]=weight_set[3] = 'X';
     weight_min = 0.0;
    weight_max = 10000;
   }
   
  Delay();
   flag_window = 0x02;break;
   default :flag_window = 0x00 ; break;
  }
}
}
void Delay() // 12M晶振1s延时
{
unsigned char h, i, j, k;
for (h = 5; h > 0; h--)
for (i = 4; i > 0; i--)
for (j = 116; j > 0; j--)
for (k = 214; k > 0; k--);
}

void Init_time0(void)
{
TMOD &= 0XF0;
TMOD |= 0X01;
TH0 = 0XD8; //5MS定时
TL0 = 0XF0;
TR0 = 1;
ET0 = 1;
EA =  1;
}

void Interrupt_time0(void) interrupt 1
{
TH0 = 0XD8; //5MS定时
TL0 = 0XF0;
key();
}
回复

使用道具 举报

ID:258566 发表于 2020-1-15 21:55 | 显示全部楼层
主程序中的WHILE 1 循环一圈需要多长时间,如果大于定时器值,注释掉key_can = 0;
回复

使用道具 举报

ID:275826 发表于 2020-1-15 22:15 | 显示全部楼层
你的按键扫描程序太复杂了,一般只要三条语句
回复

使用道具 举报

ID:473159 发表于 2020-1-16 10:57 | 显示全部楼层
如果同你说在别的芯片上能正常运行,只能说明你这里代码的时间没有调节好,先将时间调到相似试试
回复

使用道具 举报

ID:602220 发表于 2020-1-17 09:47 | 显示全部楼层
好的,谢谢各位了,我试试看,新手上路,一些东西都不懂
回复

使用道具 举报

ID:602220 发表于 2020-1-17 09:49 | 显示全部楼层
tyrl800 发表于 2020-1-15 22:15
你的按键扫描程序太复杂了,一般只要三条语句

因为在主程序里面有一些地方在一个窗口内需要不断循环,在不同的窗口时间不一样,之前使用的延时在不同窗口下灵敏度不同,所以想着用松手检测可以让灵敏度相对一致。您有什么好的建议吗?刚刚学习,不算很懂
回复

使用道具 举报

ID:602220 发表于 2020-1-17 09:50 | 显示全部楼层
yoxi 发表于 2020-1-16 10:57
如果同你说在别的芯片上能正常运行,只能说明你这里代码的时间没有调节好,先将时间调到相似试试

好的,谢谢,我试试,刚刚学习,对时间上把握比较不好
回复

使用道具 举报

ID:602220 发表于 2020-1-17 09:51 | 显示全部楼层
cccc888 发表于 2020-1-15 21:55
主程序中的WHILE 1 循环一圈需要多长时间,如果大于定时器值,注释掉key_can = 0;

好的,谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

Powered by 单片机教程网

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