库函数版独立按键用位运算方式实现(STC8)

位运算:更加简便,单片机的内存就小,占的内存空间小一点

案例:

c 复制代码
#include    "GPIO.h"
#include	"Delay.h"
#include 	"UART.h"	// 串口配置 UART_Configuration
#include 	"NVIC.h"	// 中断初始化NVIC_UART1_Init
#include 	"Switch.h"  // 引脚切换 UART1_SW_P30_P31

// 宏定义按键
#define     KEY1    P51
#define     KEY2    P52
#define     KEY3    P53
#define     KEY4    P54
// 按下抬起状态宏
#define     DOWN    0
#define     UP      1

/*
位运算:节省内存      抬起是1  按下是0
u8 last_state = 0x0f;  // 0b0000 1111
    0x0f 
            b3   b2  b1  b0   第几位
    0b0000  1    1   1   1 
            k4   k3  k2  k1   标志第几个按键

如何知道第1个按键是按下还是抬起,取出第0位
如果第0位是1,那么第1个按键是抬起
如果第0位是0,那么第1个按键是按下

如何设置第1个按键为按下或抬起,给第0位置0或置1
设置第1个按键为抬起, 给第0位置1
设置第1个按键为按下, 给第0位置0
*/
// 位运算:节省内存      抬起是1  按下是0
u8 last_state = 0x0f;  // 0b0000 111

// 宏定义的函数
#define     IS_KEY_UP(i)      ((last_state >> i & 1) == 1)
#define     IS_KEY_DOWN(i)    ((last_state >> i & 1) == 0)
#define     SET_KEY_UP(i)     (last_state |= (1 << i))
#define     SET_KEY_DOWN(i)   (last_state &= ~(1 << i))

void GPIO_config() { 
    GPIO_InitTypeDef info;
	// ===== UART1  P30  P31  准双向
    info.Mode = GPIO_PullUp; 				// 准双向
    info.Pin = GPIO_Pin_0 | GPIO_Pin_1;   	// 引脚
    GPIO_Inilize(GPIO_P3, &info);

    //准双向口	P51 P52 P53 P54
    P5_MODE_IO_PU(GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4);
}

// 串口配置函数的定义
void UART_config(void) {
	// >>> 记得添加 NVIC.c, UART.c, UART_Isr.c <<<
    COMx_InitDefine		COMx_InitStructure;					//结构定义
    COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;	//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
    COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;			//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
    COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200
    COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允许,   ENABLE或DISABLE
    COMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLE
    UART_Configuration(UART1, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4

  	NVIC_UART1_Init(ENABLE,Priority_1);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
    UART1_SW(UART1_SW_P30_P31);		// 引脚选择, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}

void main() {
	EA = 1; // 使能中断总开关
	
    GPIO_config(); // GPIO配置
	UART_config(); // 串口配置
	
    while (1){
        // =================KEY1===============
        // 上一次和当前不同,才能进入条件
        if (IS_KEY_UP(0) && KEY1 == DOWN) { // 上一次是抬起,当前是按下,按下才有效
            SET_KEY_DOWN(0); // 上一次状态需要更新
            printf("key1按下\n");
        } else if (IS_KEY_DOWN(0) && KEY1 == UP) { // 上一次是按下,当前是抬起,抬起才有效
            SET_KEY_UP(0); // 上一次状态需要更新
            printf("key1抬起\n");
        }
        
        // =================KEY2===============
        // 上一次和当前不同,才能进入条件
        if (IS_KEY_UP(1) && KEY2 == DOWN) { // 上一次是抬起,当前是按下,按下才有效
            SET_KEY_DOWN(1); // 上一次状态需要更新
            printf("key2按下\n");
        } else if (IS_KEY_DOWN(1) && KEY2 == UP) { // 上一次是按下,当前是抬起,抬起才有效
            SET_KEY_UP(1); // 上一次状态需要更新
            printf("key2抬起\n");
        }
        
        // =================KEY3===============
        // 上一次和当前不同,才能进入条件
        if (IS_KEY_UP(2) && KEY3 == DOWN) { // 上一次是抬起,当前是按下,按下才有效
            SET_KEY_DOWN(2); // 上一次状态需要更新
            printf("key3按下\n");
        } else if (IS_KEY_DOWN(2) && KEY3 == UP) { // 上一次是按下,当前是抬起,抬起才有效
            SET_KEY_UP(2); // 上一次状态需要更新
            printf("key3抬起\n");
        }
        
        // =================KEY4===============
        // 上一次和当前不同,才能进入条件
        if (IS_KEY_UP(3) && KEY4 == DOWN) { // 上一次是抬起,当前是按下,按下才有效
            SET_KEY_DOWN(3); // 上一次状态需要更新
            printf("key4按下\n");
        } else if (IS_KEY_DOWN(3) && KEY4 == UP) { // 上一次是按下,当前是抬起,抬起才有效
            SET_KEY_UP(3); // 上一次状态需要更新
            printf("key4抬起\n");
        }
		
		delay_ms(50); // 适当的延时,很有必要的,作用1:去抖动
    }  
}
相关推荐
元器件BOM超人2 小时前
STM32F103和GD32F103怎么选?
stm32·单片机·gd32
HRTOS3 小时前
HRTOS 4.0 本轮测试与升级工作阶段性总结
经验分享·单片机·嵌入式硬件·51单片机
kkkkkkkkkk_Z3 小时前
新手自学嵌入式 | 学习日记:EPIT/GPT定时器、输入捕获与PWM、UART通信与Modbus协议
单片机·gpt·学习
笨笨饿4 小时前
#142_VS Code.map文件插件的用法
git·python·stm32·单片机·嵌入式硬件·物联网·vim
三佛科技-187366133974 小时前
HN62512是什么芯片?HN62512多规格5V/12V500mA,24V350mA芯片解析
单片机·嵌入式硬件
早八晚十啊4 小时前
双MCU架构:基于视觉反馈的简易自行瞄准装置(激光云台控制)
单片机·嵌入式硬件
恒锐丰科技林技术员4 小时前
EG27517 高速低侧单通道栅极驱动芯片解析
经验分享·嵌入式硬件·硬件工程
铅笔小新z5 小时前
【stm32】RTC(实时时钟)
stm32·单片机·实时音视频
Yiran_G5 小时前
LoRa数据帧设计与工程实现:地址、长度、校验及版本兼容
网络·嵌入式硬件·物联网
糖糖单片机设计5 小时前
基于 STM32 的风力发电机控制系统
stm32·单片机·嵌入式硬件