реклама на сайте
подробности

 
 
> STM32f4 PWM проблема с первым импульсом
EmbedElektrik
сообщение Jul 8 2015, 05:57
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 121
Регистрация: 30-07-08
Из: Тверь, Россия
Пользователь №: 39 321



Задача получить серию импульсов строго заданной продолжительности и количества. Использую PWM. В приведенном коде я хочу получить два импульса по 10 мкс с паузой 40.
CODE

основной код
.................
tim_init();
TIM2->CNT=15;//предустановка счетчика в пределах низкой фазы
pulses_cnt=2;// количество импульсов
TIM_Cmd(TIM2,ENABLE); // запускаем счёт
}
//**************************************************************************
void TIM2_IRQHandler()
{
if(TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
GPIO_ResetBits(GPIOE, GPIO_Pin_9);// сброс по COMPARE
pulses_cnt--;
if(pulses_cnt==0)TIM_Cmd(TIM2, DISABLE);
}
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIO_SetBits(GPIOE, GPIO_Pin_9); // фронт по UPDATE
}
}
//****************************************************************************

void tim_init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

TIM_OCStructInit(&oc_init);
oc_init.TIM_OCMode = TIM_OCMode_PWM1; // работаем в режиме ШИМ ( PWM )
oc_init.TIM_OutputState = TIM_OutputState_Enable;
oc_init.TIM_Pulse = 10; //
oc_init.TIM_OCPolarity = TIM_OCPolarity_High; // положительная полярность
TIM_OC3Init(TIM2,&oc_init);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);

TIM_TimeBaseStructInit(&base_timer);
base_timer.TIM_Prescaler = 84 - 1; // делитель частоты
base_timer.TIM_Period = 50-1; // период
base_timer.TIM_CounterMode = TIM_CounterMode_Up; // счёт вверх
TIM_TimeBaseInit(TIM2, &base_timer);
TIM_ITConfig(TIM2, TIM_IT_CC3 | TIM_IT_Update, ENABLE);
TIM_ARRPreloadConfig(TIM2,DISABLE);

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
NVIC_EnableIRQ(TIM2_IRQn);
}

В итоге получаю следующую картинку.
Красный - мой вывод PWM, с двумя требуемыми импульсами, но перед ними влезает какой-то мелкий пик природу появления которого я не могу понять. Желтым цветом вывожу прерывания таймера - нарастающий фронт соответсвует событию таймера UPDATE, спадающий - COMPARE. Видно, что при первом прерывании update PWM как и требуется поднимается в 1, но почему-то тут же падает в 0 через странные 1.6 мкс и взводится опять через 35 мкс. После вывод PWM начинает работать как и планировалось. Теоретически можно отрубить первый мусорный импульс, но это костыль. Хотелось бы понять почему я в трех соснах заблудился.


Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 28)
Golikov A.
сообщение Jul 8 2015, 06:53
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Что-то как-то через одно место, если честно.
Зачем таймер в ШИМе если вы ноги дергаете руками?

по сути вопроса думаю что это библиотечка так работает. ШИМ параметры скважности применяются когда таймер досчитал, потому после первой их задачи обычно дергают таймер так чтобы он как бы досчитал и обновил состояние, это думаю вы и наблюдаете
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 8 2015, 07:04
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Golikov A. @ Jul 8 2015, 09:53) *
Зачем таймер в ШИМе если вы ноги дергаете руками?

Действительно. Какой-то абсурд.
В STM32 можно сделать нужную пачку импульсов чисто на таймерах, процессор может вообще спать. Но для этого нужно почитать, как таймеры работают - они там хитровывернутые. Зато после чтения такие вопросы возникать не будут.
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 8 2015, 07:26
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(scifi @ Jul 8 2015, 10:04) *
Действительно. Какой-то абсурд.

Видимо, это как раз управление желтым каналом осциллографа.
Красный канал - аппаратный.

Попробуйте на строчку веше, чем
Код
TIM_ITConfig(TIM2, TIM_IT_CC3 | TIM_IT_Update, ENABLE);

прописать нечто, вида:
Код
TIM2->EGR = TIM_EGR_UG; // 1

Go to the top of the page
 
+Quote Post
EmbedElektrik
сообщение Jul 8 2015, 07:59
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 121
Регистрация: 30-07-08
Из: Тверь, Россия
Пользователь №: 39 321



Цитата(Golikov A. @ Jul 8 2015, 09:53) *
Что-то как-то через одно место, если честно.
Зачем таймер в ШИМе если вы ноги дергаете руками?

по сути вопроса думаю что это библиотечка так работает. ШИМ параметры скважности применяются когда таймер досчитал, потому после первой их задачи обычно дергают таймер так чтобы он как бы досчитал и обновил состояние, это думаю вы и наблюдаете

Я руками не дергаю. Желтый канал для дебага - чтобы сравнивать поведение прерываний относительно фазы PWM.


Цитата(adnega @ Jul 8 2015, 10:26) *
Видимо, это как раз управление желтым каналом осциллографа.
Красный канал - аппаратный.

Попробуйте на строчку веше, чем
Код
TIM_ITConfig(TIM2, TIM_IT_CC3 | TIM_IT_Update, ENABLE);

прописать нечто, вида:
Код
TIM2->EGR = TIM_EGR_UG; // 1

увы, картина не изменилась sad.gif
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 8 2015, 08:51
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



CODE

#define PULSE_ACT (10)
#define PULSE_INACT (40)
#define PULSE_NUM (2)

volatile int puls = 0;

//-----------------------------------------------------------------------------
// void TIM2_IRQHandler(void)
//-----------------------------------------------------------------------------
void TIM2_IRQHandler(void)
{
if(TIM2->SR & (1 << TIM_SR_UIF))
{
TIM2->SR = ~(1 << TIM_SR_UIF);
if(puls) puls--;
else
{
set_pin(LED_ACTIVE_PIN, 0);
TIM2->CR1 = 0;
}
}
}

//-----------------------------------------------------------------------------
// void ufunc_demo(void *p)
//-----------------------------------------------------------------------------
void ufunc_demo(void *p)
{
NVIC->ISER[0] = (1 << NVIC_ISER0_TIM2);

TIM2->PSC = FPLL / 2 / 1000000 - 1;
TIM2->ARR = PULSE_ACT + PULSE_INACT - 1;
TIM2->CCR1 = TIM2->ARR + 1 - PULSE_ACT;
TIM2->CCMR1 = (OC_MODE_PWM2 << TIM_CCMR1_OC1M);
TIM2->EGR = (1 << TIM_EGR_UG);
TIM2->CCER = (1 << TIM_CCER_CC1E);
TIM2->DIER = (1 << TIM_DIER_UIE);
TIM2->CNT = TIM2->CCR1;
puls = PULSE_NUM - 1;
TIM2->CR1 = (1 << TIM_CR1_CEN);

set_pin(LED_ACTIVE_PIN, 1);
}

Я библиотеками не пользуюсь. Управляю напрямую регистрами. Названия битов соответствуют номеру бита, а не маске.
TIM2_CH1 - красная линия
LED_ACTIVE_PIN - желтая линия

Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
EmbedElektrik
сообщение Jul 8 2015, 10:50
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 121
Регистрация: 30-07-08
Из: Тверь, Россия
Пользователь №: 39 321



Цитата(adnega @ Jul 8 2015, 11:51) *
Я библиотеками не пользуюсь. Управляю напрямую регистрами. Названия битов соответствуют номеру бита, а не маске.
TIM2_CH1 - красная линия
LED_ACTIVE_PIN - желтая линия


Спасибо, идея инверсии понятна. У меня заработало. Но непонятки с моей изначальной инициализацией остались sad.gif С управлением регистрами напрямую все равно этот импульс пролазит.
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 8 2015, 11:48
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(EmbedElektrik @ Jul 8 2015, 13:50) *
Но непонятки с моей изначальной инициализацией остались sad.gif

Я не особо понимаю, что там с первым импульсом, меня больше волнует окончание последовательности:
PWM1 примечателен тем, что в момент UPDATE он устанавливает пин в лог. 1, т.е. в конце последовательности вывод установится в лог. 1.
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Jul 8 2015, 12:21
Сообщение #9


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



1. остановили таймер
2. отключили буферизацию
3. заполнили регистры делителей, счетчиков, сравнения
4. включили буферизацию
5. запустили таймер
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jul 9 2015, 03:55
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



EmbedElektrik, на самом деле всё очень просто. Регистр делителя частоты - буферизованный. Твоё заданное значение будет переписано в рабочий регистр только после первого события апдейта таймера.

Сообщение отредактировал ArtDenis - Jul 9 2015, 06:36


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 9 2015, 05:15
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(ArtDenis @ Jul 9 2015, 06:55) *
Регистр делителя частоты - буферизованный. Твоё заданное значение будет переписано в рабочий регистра только после первого события апдейта таймера.

В сообщении №5 ТС сказал, что апдейт не помогает (никак не меняет картину).
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jul 9 2015, 06:13
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Цитата(adnega @ Jul 9 2015, 10:15) *
В сообщении №5 ТС сказал, что апдейт не помогает (никак не меняет картину).

Усп. Не увидел. Ну значит проблема где-то в коде. Лично меня немного напрягает строка
Код
TIM2->CNT=15;


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 9 2015, 08:24
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(ArtDenis @ Jul 9 2015, 09:13) *
Лично меня немного напрягает строка
Код
TIM2->CNT=15;

Хоть намекните чем?
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jul 9 2015, 09:28
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Цитата(adnega @ Jul 9 2015, 13:24) *
Хоть намекните чем?

Ну вообще судя по приведённому коду он не должен влиять. Скважность шима = 10, а значение счётчика - 15. По умолчанию таймер на выходе ШИМа должен выдавать 0. Так возможно, что проблема в коде, который ТС не привёл.

Ещё идея. По умолчанию, счётчик равен 0. Значит на выходе ШИМа сразу после настройки таймера должен быть 1. Если между настройкой таймера и кодом TIM2->CNT=15; стоит ещё какой-то код (который ТС не показал), то на выходе некоторое время будет держаться 1.

PS: всякие TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable) и им подобные не надо делать перед заданием значений, а не после как у ТС?

PPS: ТС-у лучше привести минимальный компилируемый код, который воспроизводит ошибку.


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 9 2015, 09:38
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(ArtDenis @ Jul 9 2015, 12:28) *
PPS: ТС-у лучше привести минимальный компилируемый код, который воспроизводит ошибку.

У ТС сейчас есть рабочий код. Есть ли смысл воспроизводить и анализировать нерабочий код?
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jul 9 2015, 09:40
Сообщение #16


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



adnega, как это есть рабочий код? Вот его последнее сообщение (жирным выделено мной):
Цитата(EmbedElektrik @ Jul 8 2015, 15:50) *
Спасибо, идея инверсии понятна. У меня заработало. Но непонятки с моей изначальной инициализацией остались sad.gif С управлением регистрами напрямую все равно этот импульс пролазит.



--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 9 2015, 09:45
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



я так понял инвертировали ШИМ и все работает, а в старом варианте даже с прямым управлением регистрами пролазит импульс. Я так понимаю эти сообщения. Природа импульса как я понимаю в том что на время инициализации ШИМ как раз выдает 1, потом сбрасывается обновлением для принятия новых настроек, и работает штатно.
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 9 2015, 10:03
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Golikov A. @ Jul 9 2015, 12:45) *
я так понял инвертировали ШИМ и все работает, а в старом варианте даже с прямым управлением регистрами пролазит импульс. Я так понимаю эти сообщения.

Я тоже так понял.

Цитата(Golikov A. @ Jul 9 2015, 12:45) *
Природа импульса как я понимаю в том что на время инициализации ШИМ как раз выдает 1, потом сбрасывается обновлением для принятия новых настроек, и работает штатно.

PWM1 устанавливается в единичку в момент update.
Если инициализация приводит к update, то на выходе будет единичка.
Меня больше волнует вопрос: кто сбрасывает вывод в ноль после формирования пачки импульсов? У меня получается стабильная единичка на выходе в конце.
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Jul 9 2015, 12:34
Сообщение #19


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



а как вы формируете _пачку_, в каком регистре тот счётчик ?
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 9 2015, 12:45
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Огурцов @ Jul 9 2015, 15:34) *
а как вы формируете _пачку_, в каком регистре тот счётчик ?

Я формирую пачку программно, счетчик в переменной и обрабатывается в прерывании таймера (update).
Можно сделать каскадное соединение таймеров, но для двух импульсов с приличной задержкой между ними - по-моему, перебор.
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Jul 9 2015, 13:23
Сообщение #21


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



я вам о том и говорю: формируете сами - чего ждёте от железа ?
если же второй таймер подключить, то там 146% начнёт работать как надо
у меня на это только один вопрос остался - обязательно ли первый таймер должен иметь вход брейк или можно как-то на внутренней коммутации или эвентах это замутить ?
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 9 2015, 16:33
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Огурцов @ Jul 9 2015, 16:23) *
я вам о том и говорю: формируете сами - чего ждёте от железа ?

Я бы не торопился разделять железо и софт.
Нужно грамотно управлять и тем, и тем.
Вариантов решения много: самый простой аппаратный - вывод через SPI байта 01000010 с длительностью бита 10мкс.
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Jul 9 2015, 16:36
Сообщение #23


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



уверены, что заработает ? мега, например, страдала тем, что выводила дополнительную паузу между байтами, типа девятого бита
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 9 2015, 16:41
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Огурцов @ Jul 9 2015, 19:36) *
уверены, что заработает ? мега, например, страдала тем, что выводила дополнительную паузу между байтами, типа девятого бита

Между байтами путь будет любая пауза. Битовый интервал формируется делителем и очень стабильно.
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Jul 9 2015, 18:29
Сообщение #25


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



меня любая пауза не устраивает, мне нужно заданное количество импульсов заданной частоты и заданной длительности
оне ведь даже регистр специальный для этого сделали
вот бы он ещё работал согласно своему названию

Сообщение отредактировал Огурцов - Jul 9 2015, 18:30
Go to the top of the page
 
+Quote Post
EmbedElektrik
сообщение Jul 10 2015, 06:49
Сообщение #26


Частый гость
**

Группа: Свой
Сообщений: 121
Регистрация: 30-07-08
Из: Тверь, Россия
Пользователь №: 39 321



Вобщем господа я забил на эту проблему - тупо перевожу на время инициализации вывод в GPIO. Вобщем STM прекрасно выдает последовательность. На картинке серия из 6ти импульсов со скважностью 25 50 и 75% (попарно). Внизу импульсы гашения со второго канала таймера.
Если кто разберется как победить инициализацию - буду признателен.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 10 2015, 07:16
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



я так понимаю что именно как вы и победили.
самый первый вывод ШИМ из-за буферных регистров всегда кривоватый ИМХО...
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jul 10 2015, 09:25
Сообщение #28


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Цитата(EmbedElektrik @ Jul 10 2015, 11:49) *
Вобщем господа я забил на эту проблему - тупо перевожу на время инициализации вывод в GPIO

Так вам тут же написали - сразу после инициализации ШИМ выдаёт 1, поэтому импульс и вылазит до момента присвоения TIM2->CNT=15;


Можно вместо перевода в GPIO и TIM2->CNT=15 просто при инициализации задать длительность ШИМа в 0, а потом когда, он понадобится, выставить нужное значение.


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
EmbedElektrik
сообщение Jul 10 2015, 10:14
Сообщение #29


Частый гость
**

Группа: Свой
Сообщений: 121
Регистрация: 30-07-08
Из: Тверь, Россия
Пользователь №: 39 321



Цитата(ArtDenis @ Jul 10 2015, 12:25) *
Так вам тут же написали - сразу после инициализации ШИМ выдаёт 1, поэтому импульс и вылазит до момента присвоения TIM2->CNT=15;


Можно вместо перевода в GPIO и TIM2->CNT=15 просто при инициализации задать длительность ШИМа в 0, а потом когда, он понадобится, выставить нужное значение.

я уже сейчас не помню, потому что чего я только с таймером не делал, но при CNT=0 ширина первого импульса была больше чем должна быть. Вобщем, возможно позже вернусь к этому вопросу, а пока надо деньги зарабатывать sm.gif
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 02:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01647 секунд с 7
ELECTRONIX ©2004-2016