Функции для работы с прерываниями в WiringRP

К СВЕДЕНИЮ

При использовании функций для работы с прерываниями (interruptCreate и т.д.) необходимо учитывать следующие особенности:

  1. Режим подтяжки: Драйвер GPIO может некорректно обрабатывать прерывания для входов, использующих внутренние подтягивающие «вниз» резисторы (режим INPUT_PULLDOWN). Это связано с аппаратными особенностями SoC Allwinner. Для стабильной работы прерываний рекомендуется использовать режим INPUT (без подтяжки) или INPUT_PULLUP.

  2. Аппаратные ограничения портов: В SoC Allwinner H5 (Repka Pi 3) и Allwinner H6 (Repka Pi 4) отсутствует аппаратная поддержка прерываний для контактов порта PC. Попытка настроить прерывание на этих пинах не будет успешной. Остальные порты (PA, PD, PF, PG, PH, PL, PM) поддерживают прерывания в штатном режиме.

  3. Права доступа: Для работы с прерываниями через стандартный интерфейс ядра Linux требуются права на чтение/запись к символьным устройствам /dev/gpiochip*. Обычно gpiochip0 соответствует контроллеру R_PIO (порты PL, PM), а gpiochip1 — основному контроллеру CPUX-PORT (остальные порты). При установке из .deb пакета права настраиваются автоматически.

interruptCreate() #

Инициализирует функцию обработки прерываний для указанного в параметре контакта, и задает функцию обратного вызова для обработки события изменения уровня логического напряжения на входном контакте.

Синтаксис #

int interruptCreate(int pin, void(*callback)(__u32, __u64))

Параметры #

pin - номер контакта.

void(*callback)(__u32, __u64) - функция обратного вызова для обработки события изменения уровня логического напряжения на входном контакте.

Возврат #

0 при успешном выполнении, или отрицательное значение в случае ошибки.

interruptStop() #

Завершает обработку прерываний для указанного в параметре входного контакта

Синтаксис #

void interruptStop(int pin)

Параметры #

pin - номер контакта.

Возврат #

Ничего.

interruptStopAll() #

Завершает обработку прерываний для всех ранее инициализированных входных контактов

Синтаксис #

void interruptStopAll()

Параметры #

Ничего.

Возврат #

Ничего.

Пример использования прерываний #

Код включает светодиод при нажатии сопоставленной с ним кнопки.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#include "wiringRP.h"
#include "event_gpio.h"

// Глобальные переменные и константы
const int LED_1 = 8;
const int LED_2 = 9;
const int BUTTON_1 = 10;
const int BUTTON_2 = 1;
bool LED_1_ON = false;
bool LED_2_ON = false;

// Обработчики событий нажатия кнопки
void pushButton1(__u32 event, __u64 time);
void pushButton2(__u32 event, __u64 time);

void setup() {
    // Инициализация библиотек wiringRP
    if(setupWiringRP(WRP_MODE_SUNXI) < 0)
        exit(EXIT_FAILURE);

    // Инициализация пользовательских объектов
    pinMode(LED_1, OUTPUT);
    pinMode(LED_2, OUTPUT);
    pinMode(BUTTON_1, INPUT_PULLUP);
    pinMode(BUTTON_2, INPUT);
    
    interruptCreate(BUTTON_1, pushButton1);
    interruptCreate(BUTTON_2, pushButton2);
}

void pushButton1(__u32 event, __u64 time) {
    printf("Button 1 - is %s, timestamp: %lld\n", event == 1 ? "RISING" : "FALLING", time);
    delay(100);
    if(event && digitalRead(BUTTON_1))
        LED_1_ON = !LED_1_ON;
}

void pushButton2(__u32 event, __u64 time) {
    printf("Button 2 - is %s, timestamp: %lld\n", event == 1 ? "RISING" : "FALLING", time);
    delay(100);
    if(event && digitalRead(BUTTON_2))
        LED_2_ON = !LED_2_ON;
}

void loop() {
    // Основной цикл программы
    if(LED_1_ON)
        digitalWrite(LED_1, HIGH);
    else
        digitalWrite(LED_1, LOW);

    if(LED_2_ON)
        digitalWrite(LED_2, HIGH);
    else
        digitalWrite(LED_2, LOW);
}

ONDESTROY() {
    // Освобождение занятых ресурсов, выключение напряжения на пинах
    digitalWrite(LED_1, LOW);
    pinMode(LED_1, DISABLE);
    digitalWrite(LED_2, LOW);
    pinMode(LED_2, DISABLE);
    pinMode(BUTTON_1, DISABLE);
    pinMode(BUTTON_2, DISABLE);

    // Завершение работы библиотек
    interruptStopAll();
    releaseWiringRP();

    exit(0);    // выход из программы
}

MAIN_WIRINGRP();

1470 просмотров0 комментариев

Комментарии (0)

Для участия в обсуждении Вы должны быть авторизованным пользователем
Разделы

Навигация

ВойтиРегистрация