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

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Alex-Elektron
Встал на лапы
Сообщения: 113
Зарегистрирован: Сб янв 11, 2014 21:25:55

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

Сообщение Alex-Elektron »

Доброго времени суток! Такое дело получается: есть программа, в которой дружно работают 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:
Можно как-то через кейловский дебаг узнать, а каком прерывании завис МК? Прямо вот ситуативно, как только завис, подключиться и считать регистры нужной периферии?
Реклама
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

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

Сообщение dosikus »

Поробуйте, если дебуггер не помешает зависаниям. Я в таких случаях использую Ozone и Jlink - подключится к уже запущенному процессу...
Реклама
Аватара пользователя
Мурик
Друг Кота
Сообщения: 3383
Зарегистрирован: Пн окт 11, 2010 19:00:08

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

Сообщение Мурик »

Alex-Elektron писал(а):Можно как-то через кейловский дебаг узнать, а каком прерывании завис МК?
Не кейл, но может поймете как нужно настроить отладку. http://purebasic.mybb.ru/viewtopic.php?id=564#p7600
Аватара пользователя
Myp3ik
Мучитель микросхем
Сообщения: 450
Зарегистрирован: Вс янв 09, 2011 23:05:37
Откуда: СССР

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

Сообщение Myp3ik »

Там в отладке есть кнопка Stop. Когда контроллер зависнет нажмите её и увидите в каком месте он завис (если повезёт :))
Иван Сусанин - первый полупроводник :solder:
Реклама
Эиком - электронные компоненты и радиодетали
Alex-Elektron
Встал на лапы
Сообщения: 113
Зарегистрирован: Сб янв 11, 2014 21:25:55

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

Сообщение Alex-Elektron »

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)); и вернулся к тому, что было - пока полёт нормальный! Во всяком случае, пока я пишу это сообщение, МК ещё ни разу не завис
Реклама
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

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

Сообщение AlanDrakes »

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

Вернуться в «ARM»