Перейти к содержанию
    

STM32F103C8T - перезапуск таймера от внешнего сигнала

Пытаюсь перенести на STM32 свой старый проект на MSP430. И второй день туплю с применением таймера.

Делаю OSD. Алгоритм простой - на ногу 10 (PA0) подключен HSYNC. От него должен запустится таймер (TIM2) и запустить через какое-то время DMA и вызвать прерывание. Хотелось бы все сделать с минимумом кода, момент запуска DMA должен быть точно привязан к HSYNC, иначе изображение будет дергаться.

Задом чуствую, как-то надо использовать one pulse mode, но не выходит каменный цветок :(

Прошу помощи более опытных товарищей - с STM32 я только начал играться. Ткните носом в пример кода инициализации таймера :)

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Ткните носом в пример кода инициализации таймера :)

 

Не буду оригинален, на сайте производителя смотрели всевозможные библиотеки с примерами или просто примеры?

В кубе были по мойму примеры генерации подобных вещей.

 

(круглый)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно и по старинке - почитать мануал, понять, как всё это работает... Или это нынче не модно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо на добром слове, вот такая заготовка заработала:

void hsync_timer_init(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
 GPIO_Init(GPIOA, &GPIO_InitStructure);

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

/* Time base configuration */
 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
 TIM_TimeBaseStructure.TIM_Period = 100;
 TIM_TimeBaseStructure.TIM_Prescaler = 72-1;
 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

 /* TIM2 PWM2 Mode configuration: Channel1 */
 TIM_OCInitTypeDef TIM_OCInitStructure;
 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
 TIM_OCInitStructure.TIM_Pulse = 20;
 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
 TIM_OC1Init(TIM2, &TIM_OCInitStructure);

 /* TIM2 configuration in Input Capture Mode */

 TIM_ICInitTypeDef TIM_ICInitStructure;
 TIM_ICStructInit(&TIM_ICInitStructure);
 TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
 TIM_ICInitStructure.TIM_ICFilter = 0;
 TIM_ICInit(TIM2, &TIM_ICInitStructure);

 /* One Pulse Mode selection */
 TIM_SelectOnePulseMode(TIM2, TIM_OPMode_Single);
 /* Input Trigger selection */
 TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
 /* Slave Mode selection: Trigger Mode */
 TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger);
 //TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE)
 TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

 TIM_Cmd(TIM2, ENABLE);
 NVIC_EnableIRQ(TIM2_IRQn);
}

void TIM2_IRQHandler(void)
{
 TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
 SPI1->DR |= 0xCCCC;
 SPI2->DR |= 0x3333;
}

 

Понять бы почему, мне кажется, что

 

TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);

 

не в тему, должно быть TIM_TS_TI1FP1

 

А куб, конечно, хорошая вещь, когда памяти немеряно и спешить некуда. Ну и не удалось мне совместить HAL с scmRTOS.

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Ну и не удалось мне совместить HAL с scmRTOS.

А scmRTOS Вы раньше использовали и теперь хотите использовать я так понял? Я вот на днях, благодаря участнику esaulenka, обнаружил, что оказывается есть много библиотек и софта (esaulenka писал конкретно о stm32tpl) Участника данного форума - АНТОХА кажется его никнейм точно сейчас не помню и у него есть портированная эта ОС тоже. Человек сделал большую работу и выложил ее для всеобщего доступа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

scmRTOS чудесно работает с CMSIS, а куб генерирует HAL. У меня не получилось заставить вместе работать кубовый USB стек и scmRTOS.

Хотя может быть и к лучшему - HAL память жрет, как свинья помои.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

scmRTOS чудесно работает с CMSIS, а куб генерирует HAL...

Хм.. Значит Вы же попробовали/проверили эту ОС на этом контроллере. А я думал, что нет..

...

Хотя может быть и к лучшему - HAL память жрет, как свинья помои.

А где именно Вы нашли, что много памяти он жрет? Я спрашиваю это потому, что сам такой же новичок в АРМ-ах хотя уже лет 20 (двадцать) контроллерами занимаюсь. То что HAL много "лишних" движений делает - это понятно. Т.к. задумка для него была сделать универсальность еще. То что бывают неучтенные баги и недочеты для конкретного контроллера - это тоже понятно (опять-таки из-за универсальности). То что есть некоторые сильно "кривые" моменты - тоже понятно. Но про жрание памяти пока не знал. Память программ Вы может имели ввиду? А не ОЗУ как я понял? Это да, но ведь это не просто использование памяти, а использование памяти кодом (хоть и кривым/растянутым, но готовым уже и вместо вашего он уже есть). Еще можно отключить некоторые вещи в Cube для экономии памяти (Full Assert и т.п.). А еще, у человека про которого я написал и одного из разработчиков/писателей этой scmRTOS (АНТОХА) есть также свой фреймворк как альтернатива HAL-у. Может его попробуете? Попробуете его потом наверно все-таки т.к. сейчас основная проблема - это разобраться вначале с работой периферии (Таймера и пр.) - тут, у стм-овских контроллеров, она гораздо сложнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А где именно Вы нашли, что много памяти он жрет?

На собственном грустном опыте - у MSP430 стек отъел меньше 8к памяти - у STM в районе 20. scmRTOS не пошла - пришлось ставить FreeRTOS - еще 10 кбайт долой, плюс оперативку хорошо подъела. Короче, FreeRTOS, USB, IMU и дисплей - 60к долой. Аналогичная задача на MSP заняла меньше 20к. Ну и сложность периферии - это смотря с чем сравнивать. По-моему у MSP430 периферия посложнее будет, но есть хорошие примеры, которые снимают все вопросы.

Кстати, то же OSD на MSP430 мне удавалось сделать использую около 200 байт оперативки для видео буферов :)

хотя уже лет 20 (двадцать) контроллерами занимаюсь.

Ну Вы еще совсем молодой, у Вас все впереди :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На собственном грустном опыте - у MSP430 стек отъел меньше 8к памяти - у STM в районе 20...

Да - большая разница (хотя все-равно не понятно откуда там так много - 20К, но все равно это не так важно). Еще по именно Вашей теме напишу такую вещь - HAL как бы вводит понятия уже более "сложного" программирования и у него есть такие полезные вещи как callback-и и тут они пригодились бы. Но Вы пишите про использование FreeRTOS (и еще Вам важно быстродействие системы), то тогда это про как информация пусть будет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пытаюсь перенести на STM32 свой старый проект на MSP430. И второй день туплю с применением таймера.

Делаю OSD. Алгоритм простой - на ногу 10 (PA0) подключен HSYNC. От него должен запустится таймер (TIM2) и запустить через какое-то время DMA и вызвать прерывание. Хотелось бы все сделать с минимумом кода, момент запуска DMA должен быть точно привязан к HSYNC, иначе изображение будет дергаться.

Задом чуствую, как-то надо использовать one pulse mode, но не выходит каменный цветок :(

Прошу помощи более опытных товарищей - с STM32 я только начал играться. Ткните носом в пример кода инициализации таймера :)

 

Я бы сделал следующим образом:

Подключить строчный синхроимпульс ко входу input capture свободно бегущего таймера.

В обработчике прерывания input capture прибавил к захваченному значению требуемое время задержки в тиках таймера (h front porch) и записал полученную сумму в compare register для output compare того же таймера. В обработчике прерывания output compare запускать DMA.

Если не все понятно -- могу углубиться в детали.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы сделал следующим образом:

Подключить строчный синхроимпульс ко входу input capture свободно бегущего таймера.

В обработчике прерывания input capture прибавил к захваченному значению требуемое время задержки в тиках таймера (h front porch) и записал полученную сумму в compare register для output compare того же таймера. В обработчике прерывания output compare запускать DMA.

Если не все понятно -- могу углубиться в детали.

Примерно так кода-то делал - на другом процессоре - наложенное изображение дергается, немного, но неприятно. А когда таймер, запускаемый от hsync автоматически запускает DMA безо всяких прерываний - получается абсолютно стабильная картинка. Теоретически и STM32 должно быть то же самое - но пока у меня DMA от таймера запускается - но со временем какая-то беда, что-то не так настраиваю. В примере от ST пишут, что используется CCR1, а что-то непонятное они делают с CCR2 (/Project/STM32xx_StdPeriph_Examples/TIM/OnePulse folder.)

В принципе, эта идея вролне совместима с Вашей - вполне можно вместо вызова прерываний запустить DMA, если мой вариант не сработает - попробую Ваш.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На собственном грустном опыте - у MSP430 стек отъел меньше 8к памяти - у STM в районе 20. scmRTOS не пошла - пришлось ставить FreeRTOS - еще 10 кбайт долой, плюс оперативку хорошо подъела. Короче, FreeRTOS, USB, IMU и дисплей - 60к долой.

Что-то это как-то слишком - 60К под такую простую задачу.

Вот у меня сейчас открыт в чём-то похожий проект на Cortex-M: uCOS + USB + SPI-LCD (своя графика: прямые, прямоугольники, треугольники, текст, ...) + АЦП + прочие мелочи.

Всё в сумме: 29704 (ro code) + 20216 (ro data), причём "ro data" - это в основном шрифты и пиктограммы. Так что, если не считать шрифтов, флеши наберётся на <30К. Да и то из них там много лишнего - MassStorage в USB который там болтается, но пока не используется. Если его да всякую отладку повыкидывать - будет наверное чуть больше 20кил. Ваш проект ещё меньше флеши должен занять.

А стек Вы сами выделяете, раз сами выделили 20, вот он столько и съел. Выделяйте меньше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всё в сумме: 29704 (ro code) + 20216 (ro data), причём "ro data" - это в основном шрифты и пиктограммы. Так что, если не считать шрифтов, флеши наберётся на <30К. Да и то из них там много лишнего - MassStorage в USB который там болтается, но пока не используется. Если его да всякую отладку повыкидывать - будет наверное чуть больше 20кил.

И все это с кубовым USB и HAL? Что компилятор может настолько разный размер генерить - не очень похоже (в моем случае GCC).

Без HAL размеры несколько скромнее.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И все это с кубовым USB и HAL?

Нет конечно, такое гумно не использую. USB-стек из примеров IAR, остальное (кроме uCOS) - своё.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Примерно так кода-то делал - на другом процессоре - наложенное изображение дергается, немного, но неприятно. А когда таймер, запускаемый от hsync автоматически запускает DMA безо всяких прерываний - получается абсолютно стабильная картинка. Теоретически и STM32 должно быть то же самое - но пока у меня DMA от таймера запускается - но со временем какая-то беда, что-то не так настраиваю. В примере от ST пишут, что используется CCR1, а что-то непонятное они делают с CCR2 (/Project/STM32xx_StdPeriph_Examples/TIM/OnePulse folder.)

В принципе, эта идея вролне совместима с Вашей - вполне можно вместо вызова прерываний запустить DMA, если мой вариант не сработает - попробую Ваш.

 

Вам надо найти если возможно заускать DMA по таймеру или output compare -- тогда и предложенный мной способ будет безупречен :).

 

В моем предложении задержка с прерыванием, запускающим DMA может привести к дерганью картинки. Но всегда можно найти способ улучшить. Навскидку:

поставить прерывание на время перед окончанием front porch и запретить все остальные прерывания, разрешив их после старта DMA.

Второй вариант -- остальные процессы делать без прерываний, либо синхронизировать с hsync, избегая опасного участка -- момента окончания front porch.

Третий вариант -- делать ожидание окончания front porch чуть короче и выжигать время в цикле внутри прерывания.

Задержка с input capture interrupt пофиг. Там железо захватывает значение в регистр.

 

Нет конечно, такое гумно не использую. USB-стек из примеров IAR, остальное (кроме uCOS) - своё.

 

Я с кубовым подхожу к окончанию проекта. Нареканий нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...