Перейти к содержанию

Передача Аргументов В Прерывание


Delau

Рекомендуемые сообщения

Всем привет!

В рамках моей задачи есть необходимость изменять значение переменной в прерывании (да в прочем распространённое явление). Всё бы хорошо если бы проект не состоял из нескольких библиотек (file.c, file.h тоже распространённое явление :)).

Обычно библиотека создаётся с максимальным уровнем абстракции, что в свою очередь приводит к необходимости объявлять аргументы в функции в виде указателей. Всё хорошо - объявил, к примеру, структуру, и передал её адрес в функцию, обработал и забыл. НО, как быть если функция вызывается в обработчике прерывания?! У меня получилось только через объявление структуры глобально (extern), тогда понятно что она доступна в любом месте программы (в любом файле). И мне это ох как не нравиться. Не нравиться потому что появляется глобальная переменная.

Начал я детально изучать STMовские библиотеки, ибо там я свободно вызываю функцию в обработчике прерывания без передачи аргументов. И вот что получилось, на примере TIM6.

В файле stm32f10x.h объявлена структура:

typedef struct

{

__IO uint16_t CR1;

uint16_t RESERVED0;

__IO uint16_t CR2;

и т. д.

} TIM_TypeDef;

далее в нём же пошли такие дефайны:

#define PERIPH_BASE ((uint32_t)0x40000000)

#define APB1PERIPH_BASE PERIPH_BASE

#define TIM6_BASE (APB1PERIPH_BASE + 0x1000)

#define TIM6 ((TIM_TypeDef *) TIM6_BASE)

Теперь файл stm32f10x_tim.h

#include "stm32f10x.h"

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

И наконец файл stm32f10x_tim.c

#include "stm32f10x_tim.h"

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

{

if (NewState != DISABLE)

{

/* Enable the TIM Counter */

TIMx->CR1 |= TIM_CR1_CEN;

}

else

{

/* Disable the TIM Counter */

TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN));

}

}

Теперь я могу в абсолютно любом месте программы сделать вызов, допустим так: TIM_Cmd(TIM6, ENABLE); Хоть в обработчике прерывания хоть где ещё. Я не объявляю глобальных структур!

Давайте посмотрим на мою задачу.

В h-файле объявлена структура:

typedef struct

{

usart_status_TypeDef status;

uint32_t baudrate; //9600 or 115200

uint8_t *p_tx_buf;

и т. д.

} usart_init_struct_TypeDef;

в с-файле есть функция:

void usart_it_handler(usart_init_struct_TypeDef *usart_struct)

{

if (USART_GetITStatus (USART1, USART_IT_TC))

{

//здесь куча всяких вызовов и далее самое главное

usart_struct->status = transmit_complete; //это одно из полей вышеобъявленной структуры

};

};

Теперь обработчик прерывания.

с-файл:

void USART1_IRQHandler(void)

{

usart_it_handler(&usart_struct);

};

И работает всё это только при условии что структура usart_struct будет глобальной т. е. я её объявляю в файле main и в файле с обработчиками прерываний (extern)/

Разница между моим и STMовским кодом заключается в том что у них есть привязка к физическим адресам периферии, а у меня нет.

Как сделать код похожим на STMовский? Чтобы можно было вызывать функцию в любом месте программы без объявления глобальных структур.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

может вы не совсем понимаете что значит явное указание адреса....

для компилятора это фактически объявление глобальной переменной

для основного кода программы обработчик прерывания есть внешний код

и передача переменных в него всегда производится глобально, хоть это не всегда видно явно...

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

да правильно, только глобально...

а у младших ПИКов еще веселей если переменной указать первые адреса обшей памяти данных вообще можно поиметь нехилые грабли, по дефолту компилятор туда пишет сохранение контента прерывания, причем в хелпе об этом ни слова

Ссылка на комментарий
Поделиться на другие сайты

В прерывании МК должен находиться как можно меньше!

Воспользуйтесь флагами...

На форумах принято общаться на "ты", что не является оскорбительным и подразумевает равноправие

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...