Прерывания

На этом форуме Вы можете задать вопросы знатокам программы и автору.
Ответить
Ingwar
Полковник
Сообщения: 1929
Зарегистрирован: 28.10.2015{, 22:47}
Репутация: 223
Откуда: Ленобласть
Имя: Игорь

Прерывания

#1

Сообщение Ingwar » 13.12.2022{, 21:57}

Вопрос не "горящий", поскольку сам все равно буду разбираться.
Но вдруг кто-то точно знает и сэкономит мне время)))
Есть железка с которой я получаю данные. Сигнал готовности заведен на выбранный пин и его изменение инициирует некую функцию передачи.
Скорость обновления данных на момент замера критически важна и поэтому все "долгоиграющие" элементы в программе я на это время отключаю.
Вопрос - можно ли сигнал готовности заведя на пин с поддержкой прерывания и прописав функцию в обработчик, получить нормальную компиляцию и работоспособность остальной части программы выполняющейся в промежутке между прерываниями?
Не получится ли это двойным декларированием и прочими коллизиями?
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.

ecoins
Полковник
Сообщения: 2930
Зарегистрирован: 12.02.2016{, 11:40}
Репутация: 453
Откуда: Шатура
Имя: Энвер

Прерывания

#2

Сообщение ecoins » 14.12.2022{, 00:57}

Ingwar писал(а):
13.12.2022{, 21:57}
Вопрос - можно ли сигнал готовности заведя на пин с поддержкой прерывания и прописав функцию в обработчик, получить нормальную компиляцию и работоспособность остальной части программы выполняющейся в промежутке между прерываниями?
Модно. Как пример реализация поддержки прерываний от HC-SR04. Прописывать код следует аккуратно, там почти все важно.

Ingwar
Полковник
Сообщения: 1929
Зарегистрирован: 28.10.2015{, 22:47}
Репутация: 223
Откуда: Ленобласть
Имя: Игорь

Прерывания

#3

Сообщение Ingwar » 14.12.2022{, 05:17}

ecoins писал(а):
14.12.2022{, 00:57}
Прописывать код следует аккуратно, там почти все важно.
Наверное нужно уточнить мои условия - используемая функция из сторонней библиотеки и там по любому пин, который я хочу задействовать на прерывание, прописывается и соответственно объявляется...)
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.

ecoins
Полковник
Сообщения: 2930
Зарегистрирован: 12.02.2016{, 11:40}
Репутация: 453
Откуда: Шатура
Имя: Энвер

Прерывания

#4

Сообщение ecoins » 14.12.2022{, 12:12}

Может будет полезен такой ответ(немного усложненный) на примере функции для HC-SR04:
1. Делается обработчик прерывания, вне цикла loop() (можно и в setup()). Обработчик прерывания связан с основной функцией только через переменные, определяемые с атрибутом volatile:
RT_HW_IRAM_ATTR void RT_HW_IRQ_SR04_handler_dvSR04(){ //++++Обработчик прерываний HC-SR04------------
if(dvSR04.state==2) {if( RT_HW_PIN_DIR_READ(dvSR04.ddPin)){dvSR04.timeBegin=micros(); dvSR04.state=3;}}
if(dvSR04.state==3) {if(!RT_HW_PIN_DIR_READ(dvSR04.ddPin)){dvSR04.timeEnd =micros(); dvSR04.state=4;}}}
------------------------
Атрибут RT_HW_IRAM_ATTR для всех контроллеров кроме ESP8266 можно опустить или:
#define RT_HW_IRAM_ATTR //--Атрибут для совместимости c ESP8266;
Для ESP8266:
#define RT_HW_IRAM_ATTR IRAM_ATTR //--Атрибут для совместимости c ESP8266;
------------------------
RT_HW_PIN_DIR_READ(dvSR04.ddPin) - это аналог digitalRead(), работает побыстрее.

2. В удобном месте loop() выполняется вызов основной функции только по переменным ранее определенным с атрибутом volatile. В приведенном примере это state,timeBegin,timeEnd.
3. И структура для объекта dvSR04:
СпойлерПоказать
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Структура для сенсора HC-SR04
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
struct RT_HW_STRUCT_SR04_ID{
RT_HW_PIN_DIR_ID ddPin;
uint8_t custom=0;
uint8_t dir=0; //--Этапы управления основной программы;
uint8_t extPinEcho=255; //--Новое значение пина Echo(можно считать перед началом измерения);
uint8_t extPinTrig=255; //--Новое значение пина Trig(можно считать перед началом измерения);
uint8_t pinEcho=255; //--Номер пина Echo;
uint8_t pinTrig=255; //--Номер пина Trig;
uint8_t maxQntErr=4; //--Максимальное допустимое подряд кол-во ошибочных измерений;
uint8_t ok; //--Флаг устойчивой работоспособности сенсора;
uint8_t fresh; //--Готовность данных;
uint8_t run=1; //--Флаг "Команда на запуск измерения;
uint8_t finish=0; //--Флаг завершения измерения;
uint8_t codeErr; //--Код последней ошибки измерения;
uint8_t cntErrCur; //--Cчетчик ошибок;
uint16_t cntOk; //--Счетчик успешных измерений;
uint16_t cntErr; //--Счетчик ошибочных измерений;
//---------------------------------------------------------------------------------------------------
uint16_t maxLen=400; //--Максимальное расстояние измерения;
int8_t tmpAir=-100; //--Температура воздуха;
int8_t extAir=23; //--Внешнее значение температуры воздуха
//---------------------------------------------------------------------------------------------------
uint8_t enableIRQ=1; //--Разрешение режима с прерываниями;
int8_t numIRQ; //--Номер аппаратного прерывания;
uint8_t modeIRQ; //--Режим работы: =0 -без прерываний; =1 -с прерываниями на пине Echo;
uint8_t begin,end; //--Флаги для отслеживания прерываний;
uint8_t modeFilter=3; //--Тип фильтра;
float speedSoundAir; //--Скорость звука (функция от температуры);
uint16_t echoMcs, LenMcs; //--Расстояние в mcs от сенсора и с фильтром(внешним);
uint16_t Len;
volatile uint8_t state;
volatile uint32_t timeStart;
volatile uint32_t timeCur;
volatile uint32_t timeBegin;
volatile uint32_t timeEnd;
//-------------------------------------------------------------------------------------------------
uint8_t stepReturn; //--Номер шага для возврата add function;
uint16_t stepSetBack; //--Задержка перед возвратом add function;
uint32_t timeDelay; //--Рабочий параметр add function (timeDelay в timeDelayMs());
uint8_t stepDelay=0; //--Рабочий параметр add function (stepDelay в timeDelayMs());
};
===============================================

Ответить

Вернуться в «Спросить у знатоков»