
- •Учебный центр информационных технологий “информатика” выпускная квалификационная работа по куррсу профессиональной переподготовки
- •Введение
- •Задание на разрабатываемое устройство
- •Требования к охранным, пожарным шлейфам
- •Требования к входным и выходным исполнительным органам
- •Требования к конфигурированию и настройке устройства
- •Электронные компоненты печатной платы
- •Технические характеристики и параметры основных компонентов
- •Применяемые схемотехнические решения
- •Программное обеспечение микроконтроллера
- •Основная структура проекта
- •Задачи операционной системы реального времени.
- •Взаимодействие задач и прерываний.
- •Функции обработчиков прерываний
- •Rtos задачи проекта
- •Передача параметров настройки по usb
- •Программное обеспечение windows form c#
- •Определение общей структуры приложения
- •Создание библиотеки из ссылочных типов содержащие поля данных
- •Основная сборка проекта
- •Заключение
- •Список литературы
- •Приложение 1. Внешний вид приложения
Функции обработчиков прерываний
Рассмотрим некоторые фрагменты кода для нескольких функций обработчиков прерываний (файл stm32fxxx_it.c) :
Прерывание по таймеру выполняются каждые 2,5 милисекунды, в обработчике прерывания выполняется анализ положения ключей мультиплексора каналов сигнализации, и в зависимости от текущего положения переключаются мультиплексоры на следующие входы. После того как завершится каждое преобразованиеАЦП , DMA сохраняет значения напряжений по каналам в глобальном массиве (объявленном в app.c): __IO uint16_t ADC3ConvertedValue [16]. Таким образом полный цикл замеров по всем каналам завершится после четырех преобразований 4*2.5=10 мсек.
Void TIM3_IRQHandler(void)
{
………
if (DMA_GetCurrDataCounter(DMA2_Stream0)==0x10 ) //массив пуст
{
GPIOE->BSRRH= GPIO_BSRR_BS_7; //переключаем мультиплексор
GPIOE->BSRRH= GPIO_BSRR_BS_8;
// отдаем семафор задаче обработки результатов замеров
xSemaphoreGiveFromISR(xSemPrerADC,NULL)
}
//если массив заполнен на ¼
else if(DMA_GetCurrDataCounter(DMA2_Stream0)==0xC )
{
GPIOE->BSRRL= GPIO_BSRR_BS_7; //переключаем мультиплексор
GPIOE->BSRRH= GPIO_BSRR_BS_8;
} ……
//обновляем значение счетного регистра таймера
capture = TIM_GetCapture1(TIM3);
TIM_SetCompare1(TIM3, capture + CCR1_Val);
//запускаем следующее преобразование АЦП
ADC_SoftwareStartConv(ADC1);
/*передаем управление не планировщику, а если есть на очереди прерывание
то в следующее прерывание, не допуская лишнее переключение
контекста*/
portYIELD_FROM_ISR(1);
}
Прерывание по нажатию кнопок и брелока. Мультиплексоры как аналоговых сигналов, так и дискретных управляются от одних и тех же выводов МК. По Рис 3.2.3 прерывания на брелоке настроены на появление логической единицы (точнее появление 5В через нажатую кнопку на брелоке) на выводе RF, прерывания кнопок настроены на появление логического нуля на выводе key (на key включена подтяжка к питанию 3.3 Вольт). Таким образом, при возникновении прерывания, номер нажатой кнопки соответствует положению мультиплексорного ключа в данный момент времени. Зная продолжительность кратковременного нажатия кнопки 105 мсек и продолжительность каждого переключения мультиплксора 2.5 мсек, для четырех кнопок будем выполнять счет нажатий и сравнивть его со значением 105/4*2.5=10 равным десяти. Определение что кнопка нажата будем выполнять в задаче «vObrabVhodov» где для каждой кнопки сравниваем значение счета со значением 10 и если chetEXTIA[номер кнопки]>=10 значит кнопка нажата. Но перед сравнением значений мы будем блокировать выполнение этой задачи каждые vTaskDelay(105) -105мсек.
Счет выполняем в программе прерывания:
void EXTI15_10_IRQHandler(void) //вызов при нажатии любой кнопки
{
//определяем текущее положение ключа мультиплексора
uint8_t Ukaz=DMA_GetCurrDataCounter(DMA2_Stream0);
//если прерывание на линии RF –это радиобрелок
if(EXTI_GetITStatus(EXTI_Line14) != RESET)
{
switch (Ukaz)
case 0x10: //ключ мультиплексора в положении S1
//дополнительно считываем текущее состояние
if((VhodRF[4]=(GPIOE->IDR & GPIO_Pin_14)?1:0))
//увеличиваем счет для кнопки обрабатываемый в задаче vObrabVhodov
chetEXTIA[4]++;
break;
…….
}
//очищаем флаг прерывания
EXTI_ClearITPendingBit(EXTI_Line14);
//передаем управление следующему прерыванию
portYIELD_FROM_ISR(1);
}