stm32实现按键控制

这篇具有很好参考价值的文章主要介绍了stm32实现按键控制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、实现原理:

1.1 按键控制电路分析

二、程序部分:


一、实现原理:

1.1 按键控制电路分析

stm32 按键,stm32,单片机,arm

stm32 按键,stm32,单片机,arm

stm32 按键,stm32,单片机,arm

    可以看见电路上key_up按键连接3.3v,K1、K2、K3下拉接地。按键检测的时候需要配置输入模式。key_up配置下拉输入:在默认状态下,读取的GPIO引脚为低电平,按键按下时,输入变为高电平。K1、K2、K3配置上拉输入:在默认状态下,读取的GPIO引脚为高电平,当按键按下的时候,相应管脚变为低电平。

 1.2 按键检测分析

    按键在按下的时候并不是立马会得到稳定的低电平,如下图所示存在一个前沿抖动,同理在按键松开的时候也会存在一个后沿抖动。在实际检测的时候,为了克服这种抖动,一般可以采用两种方法消除:软件消除通过添加一个延时检测,(一般来讲在5-10ms),确定是否按键稳定按下。硬件上采用rc滤波电路来消除这种抖动。

stm32 按键,stm32,单片机,arm

二、程序部分:

button.h包含GPIO的封装

#ifndef _button_H
#define _button_H
//对一些IO口通过位带封装函数
#include "system.h"

//key_up以及key封装
#define BUTTON_PORT_RCC		RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE
#define BUTTON_UP_PIN       GPIO_Pin_0
#define BUTTON_UP_PORT  	GPIOA

#define BUTTON_LEFT_PIN     GPIO_Pin_2
#define BUTTON_DOWN_PIN     GPIO_Pin_3
#define BUTTON_RIGHT_PIN    GPIO_Pin_4
#define BUTTON_PORT  	    GPIOE


//管脚输入电平
#define BUTTON_UP           PAin(0)
#define BUTTON_LEFT         PEin(2)
#define BUTTON_DOWN         PEin(3)
#define BUTTON_RIGHT        PEin(4)
//扫描函数返回检测值
#define key_detection_up    1
#define key_detection_left  2
#define key_detection_down  3
#define key_detection_right 4

void button_Init(void);
u8 button_scan(u8 mode);

#endif

button.c包含端口初始化函数以及扫描函数

#include "button.h"
#include "SysTick.h"

void button_Init()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    //开启时钟
    RCC_APB2PeriphClockCmd(BUTTON_PORT_RCC,ENABLE);
    //key_up初始化,模式选择下拉
    GPIO_InitStructure.GPIO_Pin = BUTTON_UP_PIN ;
    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPD;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(BUTTON_UP_PORT,&GPIO_InitStructure); 
    //key初始化,模式选择输入上拉
    GPIO_InitStructure.GPIO_Pin = BUTTON_LEFT_PIN|BUTTON_DOWN_PIN|BUTTON_RIGHT_PIN;
    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(BUTTON_PORT,&GPIO_InitStructure); 


}

//mode = 0 单次扫描检测
//一次按下进入检测条件语句,key置0,而后不满足条件key==1无法进入检测语句,实现只检测一次的效果
//mode = 1 连续扫描检测
//mode始终处于1,在不满足按键按下的条件下才会不进入检测语句

u8 button_scan(u8 mode)
{
    static u8 key=1;
    if (key==1&&(BUTTON_UP==1||BUTTON_LEFT==0||BUTTON_DOWN==0||BUTTON_RIGHT==0))
    {
       //克服抖动延时10ms
        delay_ms(10);
        key = 0;
        if (BUTTON_UP==1)
        {
            return key_detection_up;
        }
        else if (BUTTON_LEFT==0)
        {
            return key_detection_left;
        }
        else if (BUTTON_DOWN==0)
        {
            return key_detection_down;
        }
        else
        {
            return key_detection_right;
        } 
    }
    else if (BUTTON_UP==0&&BUTTON_LEFT==1&&BUTTON_DOWN==1&&BUTTON_RIGHT==1)
    {
        key = 1;

    }
    if (mode==1)
    {
        key = 1;
    }
    return 0;
}

位带封装函数

#ifndef _system_H
#define _system_H


#include "stm32f10x.h"



#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 

#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 
 

#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //��� 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //���� 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //��� 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //���� 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //��� 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //���� 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //��� 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //���� 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //��� 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //����

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //��� 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //����

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //��� 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //����


#endif

本次实验还使用led灯模块用于指示按键是否运行:

led.h

#ifndef _led_H
#define _led_H

#include "system.h"


#define LED_PORT 			GPIOC   
#define LED_PIN 			(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7)
#define LED_PORT_RCC		RCC_APB2Periph_GPIOC


#define led1 PCout(0)
#define led2 PCout(1)
#define led3 PCout(2)
#define led4 PCout(3)
#define led5 PCout(7)



void LED_Init(void);


#endif

led.c

#include "led.h"


void LED_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(LED_PORT_RCC,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=LED_PIN;  
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;	 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	
	GPIO_Init(LED_PORT,&GPIO_InitStructure); 	 
	
	GPIO_SetBits(LED_PORT,LED_PIN);   
}

主函数控制main.c文章来源地址https://www.toymoban.com/news/detail-613968.html

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "button.h"


int main()
{
	u8 key,i=0;
	SysTick_Init(72);
	LED_Init();
	button_Init();
	
	while (1)
	{
		key = button_scan(0);
		switch (key)
		{
		case key_detection_up:
			led1 = 0;
			break;
		case key_detection_left:
			led1 = 1;
			break;
		case key_detection_down:
			led2 = 0;
			break;
		case key_detection_right:
			led2 = 1;
			break;
		default:
			break;
		}
		i++;
		//if更少延时不影响按键检测
		if (i%20==0)
		{
			led5 = !led5;
		}
		delay_ms(10);
		
	}
		
}

到了这里,关于stm32实现按键控制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 32单片机按键扫描 实现长短按

    key.c key.h

    2024年02月03日
    浏览(11)
  • 51单片机实现倒计时,按键控制倒计时

    51单片机实现倒计时,按键控制倒计时

    基于AT89C52的答辩倒计时。四个按键分别控制倒计时开始,暂停,时间加和减。剩下30S时蜂鸣器响,倒计时结束蜂鸣器响。  

    2024年02月07日
    浏览(11)
  • STM32单片机学习3--STM32控制键盘

    STM32单片机学习3--STM32控制键盘

    单片机型号:STM32F103C8T6 开发环境:Keil5 4种输入模式 上拉输入模式:在默认状态下(GPIO引脚无输入),读取得的GPIO引脚数据为1,高电平(与Vdd相连的为上拉电阻); 下拉输入模式:在默认状态下(GPIO引脚无输入),读取得的GPIO引脚数据为0,低电平(与Vss相连的为下拉电

    2024年02月10日
    浏览(13)
  • STM32单片机学习4--STM32控制八段码

    STM32单片机学习4--STM32控制八段码

    数码管:实际上是多个LED按照一定顺序排列,并加上遮罩所构成的元件。 八段码一般会引出9个引脚,其中7个引脚显示数字(或某些字母),1个显示小数点,1个作为片选端。 根据连接方式的不同,数码管分为 共阳 和 共阴 。 共阳在这端输出低电平时点亮,高电平时会熄灭

    2024年01月23日
    浏览(14)
  • 如果STM32/GD32一类的ARM单片机解除读写保护的方法

    如果STM32/GD32一类的ARM单片机解除读写保护的方法

    有时候啊,使用ST-Link给STM32一类的ARM单片机下载程序的时候,发现怎么也下载不了,可能是由于芯片被写保护了。那怎么办呢?可以使用STM32 ST-LINK Utility工具解除芯片的写保护,本篇博文介绍操作步骤,文章最后有工具下载链接。 双击“STM32 ST-LINK Utility.exe”,打开软件。 软

    2024年02月09日
    浏览(17)
  • STM32单片机PWM控制实现电机调速度(小车运动,STM32F103C8T6&TB6612&TT电机)

    STM32单片机PWM控制实现电机调速度(小车运动,STM32F103C8T6&TB6612&TT电机)

    作者:公子易平 时间:2023/6/6 前段时间做一个智能小车的相关项目时,发现很少有人能够将STM32的PWM控制讲清楚,故而书此文,希望对后来的学习者有所帮助。 STM32F103C8T6最小系统板 直流TT电机 电机驱动芯片(TB6612) 杜邦线若干 接线情况: TB6612引脚说明: STM32主控芯片与TB6612接

    2024年02月15日
    浏览(13)
  • 51单片机入门 - 详解定时器实现按键控制流水灯方向

    操作系统:Windows 10 x84-64 单片机:STC89C52RC 编译器:SDCC 烧录软件:stcgal 1.6 开发板:普中51单片机开发板A2套件(2022) 在 VS Code 中新建项目到烧录的过程: 左侧EIDE图标 - 新建项目 - 空项目 - 8位MCU项目 - 保存文件夹。 更改构建配置: SDCC ;更改烧录配置: stcgal 。 在项目文件

    2024年02月06日
    浏览(13)
  • 【Proteus仿真】【STM32单片机】智能窗帘控制系统设计

    【Proteus仿真】【STM32单片机】智能窗帘控制系统设计

    本项目使用Proteus8仿真STM32单片机控制器,使用LCD1602显示模块、按键模块、HC05蓝牙、DHT11温湿度、PCF8591 ADC模块、光线传感器、28BYJ48步进电机等。 主要功能: 系统运行后,LCD1602显示温湿度和光线强度值和系统模式状态。 系统模式以自动模式运行,当按下K4键切换为手动模式

    2023年04月24日
    浏览(10)
  • 单片机期末设计 - 液晶显示屏显示时间、日期、温度及按键控制(实验板实现)

    单片机期末设计 - 液晶显示屏显示时间、日期、温度及按键控制(实验板实现)

    设计本代码的主要目的是为了完成期末作业,即在液晶显示屏上显示、时间、日期、温度,以及用按键控制时间、温度的显示。总的来说就是对前面学习计数的糅合,本代码实现的是显示时间,并能在实验板上成功显示。 1.液晶显示屏模块应用 主要是学会如何在液晶显示屏上

    2024年02月08日
    浏览(12)
  • proteus结合keil-arm编译器构建STM32单片机项目进行仿真

    proteus结合keil-arm编译器构建STM32单片机项目进行仿真

        proteus是可以直接创建设计图和源码的,但是源码编译它需要借助keil-arm编译器,也就是我们安装keil-mdk之后自带的编译器。     下面给出一个完整的示例,主要是做一个LED灯闪烁的效果。     新建工程指定路径,Schematic,PCB layout都选择默认,在最后创建项目工程向导的时

    2024年02月13日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包