STC15F2K60S2学习笔记3——独立按键

目录

1.独立按键原理图

2.独立按键原理

 3.编程实现:统计S4按下次数

3.1.判断按键是否按下函数

3.2.按键处理函数

3.3.数码管函数

3.4.外设控制函数

3.5主函数


1.独立按键原理图

STC15F2K60S2中的按键有独立按键和矩阵按键两个模式,J5跳冒控制按键模式。当J5跳冒接在23口时该按键处于独立按键模式(BTN模式),当J5跳冒接在12口时该按键处于矩阵按键模式(KBD模式)。这里,我们需要将J5跳冒接在23口实现独立按键模式。

2.独立按键原理

以S7按下为例。当S7按下时,按键两端导通。由于S7左端接的GND,导通后P30口即为低电平。于是,当单片机判断一个按键是否按下时,只需检测连接该按键的端口是否为低电平即可。但是,在实际操作中,会伴随这按键的抖动。于是我们要对按键进行消抖处理,才可精确判断按键是否按下。

 3.编程实现:统计S4按下次数

思路:在while(1)内循环换:

①读取P33状态

②如果是0,则等待10ms,再读取P33状态

③如果还是0,确定有按键按下;则执行number++;让数码管数字+1

   如果不是0,则说明是抖动;则不执行任何程序

④等待按键弹起后,再等待10ms,从①再开始执行

3.1.判断按键是否按下函数

这里我们使用的是状态机法,程序代码如下:

//独立按键状态机法
#define KEY_NO   0  //无按键状态,用于判断是否按下
#define KEY_DOWN 1	//有按键按下状态,判断是否为抖动
#define KEY_UP   2	//等待松手状态,判断是否弹起

u8 vBTN_Read(void)	//10ms执行一次
{
	static u8 key_state=0; //定义key_state为静态变量,用于保存每次按键状态
	u8 key_io=0,key_val=0;	//key_io:读取IO口的状态;key_val:返回键值;
	
	key_io=P3&0x0f;				//对P3读回来的高4位IO口清0,屏蔽不关心的IO口状态
	switch(key_state)
	{
		case KEY_NO:					//无按键状态,用于判断是否按下
			if(key_io!=0x0f) key_state=KEY_DOWN;
		break;
		
		case KEY_DOWN:				//有按键按下状态,判断是否为抖动
			if(key_io!=0x0f)
			{
				if(key_io==0x0e) key_val=7;		//S7
				if(key_io==0x0d) key_val=6;		//S6
				if(key_io==0x0b) key_val=5;		//S5
				if(key_io==0x07) key_val=4;		//S4
				key_state=KEY_UP;
			}
			else
				key_state=KEY_NO;
		break;
			
		case KEY_UP:						//等待松手状态,判断弹起
			if(key_io==0x0f) key_state=KEY_NO;
		break;
	}
	return key_val;
}

3.2.按键处理函数

u8 cnt_key;  //定义按键计时变量,在定时器中计时
u8 s4_number;//定义用来保存S4按下的次数变量
void vBTN_Process(void)
{
	u8 key_val;
	if(cnt_key>=10)  //10MS进行一次读取
	{
		cnt_key=0;
		key_val=vBTN_Read(); //读取按键的键值
		if(key_val==4)
		{
			s4_number++;
		}
	}
}

3.3.数码管函数

//共阴数码管码表
u8 smg_code[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

//数码管操作函数
u8 smg_buf[8];
void vSMG_Process()
{
	smg_buf[0]=smg_code[s4_number/100];
	smg_buf[1]=smg_code[s4_number/10%10];
	smg_buf[2]=smg_code[s4_number%10];
	smg_buf[3]=0x00;
	smg_buf[4]=0x00;
	smg_buf[5]=0x00;
	smg_buf[6]=0x00;
	smg_buf[7]=0x00;
}

//数码管显示函数
void vSMG_Display()
{
	static u8 i=0;
	vDevice_Ctrl(0xc0,0);   //位选(消除鬼影)
	vDevice_Ctrl(0xe0,~smg_buf[i]);   //段选
	vDevice_Ctrl(0xc0,0x01<<i);   //位选
	i=(i+1)%8;
}

3.4.外设控制函数

#include "Device.h"

/**
  * @brief 外设控制函数
  * @param None
  * @retval None
  */
void vDevice_Ctrl(unsigned char P2data,unsigned char P0data)
{
	P0=P0data;
	P2=P2data;
	P2=0;
}

3.5主函数

#include "system.h"
#include <intrins.h>
#include "Device.h"

HexToBin led_ctrl,uln_ctrl;

/**
	* @brief 系统初始化函数:关闭继电器、蜂鸣器
  * @param None
  * @retval None
  */

void vSystem_Init(void)
{
	vDevice_Ctrl(0xa0,0);      /*关闭蜂鸣器、继电器*/
	led_ctrl.hex=0xff;
	vDevice_Ctrl(0x80,led_ctrl.hex);	/*关闭LED*/
}

void Timer2Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟12T模式
	T2L = 0x20;		//设置定时初值
	T2H = 0xD1;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	IE2|=0x04;      //开定时器2中断
	EA=1;
}

void main(void)
{
	vSystem_Init();
	Timer2Init();
	while(1)
	{
		vSMG_Process();
		vBTN_Process();
	}
}

//中断服务程序
void vTimer2_ISR() interrupt  12 //中断入口
{
	cnt_key++;
	vSMG_Display();
}

注意事项:1.每次按键按下需要单次触发

                  2.需要有松手检测

                  3.不用delay延时堵塞程序

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值