Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F100 - инициализация таймеров
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Veg@
Осваиваю работу с АРМ на STM32VL-Discovery.
Использую 6 таймеров (1,2,3,15,16,17) в режиме ШИМ. Инициализация:
CODE
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_BaseConfig;
TIM_OCInitTypeDef TIM_OCConfig;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_
AFIO, ENABLE);

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_11;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_15;
GPIO_Init(GPIOB, &GPIO_InitStruct);

GPIO_PinRemapConfig(GPIO_Remap_TIM15, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16|RCC_APB2Periph_TIM17, ENABLE);

TIM_BaseConfig.TIM_Prescaler = (uint16_t)(24000000 / 2000000) - 1;
TIM_BaseConfig.TIM_Period = 400;
TIM_BaseConfig.TIM_ClockDivision = 0;
TIM_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_BaseConfig);
TIM_TimeBaseInit(TIM2, &TIM_BaseConfig);
TIM_TimeBaseInit(TIM3, &TIM_BaseConfig);
TIM_TimeBaseInit(TIM15, &TIM_BaseConfig);
TIM_TimeBaseInit(TIM17, &TIM_BaseConfig);
TIM_TimeBaseInit(TIM16, &TIM_BaseConfig);

TIM_OCConfig.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCConfig.TIM_Pulse = TIM_BaseConfig.TIM_Period/2;
TIM_OCConfig.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OC4Init(TIM1, &TIM_OCConfig); //pa11
TIM_OC1Init(TIM2, &TIM_OCConfig); //pa0
TIM_OC3Init(TIM3, &TIM_OCConfig); //pb0
TIM_OC2Init(TIM15, &TIM_OCConfig); //pb15
TIM_OC1Init(TIM16, &TIM_OCConfig); //pb8
TIM_OC1Init(TIM17, &TIM_OCConfig); //pb9
TIM1->BDTR |= TIM_BDTR_MOE;
TIM15->BDTR |= TIM_BDTR_MOE;
TIM16->BDTR |= TIM_BDTR_MOE;
TIM17->BDTR |= TIM_BDTR_MOE;

TIM_Cmd(TIM1, ENABLE);
TIM_Cmd(TIM2, ENABLE);
TIM_Cmd(TIM3, ENABLE);
TIM_Cmd(TIM15, ENABLE);
TIM_Cmd(TIM16, ENABLE);
TIM_Cmd(TIM17, ENABLE);
В данном случае ШИМ присутствует на всех инициализированных выводах. Но если строку RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16|RCC_APB2Periph_TIM17, ENABLE); заменить двумя последовательными инициализациями для таймеров 16 и 17, то на их выходах ШИМ отсутствует. Также, если, например, заменить инициализацию для таймеров 1 и 2 сложением:
Код
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1|RCC_APB1Periph_TIM2, ENABLE);
то отключается ШИМ на выходе таймера 2.
При этом регистры TIMx_CNT инкрементируются для всех таймеров верно. Почему так происходит и что, возможно, я не учитываю?
Golikov A.
кривизну убогих библиотек от СТМ?

по мануалу регистры проверьте, что там за флаги ставятся и ставятся ли?

Почитал мануальчик, вот реально не вижу смысла подмены строчки

RCC_APB1ENR |= TIM2_ANBLE;

строчкой

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

в чем бизнес? кроме того что вы теряете суть RCC_APB1

таймер 1 и 2 в разных регистрах!!!!

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); - это во 2 регистре
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); - это в 1 регистре

и конечно же строчка

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1|RCC_APB1Periph_TIM2, ENABLE);
теряет смысл!

думаю что с 16 и 17 таймером была таже фигня, вы их при копипасте не в том регистре включали




Я понимаю еще если бы они сделали хитрую функцию, которой просто говоришь включи и устройства списком, а она сама по регистрам раскидывает. Это имело бы смысл, не надо было бы биты по мануалу смотреть. А так просто куча лишних слов, при этом жестко привязанных к регистрам и без какой либо защиты... ТУПО!!!!

Если вы только начинаете осваивать работу с АРМ, начните ее с понимания что все надо делать по мануалу, а не при помощи библиотек. Так вы избавите себя от множества тупых граблей и индийско-индуских ошибок, при этом ничего не потеряете. Как показал ваш пример, в более длинном названии теряется суть! Делали бы по мануалу, вы бы точно знали что 1 и 2 таймер в разных регистрах и желания их врубить одновременно у вас бы не было. А при включении 16 и 17 таймеров вы бы поглядели в каком они регистре и не вызывали бы левого названия!
esaulenka
Цитата(Golikov A. @ Jul 21 2014, 23:01) *
без какой либо защиты...

Справедливости ради: это неправда. Там есть assert_param(), который можно включить на этапе разработки драйверов, и который хоть что-то проверяет.

Впрочем, я и сам стараюсь обходиться без этой чудо-писанины, просто по ref.manual.
SasaVitebsk
biggrin.gif
Справедливости ради уже появился sth32cube и там библиотека заменена на HAL и, например, это уже через макросы осуществляется ...
__TIM3_CLK_ENABLE();
__TIM4_CLK_ENABLE();
Кроме того, хочется отметить, что некоторые драйвера написаны очень даже прилично. Я смотрел по диагонали, но всёже например USART, на мой взгляд написан достаточно прилично. Если бы всё уже без этого не работало, то можно было бы воспользоваться даже ... rolleyes.gif
Но работа с GPIO вызывает всё тот же весёлый смех ... ))
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.