库函数版独立按键用位运算方式实现(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:去抖动
    }  
}
相关推荐
我怕是好3 小时前
STM32 输入捕获,串口打印,定时器,中断综合运用
stm32·单片机·嵌入式硬件
国科安芯4 小时前
质子试验:守护芯片安全的关键防线
嵌入式硬件·安全·fpga开发·性能优化·硬件架构
zhmc6 小时前
MCU程序的ARM-GCC编译链接
arm开发·单片机·嵌入式硬件
点灯小铭7 小时前
基于STM32单片机的OneNet物联网环境检测系统
stm32·单片机·物联网·毕业设计·课程设计
滴啦嘟啦哒9 小时前
【从0到1制作一块STM32开发板】5. 整体布局
stm32·单片机·嵌入式硬件
普中科技15 小时前
【普中STM32精灵开发攻略】--第 11 章 SysTick系统定时器
stm32·单片机·嵌入式硬件·物联网·arm·普中科技
李夕15 小时前
掌握工程化固件烧录,开启你的技术进阶之路-FPGA ISE(xilinx)
嵌入式硬件·fpga·固件
Hello_Embed17 小时前
STM32HAL 快速入门(二):用 CubeMX 配置点灯程序 —— 从工程生成到 LED 闪烁
笔记·stm32·单片机·学习·嵌入式软件
JasmineX-117 小时前
STM32的SPI通信(软件读写W25Q64)
c语言·stm32·单片机·嵌入式硬件