Raspberry Pi pico 中的两个中断

Two interrupts in raspberry pi pico

提问人:FERN4V3 提问时间:11/15/2023 更新时间:11/15/2023 访问量:62

问:

pico 只考虑了我的中断的一个引脚,我正在尝试使用两个,我不知道解决方案是否与使用两个内核有关。

#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; 
}

int main()
{
    //std input output configuracion ie serial monitor
    stdio_init_all();
    
    //adc configuracion
    adc_init();
    adc_gpio_init(POT_PIN);
    adc_select_input(0);

    //PWM configuracion
    gpio_set_function(PWM_OUTPUT, GPIO_FUNC_PWM);
   
    //Encoder 14 configuracion
    gpio_init(ENCODER_14);
    gpio_set_dir(ENCODER_14, GPIO_IN);
    gpio_pull_down(ENCODER_14);
    
    //Encoder 15 configuracion
    gpio_init(ENCODER_15);
    gpio_set_dir(ENCODER_15, GPIO_IN);
    gpio_pull_down(ENCODER_15);

    //Interrupt 
    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);


    /*Timer / Pot reading config
    read pot every  250 ms*/
    struct repeating_timer timer1;
    struct repeating_timer timer2;
    
    add_repeating_timer_ms(250, lecturaPotenciometro, NULL, &timer1);
    add_repeating_timer_ms(100, calculoRPM, NULL, &timer2);

    //Loop infinito
    while(1)
    {
        tight_loop_contents();
    }
}

Arduino Serial monitor

我正在尝试读取两个光耦合器,将它们用作编码器来测量 RPM。我最初尝试使用 gpio_set_irq_enabled_with_callback() 来做到这一点,但我意识到它只考虑了一个函数调用。

c 覆盆子-pi-pico

评论

2赞 Craig Estey 11/15/2023
快速浏览:您正在执行:这使用逻辑和。我相信你想要按位,所以试试:if(gpio_get_irq_event_mask(15) && GPIO_IRQ_EDGE_FALL)if(gpio_get_irq_event_mask(15) & GPIO_IRQ_EDGE_FALL)
0赞 David C. Rankin 11/15/2023
此外,当从中断调用时,微微有点问题。您可能只想在中断处理程序中设置一个标志,然后将 替换为实际的 while 循环,该循环检查标志状态并在其中提供输出。即便如此,如果它触发得太快,我也会遇到问题。可能会触发缓冲问题,这看起来像是输出中可能发生的情况。另外,你为什么要用而不是?stdio.htight_loop_contents();main()rawirq_set_exclusive_handler()

答: 暂无答案