• Объявления

    • admin

      Просьба всем принять участие!   24.11.2017

      На форуме разыгрывается спектроанализатор Arinst SSA-TG LC (цена 18500 руб). Просьба всем перейти по ссылке ниже и принять участие!
Delau

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

5 сообщений в этой теме

Delau    0

Всем привет!

В рамках моей задачи есть необходимость изменять значение переменной в прерывании (да в прочем распространённое явление). Всё бы хорошо если бы проект не состоял из нескольких библиотек (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овский? Чтобы можно было вызывать функцию в любом месте программы без объявления глобальных структур.

Поделиться сообщением


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

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
IMXO    1 096

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Delau    0

Т.е. фактически у меня всё правильно. Только через объявление структуры глобально.

Спасибо за ответ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 096

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vovka    23

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

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

Поделиться сообщением


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

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас