使用按键和串口,记录按键在不消抖的情况下触发的次数
stm32

按键用中断方式,中断一次,给一个全局变量累加一次,主循环里定期输出这个全局变量的值,通过观察这个值的变化情况就可以看到抖动次数
代码通过CHATGPT生成,我就没仔细研究了,自己稍微改改吧
#include "stm32f10x.h"
#include "stdio.h"
// 定义用于计数的变量
volatile uint32_t pulseCount = 0;
void USART2_Init(void) {
// 启用USART2和GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置USART2的引脚
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART2的波特率
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
// 启用USART2
USART_Cmd(USART2, ENABLE);
}
void SysTick_Init(void) {
// 配置系统时钟为72MHz
SystemInit();
// 设置SysTick定时器的重装载值
SysTick->LOAD = 72000000; // 1秒钟的计数值
// 设置SysTick定时器的时钟源为内部时钟,并启动定时器
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk;
}
void EXTI_Configuration(void) {
// 启用AFIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// 配置IO口为浮空输入模式
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置EXTI中断线路,PA0作为按键输入
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
void NVIC_Configuration(void) {
// 配置中断优先级分组为组1
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
// 配置EXTI中断通道
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI0_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
// 清除中断标志位
EXTI_ClearITPendingBit(EXTI_Line0);
// 计数加1
pulseCount++;
}
}
void USART_SendString(const char* str) {
while (*str) {
// 等待发送缓冲区为空
while ((USART2->SR & USART_SR_TXE) == 0);
// 将字符发送到USART2
USART2->DR = *str++;
// 等待发送完成
while ((USART2->SR & USART_SR_TC) == 0);
}
}
int main(void) {
USART2_Init();
SysTick_Init();
EXTI_Configuration();
NVIC_Configuration();
while (1) {
// 等待1秒钟
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
// 重装载SysTick定时器
SysTick->VAL = 0;
// 将计数值转换为字符串
char buffer[16];
sprintf(buffer, "Count: %lu\r\n", pulseCount);
// 发送计数值到串口
USART_SendString(buffer);
}
}