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

STM32F4+таймеры+захват

Чт мар 17, 2016 10:59:44

Всем привет!
Продолжаю мучить таймеры и форумчан=))
Перешел к изучению режима захвата.
В программе дрыгаю светодиодами с задержкой 5 сек.
попутно таймером TIM3 первый канал которого находится на PA6 пытаюсь захватить сигнал со светодиода, что живет на PD12. Просто замыкаю эти две ноги.
Код:
#include "stm32f4xx.h"                  // Device header

void init_gpio(void);
void init_timer(void);
void led_blinking(void);


static volatile uint32_t TimeTick;
volatile int capture1;
volatile int capture2;

void SysTick_Handler() {
   if(TimeTick)
   {
      TimeTick--;
   }
}

void TIM3_IRQHandler(){
   if(TIM3->SR&2){
   }
}


int main(){
   SysTick_Config(SystemCoreClock/1000);
   init_gpio();
   init_timer();
   while(1){
      led_blinking();
   }
   
}

void init_gpio(){
   /*Configure pins 12, 13, 14, 15 on port D*/
   RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
   GPIOD->MODER = 0x55000000;
   
   /*Cofigure TIM3, Channel 1 (PA6)*/
   RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
   GPIOA->MODER = GPIO_MODER_MODER6_0;
   GPIOA->AFR[0] = 0x02000000;
}

void init_timer(){
   RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
   TIM3->CCMR1 |= TIM_CCMR1_CC1S_0;                           // CH1 to PA6
  TIM3->CCMR1 |= (TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1);            //
  TIM3->CCER &= ~TIM_CCER_CC1P;
  TIM3->CCER &= ~TIM_CCER_CC1NP;
  TIM3->CCMR1 &= ~TIM_CCMR1_IC1PSC;                           //
  TIM3->CCER |= TIM_CCER_CC1E;                              //
  TIM3->DIER |= TIM_DIER_CC1IE;                              //
  TIM3->CR1 |= TIM_CR1_CEN;                                 //
  NVIC_EnableIRQ(TIM3_IRQn);   
}


void DelaymS(uint32_t time){
   TimeTick = time;
    while(TimeTick);
}

void led_blinking(){
   GPIOD->BSRRH = GPIO_BSRR_BS_12 | GPIO_BSRR_BS_13 | GPIO_BSRR_BS_14 | GPIO_BSRR_BS_15; //LEDs On
   DelaymS(5000);//Delay using SysTick
   GPIOD->BSRRL = GPIO_BSRR_BS_12 | GPIO_BSRR_BS_13 | GPIO_BSRR_BS_14 | GPIO_BSRR_BS_15; //LEDs Off
   DelaymS(5000);
}

Настроил порт Д и диоды.
Настроил порт А и для шестой ноги определил альтернативную функцию.
Настроил таймер в режиме захвата, захват по фронту.
Но почему-то не заходит в прерывание. Период изменения сигнала для светодиодов 5 сек.
Где я мог ошибиться?
Вложения
L7_Genral_purpose_timer_Capture_input_LED_CMSIS.zip
(776.55 KiB) Скачиваний: 327

Re: STM32F4+таймеры+захват

Пн мар 21, 2016 07:51:55

Проблема была в том, что я неверно настроил пин на альтернативную функцию.
Код:
GPIOA->MODER = GPIO_MODER_MODER6_1;
должно быть
А вот насчет установки предделителя PSC и значения ARR не уверен, что обязательно устанавливать. У меня и так и так работает. То есть мк уходит в прерывание. Может кто объяснить надо ли для захвата их настраивать?

Далее решил разобраться а как же определить период сигнала.
По идее в обработчике прерывания необходимо (сбросить флаг само собой) записать в переменную значение TIM3->CCR1, а затем вычислить разницу между предыдущим и следующим значениями.
Код:
capture1 = capture2 = 0;
   capture2 = TIM3->CCR1;
   t = capture2 - capture1;

Верно?
Но почему-то t какая-то фигня пишется. HEX в DEC не забываю перевести.

Re: STM32F4+таймеры+захват

Чт авг 03, 2017 14:09:34

Как добиться от CubeMX установки в код прерываний по совпадению с каким-нибудь каналом, а не по переполнению счетчика?
Последний раз редактировалось *BoyKot* Чт авг 03, 2017 15:50:16, всего редактировалось 2 раз(а).

Re: STM32F4+таймеры+захват

Чт авг 03, 2017 15:47:44

Нет там никакого "прерывания по переполнению" для таймеров общего назначения. Есть TIMх global interrupt, который для всего. И есть регистр разрешения определённых прерываний TIMх_DIER, и есть регистр состояния флагов TIMх_SR. Вот по флагам и определяется, что именно послужило причиной прерывания.
Да и смысла в этом "как в AVR" аж никакого.

Re: STM32F4+таймеры+захват

Чт авг 03, 2017 15:51:45

Нет там никакого "прерывания по переполнению" для таймеров общего назначения. Есть TIMх global interrupt, который для всего. И есть регистр разрешения определённых прерываний TIMх_DIER, и есть регистр состояния флагов TIMх_SR. Вот по флагам и определяется, что именно послужило причиной прерывания.
Да и смысла в этом "как в AVR" аж никакого.


Да, разобрался. Прерывания эти действительно есть в stm32. Целых 4 канала сравнения. Точнее прерывание одно, а дальше надо разбираться в его причинах по флагам. Все-таки в AVR были разные прерывания на разные регистры сравнения.

Re: STM32F4+таймеры+захват

Чт авг 03, 2017 17:09:06

TIM1_BRK_UP_TRG_COM_IRQn
TIM1_CC_IRQn

Re: STM32F4+таймеры+захват

Сб ноя 13, 2021 17:05:10

Вопрос по прерываниям.(STM32F4) Атолик, код заносится в ОЗУ, пишу в обработчик прерывания код для таймера TIM2.Получается что в дебагере, когда код в ОЗУ прерывания не работают. Написал просто через if проверкой бита UIF, всё работает.Как сделать чтобы штатные хендлеры работали при дебагере из ОЗУ. Почему из ОЗУ , да я стока раз перезагружаю боюсь,что камень не выдержит(хоть и обещают для F4 10000 перезагрузок). Дефайн раскоментировал ( #define VECT_TAB_SRAM).Разрешаю прерывания для TIM2 может не достаточно ,может нужно и глобальные разрешить.

Re: STM32F4+таймеры+захват

Сб ноя 13, 2021 17:35:50

Как сделать чтобы штатные хендлеры работали при дебагере из ОЗУ.
1. Проверить в map-файле по какому адресу слинкована таблица векторов прерывания.
2. Проверить чтобы SCB->VTOR указывал на неё.

Re: STM32F4+таймеры+захват

Сб ноя 13, 2021 17:52:30

Ок буду смотреть

Re: STM32F4+таймеры+захват

Вс ноя 14, 2021 21:42:38

Всё решено, мой косяк был.Прерывание работает и из ОЗУ.Скопировал код с экрана, не проверил :facepalm: .Входит в обработчик.

Re: STM32F4+таймеры+захват

Пн ноя 15, 2021 20:59:29

Да... маловато знаний у меня. Работает , только если я явно вызываю обработчик в цикле while.

Добавлено after 7 hours 26 minutes 55 seconds:
Заработало , всё ок. А разобрался с помощью всеми забытого CooCoxa.Жаль что забросили его. Кстати компилит быстрее чем последний Атолик.

Re: STM32F4+таймеры+захват

Ср ноя 17, 2021 18:29:39

Всё нормально входит в прерывания из ОЗУ, ничего не меняю 3-5 раз, потом стоп уже всё не входит. Это Толик. кидаю этот же проект в СооСох всё нормально 5-10 раз проганяю в дебагере, опять стоп уже не заходит в прерывания. Что могло бы быть. после 5-10 раз прогона, ничего не меняя уже прерывания им не нравятся. Что это ....

Добавлено after 1 hour 40 minutes 4 seconds:
Интересный эффект в СооСохе. Компилирую проект под флеш, потом под озу, тогда всё работает. Если только под озу не хочет в дебагере работать. Короче сначала собираю для флеш потом для озу.

Re: STM32F4+таймеры+захват

Ср ноя 17, 2021 18:39:21

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

При старте из флеша грузитcя адрес SP, при выполнении из SRAM нужно его загрузить самостоятельно, так, например:
Код:
asm ("ldr sp, =_estack");

Иначе будет работать только если во флеше есть старая прошивка. Опять же Reset_Handler тоже берется из флеша и таблица векторов разбивается на две части, но это если основной код во флеше, а таблица векторов в RAM. Что у тебя там вообще не понятно, т.к. ни строчки кода предоставлено не было...

Re: STM32F4+таймеры+захват

Чт ноя 18, 2021 19:46:02

Какой файл показать. Что там смотреть. Скрипт линкера наверно?А в main что там ...
В Атолике внизу скрипты линкера в CooCoxe я их не могу найти

Re: STM32F4+таймеры+захват

Сб ноя 20, 2021 17:01:14

Вот main.c В прерывании просто мигают диоды по очереди. Вопрос, почему пока один раз во флеше на скомпилирую, то в озу не дебажится. Ставлю галочку дебаг во флеш собираю проект, потом ставлю галочку дебаг в RAM и всё дебаг идёт. В ST_link утилите память 0x08000000 это флеш , там чисто стоят FFFFFFFF Значит там нет таблицы прерываний. Вернее там нет вектора стека и вектора сброса.

Код:

   #include "stm32f4xx.h"
   #include "stm32f4xx_gpio.h"
   #include "stm32f4xx_rcc.h"
   #include "misc.h"
   #include "stm32f4xx_tim.h"

   void GPIO(void);
   void TIM_config(void);

   void NVIC_Config();

   void TIM3_IRQHandler(void);
   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;



   void TIM_config(void)
   {
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

   TIM_TimeBaseStructure.TIM_Prescaler=0x00FF;

   TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
   TIM_TimeBaseStructure.TIM_ClockDivision=0;
   TIM_TimeBaseStructure.TIM_Period=0xFF00;
     TIM_ITConfig( TIM3,  TIM_IT_CC1,ENABLE);

   TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

   TIM_Cmd(TIM3,ENABLE);
   }

   void GPIO(void)
   {
   GPIO_InitTypeDef GPIO_InitStructure;

   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);


   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
      GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
      GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
      GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
      GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOD,&GPIO_InitStructure);
   }




      int main()
   {
       NVIC_Config();
       GPIO();
         TIM_config();
         
           while(1)
      {

      }
   }



      void NVIC_Config()

      {
      NVIC_InitTypeDef NVIC_InitStructure;
      NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);

      }
      void TIM3_IRQHandler(void)

      {
                   switch (TIM_GetCounter ( TIM3) )

                 {

                   case  10000:
                      GPIO_SetBits(GPIOD, GPIO_Pin_12);
                     break;
                   case 20000:

                      GPIO_SetBits(GPIOD, GPIO_Pin_14);
                      break;

                    case 30000:
                             GPIO_SetBits(GPIOD, GPIO_Pin_13);
                       break;

                    case 40000:
                                GPIO_SetBits(GPIOD, GPIO_Pin_15);
                     break;

                   case 50000:
                               GPIO_ResetBits(GPIOD,GPIO_Pin_12|GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15);


                           break;



                }

      }

Re: STM32F4+таймеры+захват

Сб ноя 20, 2021 18:31:55

Вы больше доверяйте халу. Он в ините изменяет адрес таблицы прерываний в никуда.
Поправка: Конечно же куб, а не хал. Столкнулся на прошлой неделе. У меня самописный стартап работает, а у товарища генерированный кубом нет.
Последний раз редактировалось GARMIN Вс ноя 21, 2021 18:26:24, всего редактировалось 1 раз.

Re: STM32F4+таймеры+захват

Сб ноя 20, 2021 19:34:19

Извините меня чайника "халу" это кто. КУБ чтоли.

Re: STM32F4+таймеры+захват

Вс ноя 21, 2021 11:24:05

Меня просто интересует один эффект и всё. Почему в СооСохе нужно хотя бы раз поставить точку дебаг во флеше, а потом уже можно и из SRAM дебаг. Что не нравится дебагу если сразу во SRAM.

Re: STM32F4+таймеры+захват

Вт ноя 23, 2021 00:12:08

За перемещение таблицы прерываний отвечает линкер. Где в СооСохе он не могу найти. В Толике в проекте всё внизу валяется, в кокосе спрятали.
Вот нашёл, всё в озу таблица никак не делится на флеш и озу или я не прав?
Код:

Linker script and memory map

                0x20020000                _eram = 0x20020000

.text           0x20000000      0x758
 *(.isr_vector)
 .isr_vector    0x20000000      0x188 ..\obj\startup_stm32f4xx.o
                0x20000000                g_pfnVectors
 *(.text*)
 .text.Default_Reset_Handler
                0x20000188       0x6c ..\obj\startup_stm32f4xx.o
                0x20000188                Default_Reset_Handler
                0x20000188                Reset_Handler
 .text.Default_Handler





Добавлено after 25 minutes 30 seconds:
Вы больше доверяйте халу. Он в ините изменяет адрес таблицы прерываний в никуда.
Поправка: Конечно же куб, а не хал. Столкнулся на прошлой неделе. У меня самописный стартап работает, а у товарища генерированный кубом нет.

Я ваще люблю регистры, чего их так гнобят некоторые. Открыл мануал и всё лежит на ладони - простейше. Не пойму, тяжело цифру загнать в указатель.?

Добавлено after 1 hour 52 minutes 51 second:
TIM1_BRK_UP_TRG_COM_IRQn
TIM1_CC_IRQn

tim1 это не таймер общего назначения , прерывания для расширенного таймера. А ВОПРОС был по таймерам общего.

Добавлено after 7 hours 22 minutes 45 seconds:
В этой теме я сам с собой общаюсь, прикольно.Ничего stm я потихоньку "распилю", хай на это и потрачу кучу времени

Re: STM32F4+таймеры+захват

Вт ноя 23, 2021 06:12:04

1. Диалог подозревает, что вы хоть как-то реагируете на реплики собеседника.
2. Таймер сконфигурирован неправильно. Вероятно, вы не совсем понимаете как он работает.
3. В обработчике ерунда написана:
- Такой код возможен только если прерывание каждый инкремент счётчика таймера будет. Это невозможно.
- Включили вы прерывание по СС1 не сконфигурировав его.
- Флаги прерывания надо очищать при выходе.
- и т.д. и т.п.
4. Начните мигание диодами на SysTick. Он куда проще в работе. Для мигания диодами его примерно на 100 Гц настройте. В обработчике прерывания статический счётчик программный заведите и уже от него свитчём стройте свои алгоритмы мигания.
Ответить