evsx1 0 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба Добрый день, возникла проблема с обработкой прерывания по переполнению от таймера общего назначения TIM6 в микроконтроллере STM32F105RC. Среда разработки CooCox. TIM_ClearITPendingBit(TIM6, TIM_IT_Update) не сбрасывает флаг прерывания и я соответсвенно попдаю в него снова, но уже не по времени,которое мне необходимо,если верить системному таймеру. Данную строку двигал в разные часть обработчика прерывания, но в показанном мной коде,она должна стоять в этом месте,как я выяснил из литературы(проверяем, что прерывание от таймера и затем чистим(насколько я выяснил это надо сделать как можно быстрее)). Так же меня скорость тиков таймера с требуемых 100us до 1ms, так как думал,что не успеваю очистить и попадаю снова в прерывание из-за скорости. Результат один и тот же. По идее мне нужны настройки тиков таймера каждые 0,1ms и дальше период прерываний задается конфигурированием, пока работаю с конфигурацией,что прерывание должно быть каждые 96ms, те период 960 тиков или 96ms. Вопрос , что я сделал неправильно,что таймер так себя ведет? void TIM6_IRQHandler(void) // обработчик прерывания { time = portGetTickCount(); // тут получаем время от системного таймера //TIM6 ->SR &= ~TIM_SR_UIF; //TIM_ClearITPendingBit(TIM6, TIM_IT_Update); if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM6, TIM_IT_Update); // ДАННАЯ СТРОКА судя по отладчику не сбрасывает флаг прерывания if (sync_timer_callbacks[0]) { if ( sync_timer_callbacks[0]() ) { } } } } //настройка таймера void sync_timer_now_setup(uint16 alarm, uint16 ticks, uint16 period) { uint16 now; NVIC_InitTypeDef NVIC_InitStructure; sync_timer_periods[alarm]=period; now = portGetTickCnt(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); switch (alarm) { case 0: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //beacon timer setup TIM_TimeBaseStructInit(&base_timer0); base_timer0.TIM_Prescaler =(3600)-1; //one tick every 100us base_timer0.TIM_Period = ticks; TIM_TimeBaseInit(TIM6, &base_timer0); TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE); TIM_Cmd(TIM6, ENABLE); NVIC_InitStructure_timer0.NVIC_IRQChannel = TIM6_IRQn; NVIC_InitStructure_timer0.NVIC_IRQChannelPreemptionPriority = 13; NVIC_InitStructure_timer0.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure_timer0.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure_timer0); break; case 1: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // timeout timer TIM_TimeBaseStructInit(&base_timer1); base_timer1.TIM_Prescaler = 3600-1; base_timer1.TIM_Period = ticks; TIM_TimeBaseInit(TIM3, &base_timer1); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_Cmd(TIM3, ENABLE); NVIC_InitStructure_timer1.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure_timer1.NVIC_IRQChannelPreemptionPriority = 14; NVIC_InitStructure_timer1.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure_timer1.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure_timer1); break; case 2: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //timer for sending in nodes TIM_TimeBaseStructInit(&base_timer2); base_timer2.TIM_Prescaler = 3600-1; base_timer2.TIM_Period = ticks; TIM_TimeBaseInit(TIM4, &base_timer2); TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); TIM_Cmd(TIM4, ENABLE); NVIC_InitStructure_timer2.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure_timer2.NVIC_IRQChannelPreemptionPriority = 12; NVIC_InitStructure_timer2.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure_timer2.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure_timer2); break; default: break; } } //настройка системной частоты, выбор источников тактирования int RCC_Configuration(void) { ErrorStatus HSEStartUpStatus; RCC_ClocksTypeDef RCC_ClockFreq; /* RCC system reset(for debug purpose) */ RCC_DeInit(); /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); /* Wait till HSE is ready */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus != ERROR) { /* Enable Prefetch Buffer */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /****************************************************************/ /* * HCLK=72MHz, PCLK2=72MHz, PCLK1=36MHz */ /****************************************************************/ /* Flash 2 wait state */ FLASH_SetLatency(FLASH_Latency_2); /* HCLK = SYSCLK */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* PCLK2 = HCLK */ RCC_PCLK2Config(RCC_HCLK_Div1); /* PCLK1 = HCLK/2 */ RCC_PCLK1Config(RCC_HCLK_Div2); /* ADCCLK = PCLK2/4 */ RCC_ADCCLKConfig(RCC_PCLK2_Div6); /* Configure PLLs *********************************************************/ /* PLL2 configuration: PLL2CLK = (HSE / 4) * 8 = 24 MHz */ RCC_PREDIV2Config(RCC_PREDIV2_Div4); RCC_PLL2Config(RCC_PLL2Mul_8); /* Enable PLL2 */ RCC_PLL2Cmd(ENABLE); /* Wait till PLL2 is ready */ while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET){} /* PLL1 configuration: PLLCLK = (PLL2 / 3) * 9 = 72 MHz */ RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div3); RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9); /* Enable PLL */ RCC_PLLCmd(ENABLE); /* Wait till PLL is ready */ while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){} /* Select PLL as system clock source */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* Wait till PLL is used as system clock source */ while (RCC_GetSYSCLKSource() != 0x08){} } RCC_GetClocksFreq(&RCC_ClockFreq); /* Enable SPI1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); /* Enable SPI2 clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); /* Enable GPIOs clocks */ RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE); return 0; } //запуск системного таймера int SysTick_Configuration(void) { if (SysTick_Config(SystemCoreClock / CLOCKS_PER_SEC)) { /* Capture error */ while (1); } NVIC_SetPriority (SysTick_IRQn, 0); return 0; } Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба В регистрах DEBUG-модуля заморожено тактирование таймеров во время отладки? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
evsx1 0 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба 18 minutes ago, Arlleex said: В регистрах DEBUG-модуля заморожено тактирование таймеров во время отладки? Настройки по-умолчанию в CooCox, вроде бы тактирование продолжается(значения в Value меняются при пошаговой отладке, хотя в принципе так и должно быть), но сказать точно не могу. Можете подсказать где это проверить? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба 33 минуты назад, evsx1 сказал: TIM_ClearITPendingBit(TIM6, TIM_IT_Update); // ДАННАЯ СТРОКА судя по отладчику не сбрасывает флаг прерывания Так pending bit - это не бит прерывания TIM_SR_UIF. Эх, плодятся и множатся "кубисты", увеличивают энтропию вселенной. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба Только что, evsx1 сказал: Настройки по-умолчанию в CooCox, вроде бы тактирование продолжается(значения в Value меняются при пошаговой отладке, хотя в принципе так и должно быть), но сказать точно не могу. Можете подсказать где это проверить? Не знаю как в CooCox, в Keil (ды везде примерно одинаково) заходите в модуль DBG, и ставите галочку напротив таймера, тактирование которого при отладке надо заморозить (остановить). Иначе он будет работать даже при остановленном отладчиком процессоре, и, естественно, Вы будете попадать бесконечно в это прерывание. Только что, ViKo сказал: Так pending bit - это не бит прерывания TIM_SR_UIF. У него правильно сделано. А та строка с TIM_SR_UIF тоже верная. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба 3 минуты назад, Arlleex сказал: У него правильно сделано. А та строка с TIM_SR_UIF тоже верная. Верная, но закомментирована. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба Только что, ViKo сказал: Верная, но закомментирована. TIM_ClearITPendingBit(TIM6, TIM_IT_Update); делает то же самое. Посмотрите внимательнее Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
evsx1 0 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба Just now, ViKo said: Верная, но закомментирована. как написано в начале поста,я пробовал и с ней. не помогло. 6 minutes ago, Arlleex said: Не знаю как в CooCox, в Keil (ды везде примерно одинаково) заходите в модуль DBG, и ставите галочку напротив таймера, тактирование которого при отладке надо заморозить (остановить). Иначе он будет работать даже при остановленном отладчиком процессоре, и, естественно, Вы будете попадать бесконечно в это прерывание. У него правильно сделано. А та строка с TIM_SR_UIF тоже верная. Видимо, CooCox устарел уже,не вижу я таких регистров в описании МК. но за подсказку спасибо. В настройках таймера явных ошибок нет? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба Только что, evsx1 сказал: как написано в начале поста,я пробовал и с ней. не помогло. Дык остановите бедный таймер! Он молотит не останавливаясь, когда Вы на точке останова. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
evsx1 0 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба 1 minute ago, Arlleex said: Дык остановите бедный таймер! Он молотит не останавливаясь, когда Вы на точке останова. Спасибо,вот сейчас пытаюсь разобраться как это делается Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба Только что, evsx1 сказал: Спасибо,вот сейчас пытаюсь разобраться как это делается DBG->CR для Вашего МК. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
evsx1 0 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба 4 minutes ago, Arlleex said: DBG->CR для Вашего МК. Большое спасибо! Использование данных функций SPL которые конфигурируют этот регистр,помогло увидеть сброс прерывания у этого таймера DBGMCU_Config(DBGMCU_TIM3_STOP,ENABLE); DBGMCU_Config(DBGMCU_TIM4_STOP,ENABLE); DBGMCU_Config(DBGMCU_TIM6_STOP,ENABLE); Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба 16 минут назад, Arlleex сказал: TIM_ClearITPendingBit(TIM6, TIM_IT_Update); делает то же самое. Посмотрите внимательнее ClearITPendingBit означает стереть pending bit в контроллере прерываний. Он сам стирается, когда выполняется прерывание. А нужно стереть источник запроса прерывания. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
evsx1 0 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба 1 minute ago, ViKo said: ClearITPendingBit означает стереть pending bit в контроллере прерываний. Он сам стирается, когда выполняется прерывание. А нужно стереть источник запроса прерывания. 3 minutes ago, ViKo said: ClearITPendingBit означает стереть pending bit в контроллере прерываний. Он сам стирается, когда выполняется прерывание. А нужно стереть источник запроса прерывания. Каким образом он сам сотрется ? просто из-за того что прерывание выполненыно? нет. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 февраля, 2019 Опубликовано 6 февраля, 2019 · Жалоба Ага. При входе в прерывание. Автоматически. Похоже, у вас таймер молотит чаще, чем вы успеваете обработать его запросы прерывания. Это если стираете TIM_SR_UIF. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться