花生了什么树694 2023-06-05 22:21 采纳率: 0%
浏览 72
已结题

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

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

img

  • 写回答

9条回答 默认 最新

  • qllaoda 2023-06-05 23:10
    关注

    按键用中断方式,中断一次,给一个全局变量累加一次,主循环里定期输出这个全局变量的值,通过观察这个值的变化情况就可以看到抖动次数
    代码通过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);
        }
    }
    
    
    
    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月12日
  • 创建了问题 6月5日

悬赏问题

  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler