You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Raspberry Pi Pico双中断异常:仅识别单个引脚中断的问题排查

问题:Raspberry Pi Pico双光耦编码器中断仅识别一个引脚

我正在使用Raspberry Pi Pico,尝试用两个光耦作为编码器测量RPM。配置引脚14和15的下降沿中断后,设备只能识别其中一个引脚的中断。最初使用gpio_set_irq_enabled_with_callback()函数,发现该函数仅支持绑定一个回调函数,不确定是否需要借助双核心解决此问题。

相关代码

#include<stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/adc.h"
#include "hardware/pwm.h"
#include "hardware/timer.h"

#define POT_PIN 26
#define PWM_OUTPUT 12
#define ENCODER_14 14
#define ENCODER_15 15
#define FALLING_EDGE 0x04

uint8_t contador_14 = 0;
uint8_t contador_15 = 0;
uint8_t revoluciones_14 = 0;
uint8_t revoluciones_15 = 0;
uint8_t numeroAnterior_14 = 0;
uint8_t numeroAnterior_15 = 0;

long map(long x, long in_min, long in_max, long out_min, long out_max)
{
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void button_callback_14()
{
    if(gpio_get_irq_event_mask(14) && GPIO_IRQ_EDGE_FALL)
    {
        contador_14+=1;
        printf("Interrupt occurred at pin 14 contador : %i \n", contador_14);
        revoluciones_14 = contador_14 % 20;  
    }
}

void button_callback_15()
{
    if(gpio_get_irq_event_mask(15) && GPIO_IRQ_EDGE_FALL)
    {
        contador_15+=1;
        printf("Interrupt occurred at pin 15 contador : %i \n", contador_15);
        revoluciones_15 = contador_15 % 20;
    }
}

bool lecturaPotenciometro(struct repeating_timer *t)
{
    uint slice_num = pwm_gpio_to_slice_num(PWM_OUTPUT);

    pwm_set_wrap(slice_num,255);
    pwm_set_chan_level(slice_num, PWM_CHAN_A, 0); 
    pwm_set_enabled(slice_num, true); 
    
    uint16_t result = adc_read();
    long pwm_value = map(result, 0, 4095, 0, 255);
    //printf("Raw value : %i PWM value : %i \n", result, pwm_value);
    pwm_set_chan_level(slice_num, PWM_CHAN_A, pwm_value);
    return true;
}

bool calculoRPM(struct repeating_timer *t)
{
    uint8_t RPM_14 = (revoluciones_14 - numeroAnterior_14) * 600;
    uint8_t RPM_15 = (revoluciones_15 - numeroAnterior_15) * 600; 
    
    //printf("RPM 14 : %i \n", RPM_14); 
    //printf("RPM 15 : %i \n", RPM_15); 
 
    numeroAnterior_14 = revoluciones_14;  
    numeroAnterior_15 = revoluciones_15; 
    return true;
}

int main()
{
    // 串口初始化
    stdio_init_all();
    
    // ADC初始化
    adc_init();
    adc_gpio_init(POT_PIN);
    adc_select_input(0);

    // PWM引脚配置
    gpio_set_function(PWM_OUTPUT, GPIO_FUNC_PWM);
   
    // 编码器14引脚配置
    gpio_init(ENCODER_14);
    gpio_set_dir(ENCODER_14, GPIO_IN);
    gpio_pull_down(ENCODER_14);
    
    // 编码器15引脚配置
    gpio_init(ENCODER_15);
    gpio_set_dir(ENCODER_15, GPIO_IN);
    gpio_pull_down(ENCODER_15);

    // 中断配置
    gpio_set_irq_enabled(ENCODER_14, FALLING_EDGE, 1);
    gpio_set_irq_enabled(ENCODER_15, FALLING_EDGE, 1);
    gpio_add_raw_irq_handler(ENCODER_14, button_callback_14);
    gpio_add_raw_irq_handler(ENCODER_15, button_callback_15);
    irq_set_enabled(IO_IRQ_BANK0, true);


    // 定时器配置:250ms读取电位器,100ms计算RPM
    struct repeating_timer timer1;
    struct repeating_timer timer2;
    
    add_repeating_timer_ms(250, lecturaPotenciometro, NULL, &timer1);
    add_repeating_timer_ms(100, calculoRPM, NULL, &timer2);

    // 主循环
    while(1)
    {
        tight_loop_contents();
    }
}

串口输出情况

串口仅打印引脚14的中断计数信息,完全没有引脚15的相关输出。


内容的提问来源于stack exchange,提问作者FERN4V3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 12:01:34