Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Таймер вешает STM32f103

Чт окт 25, 2018 11:30:20

Доброго времени суток! Такое дело получается: есть программа, в которой дружно работают SPI через DMA, собачий таймер (для создания задержек) и USART. Как только я инициализирую TIMER3 (он нужен для опроса кнопок и энкодера), какое-то время МК работает (скажем, секунд 4-6, точно не измерял), а потом просто зависает, причём наглухо, до следующей перезагрузки. Как будто не сбрасывает флаг в каком-то прерывании. Но флаги я сбрасываю во всех прерываниях! Какие есть идеи?

На всякий случай, иниты вочдога+функции задержек и таймера:

Код:
#define    DWT_CYCCNT    *(volatile unsigned long *)0xE0001004
#define    DWT_CONTROL   *(volatile unsigned long *)0xE0001000
#define    SCB_DEMCR     *(volatile unsigned long *)0xE000EDFC

void DWT_Init(void){
    //разрешаем использовать счётчик
    SCB_DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    //обнуляем значение счётного регистра
   DWT_CYCCNT  = 0;
    //запускаем счётчик
   DWT_CONTROL |= DWT_CTRL_CYCCNTENA_Msk;
}

static __inline uint32_t delta(uint32_t t0, uint32_t t1){
    return (t1 - t0);
}

void delay_us(uint32_t us){
   
      uint32_t t0 =  DWT->CYCCNT;
      uint32_t us_count_tic =  us * (SystemCoreClock/1000000);
      while (delta(t0, DWT->CYCCNT) < us_count_tic) ;

   
}

void delay_ms(uint32_t us){
 
      uint32_t t0 =  DWT->CYCCNT;
      uint32_t us_count_tic =  us * (SystemCoreClock/1000);
      while (delta(t0, DWT->CYCCNT) < us_count_tic) ;

 
}


void Timer3Init(){
   RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;

   TIM3->PSC    = 120-1;
   TIM3->ARR    = 500-1;
   TIM3->DIER |= TIM_DIER_UIE;
        TIM3->EGR |= TIM_EGR_UG;               
        TIM3->SR &= ~(TIM_SR_UIF);             
   TIM3->CR1  |= TIM_CR1_CEN;

   NVIC_EnableIRQ(TIM3_IRQn);
}


Добавлено after 32 minutes 45 seconds:
Можно как-то через кейловский дебаг узнать, а каком прерывании завис МК? Прямо вот ситуативно, как только завис, подключиться и считать регистры нужной периферии?

Re: Таймер вешает STM32f103

Чт окт 25, 2018 11:53:16

Поробуйте, если дебуггер не помешает зависаниям. Я в таких случаях использую Ozone и Jlink - подключится к уже запущенному процессу...

Re: Таймер вешает STM32f103

Чт окт 25, 2018 12:15:01

Alex-Elektron писал(а):Можно как-то через кейловский дебаг узнать, а каком прерывании завис МК?
Не кейл, но может поймете как нужно настроить отладку. http://purebasic.mybb.ru/viewtopic.php?id=564#p7600

Re: Таймер вешает STM32f103

Чт окт 25, 2018 13:02:36

Там в отладке есть кнопка Stop. Когда контроллер зависнет нажмите её и увидите в каком месте он завис (если повезёт :))

Re: Таймер вешает STM32f103

Чт окт 25, 2018 13:16:00

Myp3ik, спасибо за совет! Повезло, увидел, на чём висну:

Код:
void DMA1_Channel5_IRQHandler() {
    if (DMA1->ISR & DMA_ISR_TCIF5 ) {
      while(!(SPI2->SR & SPI_SR_RXNE));
      while (SPI2->SR & SPI_SR_BSY);
       
      (void) SPI2->DR;
       
    //  while(!(SPI2->SR & SPI_SR_TXE));
     
      GlobalVar_SPI_Transmitted = 1;       
             
      DMA1_Channel5->CCR &= ~DMA_CCR5_EN; 
      SPI2->CR2 &= ~ SPI_CR2_TXDMAEN;
     
      DMA1->IFCR |= DMA_IFCR_CTCIF5;
    }
 }



вот тут: while(!(SPI2->SR & SPI_SR_RXNE));

до этого использовал поллинг while(!(SPI2->SR & SPI_SR_TXE)); но ушёл от него, видимо, потому, что флаг о законченной передаче данных всплывал раньше времени. Хотя он вообще не должен всплывать раньше while (SPI2->SR & SPI_SR_BSY);

сейчас закомментил while(!(SPI2->SR & SPI_SR_RXNE)); и вернулся к тому, что было - пока полёт нормальный! Во всяком случае, пока я пишу это сообщение, МК ещё ни разу не завис

Re: Таймер вешает STM32f103

Пт окт 26, 2018 18:47:51

Как по мне - странный обработчик прерывания.
В прерывании DMA происходит работа с SPI. Мягко говоря, это не очень логичное действие. Плюс, обработка данных SPI интерфейса.
Я бы рекомендовал вынести работу с ним в основной поток и управлять им флагами состояний, а не мучать обработчик прерывания.
Плюс, прерывание рекомендуется делать максимально коротким, а конструкции ожидания - это паузы. А паузы в прерываниях - плохо. Особенно, потенциально бесконечные паузы.
Ответить