VladislavS 39 19 февраля Опубликовано 19 февраля · Жалоба На время отладки все остальные прерывания отключить, колбэки убрать. Добиться отсутствия пропусков и понемногу возвращать функционал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 19 февраля Опубликовано 19 февраля · Жалоба ... а также запретить DMA (если есть), или любых других мастеров кроме CPU. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 20 февраля Опубликовано 20 февраля (изменено) · Жалоба On 2/19/2024 at 7:13 PM, VladislavS said: Добиться отсутствия пропусков Сделал специальный дебуговый проект. В нём делаю минимальную инициализацию для настройки тактирования, пинов, таймера 1. По завершении инициализации проект висит в while(1){;}. На 4 канала таймера 1 подаю одинаковые пачки импульсов. Вот в таком варианте обработчика прерываний: Spoiler void TIMER1_IRQHandler (void) { //---Variables---// uint8_t ch = 0; // Переменная определяет номер канала. uint32_t INTF_regval = TIMER_INTF(TIMER1); uint32_t CHCTL2_regval = TIMER_CHCTL2(TIMER1); uint32_t polarity = 0x00; EdgeEnum edge = FALLING; GPIO_PinState NewPinState [4] = {GPIO_PIN_RESET}; static GPIO_PinState OldPinState [4] = {GPIO_PIN_SET, GPIO_PIN_SET, GPIO_PIN_SET, GPIO_PIN_SET}; GPIO_PinState LoopCondition = GPIO_PIN_RESET; //---------------// //---If channel 0 capture/compare interrupt flag is set---// if (INTF_regval & TIMER_INTF_CH0IF) // If channel 0 capture/compare interrupt flag is set. { ch = 0; // Выбор номера канала. polarity = (CHCTL2_regval & TIMER_CHCTL2_CH0P); //---Input capture event--------------------------------------------------------------// if (polarity) // Если было настроено прерывание на срез... { edge = RISING; LoopCondition = GPIO_PIN_RESET; } else // Если было настроено прерывание на фронт... { edge = FALLING; LoopCondition = GPIO_PIN_SET; } do { EdgeChanging(TIMER1, ch, edge); edge = (EdgeEnum)!edge; LoopCondition = (GPIO_PinState)!LoopCondition; do { TIMER_INTF(TIMER1) = ~TIMER_INTF_CH0IF; // Clear capture/compare interrupt flag. NewPinState[ch] = GPIO_GetPinState(DALI_RX_Connect[ch].port, DALI_RX_Connect[ch].pin); } while(TIMER_INTF(TIMER1) & TIMER_INTF_CH0IF); } while(NewPinState[ch] == LoopCondition); if (NewPinState[ch] == OldPinState[ch]) {;}//return; else OldPinState[ch] = NewPinState[ch]; } //--------------------------------------------------------// //---If channel 1 capture/compare interrupt flag is set---// if (INTF_regval & TIMER_INTF_CH1IF) // If channel 1 capture/compare interrupt flag is set. { // Аналогично channel 0 // } //--------------------------------------------------------// //---If channel 2 capture/compare interrupt flag is set---// if (INTF_regval & TIMER_INTF_CH2IF) // If channel 2 capture/compare interrupt flag is set. { // Аналогично channel 0 // } //--------------------------------------------------------// //---If channel 3 capture/compare interrupt flag is set---// if (INTF_regval & TIMER_INTF_CH3IF) // If channel 3 capture/compare interrupt flag is set. { // Аналогично channel 0, но всё равно выложу. Может чем-то отличается, чем я не вижу// ch = 3; // Выбор номера канала. polarity = (CHCTL2_regval & TIMER_CHCTL2_CH3P); //---Input capture event--------------------------------------------------------------// if (polarity) // Если было настроено прерывание на срез... { edge = RISING; LoopCondition = GPIO_PIN_RESET; } else // Если было настроено прерывание на фронт... { edge = FALLING; LoopCondition = GPIO_PIN_SET; } do { EdgeChanging(TIMER1, ch, edge); edge = (EdgeEnum)!edge; LoopCondition = (GPIO_PinState)!LoopCondition; do { TIMER_INTF(TIMER1) = ~TIMER_INTF_CH3IF; // Clear capture/compare interrupt flag. NewPinState[ch] = GPIO_GetPinState(DALI_RX_Connect[ch].port, DALI_RX_Connect[ch].pin); } while(TIMER_INTF(TIMER1) & TIMER_INTF_CH3IF); } while(NewPinState[ch] == LoopCondition); if (NewPinState[ch] == OldPinState[ch]) {;}//return; else OldPinState[ch] = NewPinState[ch]; } //--------------------------------------------------------// } //...// void EdgeChanging (uint32_t timer, uint8_t channel, EdgeEnum edge) { uint32_t temp = TIMER_CHCTL2(timer); uint32_t TIMER_CHCTL2_CHxP = (TIMER_CHCTL2_CH0P << (channel * 4)); if (edge == FALLING) temp |= TIMER_CHCTL2_CHxP; else temp &= (~TIMER_CHCTL2_CHxP); TIMER_CHCTL2(timer) = temp; // Change channel x capture/compare function polarity. } //------------------------------------------------------------------------------// стабильно ловлю пропуски в канале 3. Даже если в обработчике ставлю обработку канала 3 в самое начало, всё равно ловлю пропуски в канале 3. В остальных поймать не получилось. Вот в таком варианте обработчика прерываний: Spoiler void TIMER1_IRQHandler (void) { //---Variables---// uint8_t ch = 0; // Переменная определяет номер канала. uint32_t INTF_regval = TIMER_INTF(TIMER1); uint32_t CHCTL2_regval = TIMER_CHCTL2(TIMER1); uint32_t polarity = 0x00; EdgeEnum edge = FALLING; //---------------// if (INTF_regval & TIMER_INTF_CH0IF) // If channel 0 capture/compare interrupt flag is set. { ch = 0; // Выбор номера канала. polarity = (CHCTL2_regval & TIMER_CHCTL2_CH0P); //---Input capture event--------------------------------------------------------------// if (polarity) // Если было настроено прерывание на срез... edge = RISING; else // Если было настроено прерывание на фронт... edge = FALLING; EdgeChanging(TIMER1, ch, edge); TIMER_INTF(TIMER1) = ~TIMER_INTF_CH0IF; // Clear capture/compare interrupt flag. i_ch0++; } if (INTF_regval & TIMER_INTF_CH1IF) // If channel 1 capture/compare interrupt flag is set. { ch = 1; // Выбор номера канала. polarity = (CHCTL2_regval & TIMER_CHCTL2_CH1P); //---Input capture event--------------------------------------------------------------// if (polarity) // Если было настроено прерывание на срез... edge = RISING; else // Если было настроено прерывание на фронт... edge = FALLING; EdgeChanging(TIMER1, ch, edge); TIMER_INTF(TIMER1) = ~TIMER_INTF_CH1IF; // Clear capture/compare interrupt flag. i_ch1++; } if (INTF_regval & TIMER_INTF_CH2IF) // If channel 2 capture/compare interrupt flag is set. { ch = 2; // Выбор номера канала. polarity = (CHCTL2_regval & TIMER_CHCTL2_CH2P); //---Input capture event--------------------------------------------------------------// if (polarity) // Если было настроено прерывание на срез... edge = RISING; else // Если было настроено прерывание на фронт... edge = FALLING; EdgeChanging(TIMER1, ch, edge); TIMER_INTF(TIMER1) = ~TIMER_INTF_CH2IF; // Clear capture/compare interrupt flag. i_ch2++; } if (INTF_regval & TIMER_INTF_CH3IF) // If channel 3 capture/compare interrupt flag is set. { ch = 3; // Выбор номера канала. polarity = (CHCTL2_regval & TIMER_CHCTL2_CH3P); //---Input capture event--------------------------------------------------------------// if (polarity) // Если было настроено прерывание на срез... edge = RISING; else // Если было настроено прерывание на фронт... edge = FALLING; EdgeChanging(TIMER1, ch, edge); TIMER_INTF(TIMER1) = ~TIMER_INTF_CH3IF; // Clear capture/compare interrupt flag. i_ch3++; } } пропусков поймать не удалось. Изменено 14 марта пользователем haker_fox Длинный код спрятал под спойлер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 245 20 февраля Опубликовано 20 февраля · Жалоба 7 часов назад, LAS9891 сказал: Вот в таком варианте обработчика прерываний: ... Ужас - такого бурелома нагородить на ровном месте из простого алгоритма... 7 часов назад, LAS9891 сказал: Вот в таком варианте обработчика прерываний: ... пропусков поймать не удалось. Но они всё равно будут, просто реже. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 21 февраля Опубликовано 21 февраля (изменено) · Жалоба 10 hours ago, jcxz said: Ужас Другой оценки мне не стоит ожидать. Предложите свой код, в котором не будет пропусков, а я проверю. Где найти достойный пример, если даже в STM работают говнокодеры? На свежую голову (или что там вместо головы у говнокодеров) нашёл косяк. Теперь не ловлю пропуски в обоих вариантах, но надеюсь, что выложат неговнокодовый пример того, как надо делать. Изменено 21 февраля пользователем LAS9891 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться