Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как настроить обработку прерываний (IRQ) на Raspberry Pi Pico с помощью FreePascal

Delphi , Интернет и Сети , Интернет

 

В этой статье мы рассмотрим настройку обработки прерываний (IRQ) на Raspberry Pi Pico с использованием FreePascal. Этот вопрос был поднят пользователем Germo, столкнувшимся с проблемой при использовании функции gpio_set_irq_enabled_with_callback.

Проблема:

Germo не смог настроить обработку прерываний от GPIO на своей Raspberry Pi Pico, используя FreePascal. При запуске программы отладчик останавливался на функции gpio_set_irq_enabled_with_callback.

Решение Thaddy:

Thaddy предложил следующий пример кода, демонстрирующий настройку прерывания по спадающему фронту сигнала на GPIO пине:

program gpio_irq_test;
 {$MODE OBJFPC}
{$H+}
 uses
  pico_gpio_c, pico_irq_c;
 const
  LED_PIN = 25;
  IRQ_PIN = 15;
 procedure irq_callback(gpio: byte; events: longword); cdecl;
begin
  gpio_put(LED_PIN, not gpio_get(LED_PIN)); // Toggle LED on IRQ
end;
 begin
  stdio_init_all;
  gpio_init(LED_PIN);
  gpio_set_dir(LED_PIN, GPIO_OUT);
  gpio_init(IRQ_PIN);
  gpio_set_dir(IRQ_PIN, GPIO_IN);
  gpio_pull_up(IRQ_PIN);
   gpio_set_irq_enabled_with_callback(
    IRQ_PIN,
    GPIO_IRQ_EDGE_FALL,
    true,
    @irq_callback
  );
   while true do
    // Main loop
  end;
end.

Разбор кода:

  • uses pico_gpio_c, pico_irq_c;: Подключает необходимые модули для работы с GPIO и прерываниями. Убедитесь, что эти модули правильно установлены и доступны в вашем проекте FreePascal.
  • LED_PIN = 25; IRQ_PIN = 15;: Определяет константы для пина светодиода (выход) и пина прерывания (вход). Замените эти значения на пины, которые вы используете в своей схеме.
  • procedure irq_callback(gpio: byte; events: longword); cdecl;: Определяет процедуру-обработчик прерывания. Важно отметить ключевое слово cdecl, указывающее на соглашение о вызовах C, которое необходимо для правильной работы с библиотеками, написанными на C. Внутри процедуры irq_callback происходит переключение состояния светодиода при возникновении прерывания. Параметры gpio и events содержат информацию о пине, вызвавшем прерывание, и типе события.
  • stdio_init_all;: Инициализирует стандартный ввод/вывод.
  • gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT);: Инициализирует пин светодиода как выход.
  • gpio_init(IRQ_PIN); gpio_set_dir(IRQ_PIN, GPIO_IN);: Инициализирует пин прерывания как вход.
  • gpio_pull_up(IRQ_PIN);: Включает подтягивающий резистор на пине прерывания. Это важно, чтобы пин не "плавал" и имел определенное состояние, когда на него не подается сигнал.
  • gpio_set_irq_enabled_with_callback(IRQ_PIN, GPIO_IRQ_EDGE_FALL, true, @irq_callback);: Ключевая функция! Включает прерывание на указанном пине.
    • IRQ_PIN: Номер пина, на котором нужно включить прерывание.
    • GPIO_IRQ_EDGE_FALL: Тип прерывания - по спадающему фронту сигнала. Другие возможные значения: GPIO_IRQ_EDGE_RISE (по восходящему фронту), GPIO_IRQ_LEVEL_LOW (низкий уровень), GPIO_IRQ_LEVEL_HIGH (высокий уровень).
    • true: Включает прерывание.
    • @irq_callback: Указатель на процедуру-обработчик прерывания.
  • while true do // Main loop: Бесконечный цикл, в котором программа ожидает прерывания.

Важные моменты и альтернативные решения:

  1. Соглашение о вызовах cdecl: Как правильно отметил Thaddy, использование cdecl для процедуры-обработчика прерывания критически важно. Неправильное соглашение о вызовах может привести к краху программы или непредсказуемому поведению.

  2. Модули и линковка: Убедитесь, что вы правильно подключили необходимые модули (pico_gpio_c, pico_irq_c) и указали необходимые библиотеки для линковки (pico_multicore, pico_stdlib, hardware_gpio). Это можно сделать в настройках вашего проекта FreePascal.

  3. Тип прерывания: Выбор типа прерывания зависит от вашей конкретной задачи. Если вам нужно реагировать на изменение состояния пина, используйте GPIO_IRQ_EDGE_RISE или GPIO_IRQ_EDGE_FALL. Если вам нужно реагировать на определенный уровень сигнала, используйте GPIO_IRQ_LEVEL_LOW или GPIO_IRQ_LEVEL_HIGH.

  4. Подтягивающие резисторы: Использование подтягивающих (или подтягивающих вниз) резисторов необходимо для обеспечения стабильного состояния пина, когда на него не подается сигнал. В примере Thaddy используется gpio_pull_up(IRQ_PIN), но в зависимости от вашей схемы вам может потребоваться gpio_pull_down(IRQ_PIN).

  5. Альтернативное решение (использование прерываний в стиле Object Pascal): Хотя пример Thaddy использует C-совместимый подход с cdecl, можно попробовать реализовать обработку прерываний в более объектно-ориентированном стиле, используя классы и события. Это может потребовать написания оберток (wrappers) вокруг C-функций, но позволит вам работать с прерываниями более интуитивно. Пример такой обертки (псевдокод):

type
  TGPIOInterruptEvent = procedure(Sender: TObject; Pin: Integer; Event: LongWord) of object;

  TGPIOInterruptHandler = class(TObject)
  private
    FOnInterrupt: TGPIOInterruptEvent;
    FPin: Integer;
    FEventType: LongWord;
    procedure InternalCallback(gpio: byte; events: longword); cdecl;
  public
    constructor Create(APin: Integer; AEventType: LongWord);
    destructor Destroy; override;
    property OnInterrupt: TGPIOInterruptEvent read FOnInterrupt write FOnInterrupt;
  end;

constructor TGPIOInterruptHandler.Create(APin: Integer; AEventType: LongWord);
begin
  inherited Create;
  FPin := APin;
  FEventType := AEventType;
  gpio_init(FPin);
  gpio_set_dir(FPin, GPIO_IN);
  gpio_set_irq_enabled_with_callback(FPin, FEventType, true, @InternalCallback);
end;

destructor TGPIOInterruptHandler.Destroy;
begin
  gpio_set_irq_enabled_with_callback(FPin, FEventType, false, nil); // Disable IRQ
  inherited Destroy;
end;

procedure TGPIOInterruptHandler.InternalCallback(gpio: byte; events: longword); cdecl;
begin
  if Assigned(FOnInterrupt) then
    FOnInterrupt(Self, FPin, events);
end;

Этот пример демонстрирует создание класса TGPIOInterruptHandler, который инкапсулирует логику настройки и обработки прерывания. Событие OnInterrupt позволяет вам подписаться на прерывание и обрабатывать его в вашем коде.

Заключение:

Настройка прерываний на Raspberry Pi Pico с использованием FreePascal требует внимательности к деталям, особенно в отношении соглашений о вызовах и правильной линковки библиотек. Пример Thaddy является хорошей отправной точкой. Рассмотрите возможность использования объектно-ориентированного подхода для более удобной работы с прерываниями. Убедитесь, что вы правильно настроили тип прерывания и подтягивающие резисторы в соответствии с вашей схемой.

Создано по материалам из источника по ссылке.

В статье рассматривается настройка обработки прерываний на Raspberry Pi Pico с использованием FreePascal, демонстрируя пример кода и объясняя ключевые моменты, такие как соглашение о вызовах `cdecl`, подключение модулей и выбор типа прерывания.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Интернет ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-09-21 13:33:14/0.0039908885955811/0