stm32硬件消抖_按键消抖 - STM32 - 论坛-意法半导体STM32/STM8技术社区
#include "stdio.h"
#define _IO volatile
typedef unsigned int uint32_t;
typedef _IO uint32_t vu32;
typedef unsigned short int uint16_t;
#define GPIO_Pin_0 ((uint16_t)0x0001)
#define GPIO_Pin_1 ((uint16_t)0x0002)
#define GPIO_Pin_2 ((uint16_t)0x0004)
#define GPIO_Pin_3 ((uint16_t)0x0008)
#define GPIO_Pin_4 ((uint16_t)0x0010)
#define GPIO_Pin_5 ((uint16_t)0x0020)
#define GPIO_Pin_6 ((uint16_t)0x0040)
#define GPIO_Pin_7 ((uint16_t)0x0080)
#define GPIO_Pin_8 ((uint16_t)0x0100)
#define GPIO_Pin_9 ((uint16_t)0x0200)
#define GPIO_Pin_10 ((uint16_t)0x0400)
#define GPIO_Pin_11 ((uint16_t)0x0800)
#define GPIO_Pin_12 ((uint16_t)0x1000)
#define GPIO_Pin_13 ((uint16_t)0x2000)
#define GPIO_Pin_14 ((uint16_t)0x4000)
#define GPIO_Pin_15 ((uint16_t)0x8000)
#define GPIO_Pin_All ((uint16_t)0xFFFF)
#define RCC_APB2Periph_AFIO ((uint32_t)0x00000001)
#define RCC_APB2Periph_GPIOA ((uint32_t)0x00000004)
#define RCC_APB2Periph_GPIOB ((uint32_t)0x00000008)
#define RCC_APB2Periph_GPIOC ((uint32_t)0x00000010)
#define RCC_APB2Periph_GPIOD ((uint32_t)0x00000020)
#define LEDON (GPIOD->BRR = GPIO_Pin_2)
#define LEDOFF (GPIOD->BSRR = GPIO_Pin_2)
#define BITBAND(addr,bitnum) ((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+ (bitnum<<2))
/*******这个的公式是FLASH的话, 0X4200 0000 + ((add-0x4000 0000)*8+n)*4;
其中add是你要绑定的寄存器的地址,n是你要绑定的寄存器的位,
现在将其变成这种形式((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5 + (bitnum)<<2))
:addr & 0xF000 0000是将其保留最高的思位比如说addr地址是0x4201 8000那么他现在是0x4000 0000
+0x2000000变成了0x4200 0000;(addr-0x4000 0000)这其实就是保留它的后7位(在这里的改变的寄存器的地址都是
0x4001 0000的那么就是说进一步保存的是后五位)(这里注意一点,0x2200_0000这个地址每增加1,实际上就是增加
8个bit(一个地址对应一个字节),实际寄存器中的1个bit对应32个bit,所以就乘以4,地址本身增加1是8bit,
8bit乘以4倍刚好是32bit。)那么现在(addr &0XFFFFF)其实就是保留后五位,<<5就是*32(2^5),<<2就是*4(2^2);
将((A-0x4000 0000)(这个就是addr &0xFFFFF)*8+n)*4拆开就是(addr & 0XFFFFF)<<5 +(bitnum)<<2了
**********/
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr, bitnum))
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n)
#define KEY1 PCin(4)
typedef struct
{
_IO uint32_t CRL;
_IO uint32_t CRH;
_IO uint32_t IDR;
_IO uint32_t ODR;
_IO uint32_t BSRR;
_IO uint32_t BRR;
_IO uint32_t LCKR;
}GPIO_TypeDef;
typedef struct
{
_IO uint32_t ACR;
_IO uint32_t KEYR;
_IO uint32_t OPTKEYR;
_IO uint32_t SR;
_IO uint32_t CR;
_IO uint32_t AR;
_IO uint32_t OBR;
_IO uint32_t WRPR;
}FLASH_TypeDef;
/************GPIOD管脚的内存对应地址********/
#define PERIPH_BASE ((uint32_t)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define GPIOD ((GPIO_TypeDef *)GPIOD_BASE)
//#define PERIPH_BASE ((uint32_t) 0x40000000)
//#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE)
#define GPIOC_IDR_Addr (GPIOC_BASE+8)
#define FLASH_BASE ((uint32_t)0x40022000)
#define FLASH ((FLASH_TypeDef *)FLASH_BASE)
typedef struct
{
_IO uint32_t CR;
_IO uint32_t CFGR;
_IO uint32_t CIR;
_IO uint32_t APB2RSTR;
_IO uint32_t APB1RSTR;
_IO uint32_t AHBENR;
_IO uint32_t APB2ENR;
_IO uint32_t APB1ENR;
_IO uint32_t BDCR;
_IO uint32_t CSR;
_IO uint32_t AHBRSTR;
_IO uint32_t CFGR2;
}RCC_TypeDef;
/****************RCC时钟************/
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
#define RCC ((RCC_TypeDef *)RCC_BASE)
void RCC_init(void)
{
RCC->CR|=1<<16;
while(!(RCC->CR>>17));
RCC->CFGR2|=4<<4;
RCC->CFGR2|=6<<8;
RCC->CFGR2|=1<<16;
RCC->CR|=1<<26;
while(!(RCC->CR>>27));
RCC->CFGR2|=1<<2;
RCC->CFGR|=1<<16;
RCC->CFGR|=7<<18;
FLASH->ACR|=0x32;
RCC->CR|=1<<24;
while(!(RCC->CR>>25));
//FLASH->ACR|=0x32;//
RCC->CFGR|=1<<1;
}
void LED_init()
{
RCC->APB2ENR|=RCC_APB2Periph_GPIOD;
GPIOD->CRL&=0xFFFFF0FF;
GPIOD->CRL|=0x00000300;
}
void Delay(vu32 nCount)
{
for(;nCount!=0;nCount--);
}
void Key_init()
{
RCC->APB2ENR|=RCC_APB2Periph_GPIOC;//如果你写成RCC->APB2ENR=RCC_APB2Periph_GPIOC;
//就不行了,因为这样的话RCC的时钟只为GPIOC打开了,
GPIOC->CRL&=0xFFF0FFFF;
GPIOC->CRL|=0x00080000;
}
int main(void)
{
unsigned int key_up=1,flag;
RCC_init();
LED_init();
Key_init();
while(1)
{
if(key_up)
LEDON;
else
LEDOFF;
/************键盘消抖**********
这里,因为键盘按下的时候,会有一段波动,不稳定.所以在这里,我们需要消抖
首先,我们的按键是按下的时候是0,所以进来一个while()循环(主要是stm32的运转速率太快了)
然后在里面我们进行延时等待,为了防止按一下按键stm32跑了很多次的情况,我们设置一个标志flag
,只让他按一下不论多长时间,LED只亮一次。*/
while(KEY1==0)//键盘消抖
{
Delay(0xfffff);
flag++;
if(flag==1)
{
key_up=!key_up;
}
}
flag=0;
}
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)