独立按键控制

独立按键消抖,下降沿读取代码模板

按键消抖的详细分析放在文章后面


/********************变量声明********************/
unsigned char Key_Val,Key_Down, Key_Up,Key_Old;//按键扫描变量   

/*******************函数区**********************/
unsigned char Key_Read()//按键读取函数
{
	unsigned char temp=0;
	if(P33 == 0) temp=1;    //对应按键按下,返回相应的Key_Read值
	if(P32 == 0) temp=2;
	if(P31 == 0) temp=3;
	if(P30 == 0) temp=4;
	return temp;
}

四行固定代码//用于消抖和下降沿触发,加在main函数里面使用
    Key_Val = Key_Read();//读取键码值
		Key_Down = Key_Val&(Key_Val ^ Key_Old);//检测下降沿
		Key_Up= ~Key_Val&(Key_Val ^ Key_Old);//检测上升沿
		Key_Old=Key_Val;//扫描辅助变量

独立按键控制LED亮灭

  • 独立按键的原理图;跳线帽接23端口时为独立键盘模式在这里插入图片描述

  • 实现原理:通过扫描IO口检测按键是否按下

  • 程序实例:

    前置函数

    #include <STC15F2K60S2.H>                
    #include "HC138.h"
    #include <intrins.H>
    
    /*********** 变量声明区*********/
    unsigned char LED=0xfe;//LED数据变量 1111 1110
    
    
    unsigned char Key_Val,Key_Down, Key_Up,Key_Old;//按键扫描变量
    
    /*************函数区***************/
    
    unsigned char Key_Read()//按键读取函数
    {
    	unsigned char temp=0;
    	if(P33 == 0) temp=1;//P33口对应的按键按下时,返回值为1
    	if(P32 == 0) temp=2;
    	if(P31 == 0) temp=3;
    	if(P30 == 0) temp=4;
    	return temp;
    }
    

主程序

void main()
{
	HC138(4);
	while(1)
	{
		Key_Val = Key_Read();//读取键码值
		Key_Down = Key_Val&(Key_Val ^ Key_Old);//检测下降沿
		Key_Up= ~Key_Val&(Key_Val ^ Key_Old);//检测上升沿
		Key_Old=Key_Val;//扫描辅助变量
		
		switch (Key_Down)
		{
			case(1)://按键返回值为1时,P00低电平,L1亮
			P00=0;
			break;
			case(2)://按键返回值为2时,P01低电平,L2亮
			P01=0;
			break;
			case(3)://按键返回值为3时,P00高电平,L1灭
			P00=1;
			break;
			case(4)://按键返回值为4时,P01高电平,L2灭
			P01=1;
			break;
		}
	}
}

独立按键控制流水灯速度

  • 实现原理:
    1. 用独立按键控制流水灯的开启与暂停
      注:由于使用Delay()函数,在延时较高的情况下可能会出现,按键按下无法控制的情况,这是因为在执行Delay()函数时,无法对按键进行检测。并非程序没有消抖。
    2. 通过独立按键控制time变量,从而改变延时
  • 程序实例:
    void main()
    {
    	HC138(4);//打开Y4使得P0口电平信息能传递给LED
    	while(1)  
    	{
    		Key_Val = Key_Read();//读取键码值
    		Key_Down = Key_Val&(Key_Val ^ Key_Old);//检测下降沿
    		Key_Up= ~Key_Val&(Key_Val ^ Key_Old);//检测上升沿
    		Key_Old=Key_Val;//扫描辅助变量
    		
    		P0=LED;
    		Delay(time);
    		if(flag == 1)//暂停标志位为1时,开始位移
    		{
    			LED = _crol_(LED,1);
    		}
    		
    		switch(Key_Down)
    		{
    			case(1):
    				flag=1;//按键1按下,开始位移
    			break;
    			case(2):
    				flag=0;//按键2按下,停止位移
    			break;
    			case(3):
    			if(time!=50)//最小间隔为50ms,在此间隔情况下按下按键,间隔不变
    			{
    				time=time-50;//按键3按下,流速加快,间隔缩短0.05s
    			}				
    			break;
    			case(4):
    				time=time+50;//按键4按下,流速放缓,间隔增加0.05s
    			break;
    		}
    	}
    }
    
    


(蓝桥杯题目)LED彩灯控制系统

  • 彩灯运行模式:
  1. Led1-Led2-Led3-Led4-Led5-Led6-Led7-Led8
  2. Led8-Led7-Led6-Led5-Led4-Led3-Led2-Led1
  3. Led1+Led8-Led2+Led7-Led3+Led6-Led4+Led5
  4. Led4+Led5-Led3+Led6-Led2+Led7-Led1+Led8
  • 功能定义:

    S1 启动

    S2暂停

    S3运行模式+1 模式4后返回1

    S4运行模式-1 模式1后返回4

  • 初始化:

    上电默认为模式1-启动,固定流转时间为500ms

  • 程序实例:
    由于延时500,会导致暂停时大概率暂停失败,下面代码中的延时均为50ms

    #include <STC15F2K60S2.H>
    #include <HC138.H>
    #include <intrins.H>
    
    /**********************变量声明**********************/
    unsigned char LED_date=0xfe;//LED数据变量 1111 1110
    unsigned char LED_date34[4] = {0x7e,0xbd,0xdb,0xe7};//18,27,36,45
    unsigned char LED_date34index;
    unsigned char LED_mode=1;//LED_mode初值为1
    
    unsigned char Key_Val,Key_Down, Key_Up,Key_Old;//按键扫描变量
    //unsigned int time=100;
    bit flag=1;//开始暂停标志位
    
    /*************函数区***************/
    unsigned char Key_Read()
    {
    	unsigned char temp=0;
    	if(P33==0) temp=1;
    	if(P32==0) temp=2;
    	if(P31==0) temp=3;
    	if(P30==0) temp=4;
    return temp;
    }
    
    void Delay(unsigned int x)	//@11.0592MHz
    {	
    	unsigned char data i, j;
    	while(x--)
    	{
    		_nop_();
    		_nop_();
    		_nop_();
    		i = 11;
    		j = 190;
    		do
    		{
    			while (--j);
    		} while (--i);
    	}
    
    }
    
    void main ()
    {
    	HC138(4);
    	while(1)
    	{
    		Key_Val = Key_Read();//读取键码值
    		Key_Down = Key_Val&(Key_Val ^ Key_Old);//检测下降沿
    		//Key_Up= ~Key_Val&(Key_Val ^ Key_Old);//检测上升沿
    		Key_Old=Key_Val;//扫描辅助变量
    		
    		switch(Key_Down)//按键功能
    		{
    			case(1):
    				flag=1;//开始
    			break;
    			case(2):
    				flag=0;//暂停
    			break;
    			case(3)://LEd模式数加1
    				if(LED_mode==4)
    				{
    					LED_mode=1;
    				}
    				else
    				{
    					LED_mode++;
    				}
    			break;
    			case(4)://LED模式数减1
    				if(LED_mode == 1)
    				{
    					LED_mode=4;
    				}
    				else
    				{
    					LED_mode--;
    				}
    			break;
    		}	
    			if(flag == 1)//判断是否开启
    			{
    				switch(LED_mode)//检查LED工作模式
    				{
    					case(1):
    					P0 = LED_date;
    					Delay(50);
    					LED_date = _crol_(LED_date,1);//左移位
    					break;
    					case(2):
    						P0 = LED_date;
    						Delay(50);
    						LED_date = _cror_(LED_date,1);//右移位
    					break;
    					case(3):
    					P0=LED_date34[LED_date34index];//使用数组,两边向中间
    					Delay(50);
    					if(LED_date34index==3)
    					{
    						LED_date34index=0;
    					}
    					else
    					{
    						LED_date34index++;
    					}
    					break;
    					case(4):
    					P0=LED_date34[LED_date34index];//中间向两边
    					Delay(50);
    					if(LED_date34index==0)
    					{
    						LED_date34index=3;
    					}
    					else
    					{
    						LED_date34index--;
    					}
    					break;
    				}
    					
    			}				
    		}
    		 
    	}
    
    
  • 演示视频:

    LED彩灯控制系统演示

  • 49
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个基于C51单片机的独立按键控制数码管的例子。 ``` #include <reg51.h> //包含头文件 #define uchar unsigned char //宏定义uchar为unsigned char sbit LSA=P2^2; //定义数码管连接的引脚,从左到右分别为LSA、LSB、LSC、DIO、CLK sbit LSB=P2^3; sbit LSC=P2^4; sbit DIO=P2^0; sbit CLK=P2^1; uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //定义显示0~9的编码 void delay(uchar i) //延时函数 { uchar j,k; for(j=i;j>0;j--) { for(k=110;k>0;k--); } } void main() { uchar i=0,j=0,k=0; //定义三个计数器 while(1) //循环 { if(P3!=0xff) //判断是否有按键按下 { delay(5); //消除抖动 if(P3!=0xff) //再次判断是否有按键按下 { switch(P3) //根据按键进行操作 { case(0xfe): //第一个按键按下 i++; //计数器i加1 if(i>9) //当计数器i大于9时,i清零 { i=0; } break; case(0xfd): //第二个按键按下 j++; //计数器j加1 if(j>9) //当计数器j大于9时,j清零 { j=0; } break; case(0xfb): //第三个按键按下 k++; //计数器k加1 if(k>9) //当计数器k大于9时,k清零 { k=0; } break; default: break; } } } LSA=0; //锁存器清零 LSB=0; LSC=0; P0=table[i]; //P0口输出i对应的编码值 delay(5); //延时 LSA=1; //锁存器锁存 P0=0x00; //P0口清零 LSA=0; //锁存器清零 LSB=1; //同上 P0=table[j]; delay(5); LSB=0; LSC=1; //同上 P0=table[k]; delay(5); LSC=0; } } ``` 在该程序中,我们将P2口的第2、3、4、0、1个引脚分别连接到数码管的LSA、LSB、LSC、DIO、CLK引脚上。在程序中通过一个计数器来控制数码管的显示,同时通过三个独立按键来分别对三个计数器进行操作,从而实现对数码管的控制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值