реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> STM32F072CB PC13 в режиме EXTI
seniorandre
сообщение Feb 19 2015, 18:56
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 58
Регистрация: 6-07-12
Из: г.Нижний Новгород
Пользователь №: 72 651



Очень долгое время бился над проблемой, сейчас она локализована, но легче не стало:
1. На выводах PC13-PC15 висят кнопки, выводы в режиме EXTI, проинициализировано, вот так:
Код
void EXTI_User_Button_Config(void)
{
    EXTI_InitTypeDef   EXTI_InitStructure;
    GPIO_InitTypeDef   GPIO_InitStructure;
    NVIC_InitTypeDef   NVIC_InitStructure;
    /* Enable GPIOA clock */
    RCC_AHBPeriphClockCmd(BUTTON_GPIO_CLK, ENABLE);

    /* Configure Button`s pins as input floating */
    GPIO_InitStructure.GPIO_Pin = BUTTON_LEFT | BUTTON_OK | BUTTON_RIGHT;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(BUTTON_GPIO_PORT, &GPIO_InitStructure);

    /* Enable SYSCFG clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    /* Connect EXTI Line to pin */
    SYSCFG_EXTILineConfig(BUTTON_EXTI_PORT_SOURCE, BUTTON_LEFT_EXTI_PIN_SOURCE);
    SYSCFG_EXTILineConfig(BUTTON_EXTI_PORT_SOURCE, BUTTON_OK_EXTI_PIN_SOURCE);
    SYSCFG_EXTILineConfig(BUTTON_EXTI_PORT_SOURCE, BUTTON_RIGHT_EXTI_PIN_SOURCE);

    /* Configure EXTI0 line */
    EXTI_InitStructure.EXTI_Line = BUTTON_LEFT_EXTI_LINE | BUTTON_OK_EXTI_LINE | BUTTON_RIGHT_EXTI_LINE;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /* Enable and set EXTI0 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = BUTTON_EXTI_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

2. Есть обработчик прерывания, вот:
Код
void EXTI4_15_IRQHandler(void)
{
    BaseType_t xTaskWoken;
    xTaskWoken = pdFALSE;
    //OK BUTTON
    if(EXTI_GetITStatus(BUTTON_OK_EXTI_LINE) != RESET)
    {
        //Button Pressed/Released
        //GPIO_ToggleBits(ERR_LED_PORTx,ERR_LED_PIN);
        if (GPIO_ReadInputDataBit(BUTTON_GPIO_PORT, BUTTON_OK) == 1){ //Released
            xTaskWoken = SendCommandFromISR(CMD_LUX, CurrentCmd); //lux and CurrentCmd
        }
        /* Clear the EXTI line pending bit */
        EXTI_ClearITPendingBit(BUTTON_OK_EXTI_LINE);
    }

    //LEFT BUTTON
    if(EXTI_GetITStatus(BUTTON_LEFT_EXTI_LINE) != RESET)
    {
        if (GPIO_ReadInputDataBit(BUTTON_GPIO_PORT, BUTTON_LEFT) == 1){ //Released
            if (CurrentCmd == 0)
                CurrentCmd = BUTTON_CMD1_LEN - 1;
            else
                --CurrentCmd;
            xTaskWoken = SendCommandFromISR(CMD_LUX, CurrentCmd); //lux and CurrentCmd
        }
        /* Clear the EXTI line pending bit */
        EXTI_ClearITPendingBit(BUTTON_LEFT_EXTI_LINE);
    }

    //RIGHT BUTTON
    if(EXTI_GetITStatus(BUTTON_RIGHT_EXTI_LINE) != RESET)
    {
//        if (GPIO_ReadInputDataBit(BUTTON_GPIO_PORT, BUTTON_RIGHT) == 1){ //Released
//            if (CurrentCmd >= BUTTON_CMD1_LEN - 1)
//                CurrentCmd = 0;
//            else
//                ++CurrentCmd;
//            ProcessButtonCmd();
//        }
        if (GPIO_ReadInputDataBit(BUTTON_GPIO_PORT, BUTTON_RIGHT) == 0){ // Released
            xTimerStart( xButtonPowerOffTimer, BUTTON_TIMERS_WAIT_START );  //Start Long press timer
            ButtonPowerOffProcessed = 0;
        } else {
            if (!ButtonPowerOffProcessed){
                xTimerStop( xButtonPowerOffTimer, BUTTON_TIMERS_WAIT_START );  //Stop Long press timer
                if (CurrentCmd >= BUTTON_CMD1_LEN - 1)
                    CurrentCmd = 0;
                else
                    ++CurrentCmd;
                xTaskWoken = SendCommandFromISR(CMD_LUX, CurrentCmd); //lux and CurrentCmd
                ButtonPowerOffProcessed = 1;
            }
        }
        /* Clear the EXTI line pending bit */
        EXTI_ClearITPendingBit(BUTTON_RIGHT_EXTI_LINE);
    }
    if( xTaskWoken != pdFALSE ) taskYIELD ();
}

3. На аппаратном SPI висит индикатор.
4. Все работает под FreeRtos и все работает правильно.
Проблема возникает перманентно при нажатии на кнопку PC13. Если начать нажимать на кнопку PC13, то может перестать работать индикатор. Иногда это происходит после одного нажатия иногда после 50. При нажатии на другие кнопки проблема не возникает НИКОГДА. Код выполняется один и тот же, задача одна и та же. На других кнопках задачи даже сложнее, а на этой просто - повторить.
Тренировал обработчик прерывания программным вызовом обработчика прерывания, проблем нет, работает железобетонно. Код ниже. Раз в 2 секунды делает 5 нажатий с задержкой 50ms.
Код
void DoLuxCMD( TimerHandle_t xTimer )
{
    (void) xTimer;
    int i;
    PrintfToOutQueue("LUX CMD\n\r");
    //SendCommandFromISR(CMD_LUX, 6);
    for (i = 0; i < 5; ++i){
        EXTI_GenerateSWInterrupt(EXTI_Line13); //ok
        vTaskDelay(50);
    };
}

void vTimerLuxTest(void){
    xLuxTimer = xTimerCreate("TmrLuxCmd",            /* The task name, only for help debugging. */
                            2000,                /* The timer period, which is a multiple command Delay. */
                            pdTRUE,                        /* This is auto restart timer */
                            NULL,                           /* Parameters is NULL */
                            DoLuxCMD                 /* Timer uses the callback. */
                          );
    xTimerStart( xLuxTimer, 0);  //Start/Restart Packed Exti
}

Проблема возникает только если нажимать аппаратно на кнопку PC13 - TAMPER -RTC. Может я должен еще как-то RTC конфигурировать, не пойму?
P.S. Обнаружил что RESET and CS от индикатора идут возле кнопки, поставил резисторы по 10к на массу, результата нет.

Сообщение отредактировал seniorandre - Feb 19 2015, 20:04
Go to the top of the page
 
+Quote Post
billidean
сообщение Feb 20 2015, 04:50
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 247
Регистрация: 4-10-10
Из: г. Екатеринбург
Пользователь №: 59 925



Может проблема в том, что Вы в обработчике прерывания запускаете "тяжелые функции" типа SendCommandFromISR(CMD_LUX, CurrentCmd), я не знаю на счет именно этой ф-ции. что она делает, но может её выполнение длительное.
И еще "в эту же струю" - ф-ция taskYIELD (); не поток ли запускает? Может в обработчике прерывания не стоит запускать потоки?

З.Ы.: с контроллерами работаю недавно, поэтому возможно моё мнение не особо верное.
Go to the top of the page
 
+Quote Post
AndrejM
сообщение Feb 20 2015, 05:38
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 20-11-13
Пользователь №: 79 278



NVIC_InitStructure.NVIC_IRQChannelPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1;

посмотрите в отладчике какой реально приоритет функция NVIC_Init установит в IP регистр , не знаю как для F072 , но для F407 NVIC_Init это делает не правильно ,в результате вы можете иметь проблемы с вызовом функций freertos из вашего прерывания.
Go to the top of the page
 
+Quote Post
vladec
сообщение Feb 20 2015, 07:57
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 167
Регистрация: 3-10-05
Из: Москва
Пользователь №: 9 158



Може быть дело в самих портах PC13-PC15, не знаю как для конкретно вашего типа контроллера, но для многих ST-шных ARM-ов именно эти порты особенные, они связаны с RTC и запитываются через отдельный внутренний коммутатор, при этом их вытекающий ток ограничивается тремя милиамперами. Посмотрите datasheet на свой контроллер - таблицу с контактами и портами, нет ли там для этих портов соответствующих примечаний. Так например, для некоторых контроллеров утилита STM32CubeMX не позволяет сконфигурировать одновременно более одного порта из портов PC13-PC15 в режим IO_OUTPUT.
Go to the top of the page
 
+Quote Post
seniorandre
сообщение Feb 20 2015, 08:05
Сообщение #5


Участник
*

Группа: Свой
Сообщений: 58
Регистрация: 6-07-12
Из: г.Нижний Новгород
Пользователь №: 72 651



Цитата(billidean @ Feb 20 2015, 07:50) *
Может проблема в том, что Вы в обработчике прерывания запускаете "тяжелые функции"

Функции легкие написаны для IRQ, отправляют команду в очередь.
Цитата
NVIC_InitStructure.NVIC_IRQChannelPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1;

Про эту проблему знаю, но на 072 нет такой проблемы и приоритет ниже приоритетов OS.

Я в общем писал, что все тренировал с программным запуском этого обработчика, все ок.
Сейчас грешу только на HW, но на девборде не могу попробовать (на ней 072RBT), т.к. индикатор запаян в рабочую плату наглухо, а второй едет с Китая.

Цитата(vladec @ Feb 20 2015, 10:57) *
Може быть дело в самих портах PC13-PC15, не знаю как для конкретно вашего типа контроллера, но для многих ST-шных ARM-ов именно эти порты особенные,

Я про это знаю, поэтому и спрашиваю, может кто работал с ними в таком варианте. Может еще PullUp внешние повесить надо, пока ХЗ.
На каждой кнопке висит кондер по 1000 pF.
Осцил ни каких подозрительных выбросо вне видит, хочу еще изгиб платы попробовать.
Кстати ... надо попробовать сконфигурировать их CubeMx, может есть особенности...

Сообщение отредактировал seniorandre - Feb 20 2015, 08:07
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Feb 20 2015, 08:08
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а можно понять что ломается?

то есть надо различить
перестает прерывание от кнопки приходить?
перестает передаваться данные по SPI
остальное все работает?

может где-то какой хардфалт и весь проц помирает?
Go to the top of the page
 
+Quote Post
seniorandre
сообщение Feb 20 2015, 08:12
Сообщение #7


Участник
*

Группа: Свой
Сообщений: 58
Регистрация: 6-07-12
Из: г.Нижний Новгород
Пользователь №: 72 651



Цитата(billidean @ Feb 20 2015, 07:50) *
И еще "в эту же струю" - ф-ция taskYIELD (); не поток ли запускает? Может в обработчике прерывания не стоит запускать потоки?


taskYIELD говорит планировщику что есть более приоритетная задача в очереди и это значит что возврат из прерывания будет в эту задачу.

Цитата(Golikov A. @ Feb 20 2015, 11:08) *
а можно понять что ломается?

то есть надо различить
перестает прерывание от кнопки приходить?
перестает передаваться данные по SPI
остальное все работает?

может где-то какой хардфалт и весь проц помирает?

Подвисает индикатор, иногда перестает принимать данные, иногда включит инверсию экрана. Прерывания срабатывают, команды выполняются. Данные по SPI идут. Rtos работает, все команды выполняются, вывод на USART есть. Проскакивает видимо по SPI какая-то хрень, которая вводит индикатор в ступор.
Может будут идеи как отловить сей момент, у меня уже просто идеи кончились

Сообщение отредактировал seniorandre - Feb 20 2015, 08:13
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Feb 20 2015, 08:24
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а чипселект что двигает?
Go to the top of the page
 
+Quote Post
seniorandre
сообщение Feb 20 2015, 08:27
Сообщение #9


Участник
*

Группа: Свой
Сообщений: 58
Регистрация: 6-07-12
Из: г.Нижний Новгород
Пользователь №: 72 651



Цитата(Golikov A. @ Feb 20 2015, 11:24) *
а чипселект что двигает?

CS индикатора ставится программно, один раз в 0 при инициализации и всегда стоит в нуле. Так драйвер написан.
Схема вот: Схема
Индикатор ILI9163

Сообщение отредактировал seniorandre - Feb 20 2015, 08:29
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Feb 20 2015, 08:30
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ну так плохо...
если его опускать только на посылку вы будите защищены...
А по нему можно будет найти что происходит.

то есть обмен по шине с CS в 1 сразу выявит проблему

можете в драйвер дописать еще одну ножку, которую опускать на штатные посылки, и поднимать после них.

дальше надо на чем либо сделать логическое & этой ноги, и на осцилограф и ловить посылки нештатные ... иногда это осциллограф умеет сам в мат функциях делать...
Go to the top of the page
 
+Quote Post
seniorandre
сообщение Feb 20 2015, 08:38
Сообщение #11


Участник
*

Группа: Свой
Сообщений: 58
Регистрация: 6-07-12
Из: г.Нижний Новгород
Пользователь №: 72 651



Цитата(Golikov A. @ Feb 20 2015, 11:30) *
то есть обмен по шине с CS в 1 сразу выявит проблему

Спасибо, хотя какой-то вариант, а то я уже неделю головой бьюсь.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Feb 20 2015, 08:45
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Ничего такого не вижу на схеме...


EXTI_ClearITPendingBit(BUTTON_RIGHT_EXTI_LINE); - переставьте это в начало функции обработки прерывания... так правильнее, иногда бывают повторные срабатывания из за того что в конвейерах чего то задержалось, и бит снялся после выхода из функции и вы влетаете в нее повторно

и еще один момент...
если я не ошибаюсь функция обрабатывает прерывания от 4 ног или больше.
а снимаете вы флаги только тех что обрабатываете. Если так совершенно случайно у вас выставиться флаг еще одного прерывания, вы влетите в это прерывание и будите в нем сидеть вечно.... хорошо бы чисто на всякий случай добавить сброс всех флагов что вызывают это прерывание

ну и конечно надо после того как все настроили библиотечными функциями проверить реальное значение регистров. То есть проверить результаты настройки, чтобы сюрпризов не было
Go to the top of the page
 
+Quote Post
seniorandre
сообщение Feb 20 2015, 08:53
Сообщение #13


Участник
*

Группа: Свой
Сообщений: 58
Регистрация: 6-07-12
Из: г.Нижний Новгород
Пользователь №: 72 651



Цитата(Golikov A. @ Feb 20 2015, 11:45) *
Ничего такого не вижу на схеме...


EXTI_ClearITPendingBit(BUTTON_RIGHT_EXTI_LINE); - переставьте это в начало функции обработки прерывания... так правильнее, иногда бывают повторные срабатывания из за того что в конвейерах чего то задержалось, и бит снялся после выхода из функции и вы влетаете в нее повторно

и еще один момент...
если я не ошибаюсь функция обрабатывает прерывания от 4 ног или больше.
а снимаете вы флаги только тех что обрабатываете. Если так совершенно случайно у вас выставиться флаг еще одного прерывания, вы влетите в это прерывание и будите в нем сидеть вечно.... хорошо бы чисто на всякий случай добавить сброс всех флагов что вызывают это прерывание

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

Еще раз спасибо, все в тему, вечером буду пробовать.

Ну и еще вопрос: "Если делать debouce, то как правильнее? Таймер настраивать что ли на это? Я думал с Exti вроде не должно быть дребезга?"
Я думаю ваш вариант со сбросом битов должен решить большинство проблем.
Go to the top of the page
 
+Quote Post
Копейкин
сообщение Feb 20 2015, 09:12
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 190
Регистрация: 7-11-07
Из: С-Петербург
Пользователь №: 32 134



Антидребезг нужен. Кнопки дают его почти всегда.
По таймеру. Если уже есть работающий, по подцепить к нему.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Feb 20 2015, 09:25
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ну там кондерчик на кнопицах вроде есть по схеме...

самое простое это так.
как возникает прерывание от кнопки, вы отключаете прерывание, и запускаете таймер на 2-5 миллисекунд, по истечению которого возвращаете прерывания не забыв скинут флаг вызвавшего его кнопки.
Флаги остальных кнопок не трогаете, тогда если их тоже кто-то нажимал в период таймера, не позже чем через 2-5 мСек они обработаются, и там опять же запрет прерывания и таймер.

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


Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 04:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.01495 секунд с 7
ELECTRONIX ©2004-2016