Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.82/38: Рейтинг темы: голосов - 38, средняя оценка - 4.82
Tromomd
1

Проблема с таймером TIM2

12.01.2013, 16:03. Просмотров 7509. Ответов 15
Метки нет (Все метки)

Добрый день! Нужна ваша помощь.
Проблема в том, что в режиме отладки, сразу после включения таймера (TIM2->CR1 |= TIM_CR1_CEN;), устанавливается бит в регистре прерывания (CC1IF), хотя значение таймера не равно CCR1 и при этом переход на вектор прерывания не происходит. Что делать? Пробовал менять значения CCR1, PSC, ARR.

Вот код программы:
#include "stm32f10x.h"

void TIM2_IRQHomdler (void)
{
TIM2->CR1=0x0000;
TIM2->SR &= ~TIM_SR_UIF; // очищаем флаг
TIM2->SR &= ~TIM_SR_CC1IF;
GPIOC->BSRR=GPIO_BSRR_BS9; //Вкл
}

int main(void)
{
__enable_irq();
NVIC_EnableIRQ(TIM2_IRQn);

RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

GPIOC->CRH |= GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1;
GPIOC->CRH &= ~ GPIO_CRH_CNF9;

GPIOA->CRL &= ~GPIO_CRL_MODE0;
GPIOA->CRL &= ~GPIO_CRL_CNF0_0;
GPIOA->CRL |= GPIO_CRL_CNF0_1;
GPIOA->ODR &= ~GPIO_ODR_ODR0;

RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // вкл тактирование таймера

TIM2->DIER |= TIM_DIER_CC1IE;//прер по сравн первый канал бит - CC1IE

TIM2->PSC = 7; // пределитель 8000000/60000 - 1
TIM2->CCR1 = 700; // с каким значением сравниваем
TIM2->ARR = 5000;

TIM2->CR1 |= TIM_CR1_CEN; // запускаю

while(1){
}

}

Для проектов использую IAR
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.01.2013, 16:03
Ответы с готовыми решениями:

проблема с таймером и прерыванием
Решил подключить к stm32vldiscovery двухразрядный семисегментный индикатор. Включить отдельно...

Проблема с таймером в Center Aligned Mode
День добрый! Нужна помощь, два дня не могу решить проблему. Задача - с двух ног генерить ШИМ на...

STM32L152 проблема с таймером(ногой PB12) и DAC(PA5)
Есть проектик на STM32T152. К ноге PB12 подключен пьезик, и используется таймер TYM10 в качестве...

Прерывание от TIM2
Добрый день. Всплыла такая проблемка, что при инициализации NVIC void InteruptTIM2(void) { /*...

15
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 87
12.01.2013, 19:08 2
Перед включением таймера сгенерируй событие обновления:

TIM2->EGR|=(TIM_EGR_UG);

и будет тебе счастье.
Все настройки тактирования сравненияи и т. д. перегружаються в рабочие регистры после события обновления. Когда это события наступает - читай доку.
0
Tromomd
12.01.2013, 20:09 3
Спасибо!
теперь с CC1IF всё ок, только теперь друга проблема - на вектор прерывания не переходит
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 87
12.01.2013, 20:45 4
Эт, непонял...Что куда не переходит ??? Не заходим в функцию обработки прерывания ??
0
Tromomd
13.01.2013, 12:43 5
Да, в void TIM2_IRQHomdler (void)
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 87
13.01.2013, 15:43 6
У меня все работает, в прерывания заходим. НО.
Первое: ножно включить режим предзаграузки, раз уж задал величину предзагрузки:
TIM2->ARR = 5000;
TIM2->CR1|=TIM_CR1_ARPE;
второе - частота мерцания у тебя будет 1,663 кГц....???
третье - в прерывании ты выключаеш таймер, учти.
С уважением ))
0
Tromomd
13.01.2013, 20:51 7
Частота эт я просто экспериментировал =) Сейчас у меня частота 1 гц.
Почему-то после фун-ции разрешения прерывания NVIC_EnableIRQ(TIM2_IRQn); у меня в регистре NVIC устанавливается бит в регистре SITENA0 (т.е. разрешение прерывания) и при этом бит в регистре CLRENA0 (выключение прерывания), как так?
wro
18.01.2013, 01:06 8
У меня немного другая проблема:
Работаю с таймером по прерываниям. Использую функции (не напрямую с регистрами) Возникла проблема:
при инициализации таймера даю разрешение на прерывание, но не включаю таймер (он включается из кода).
Так вот, при вызове в инициализаторе NVIC_EnableIRQ(TIM2_IRQn); моментально происходит прерывание по переполнению (с переходом на обработчик). Откуда прерывание (таймер еще даже не включен)?
Параллельно интересует какой функцией устанавливается текущее значение счетчика?

На всякий привожу код:
Код
void HostTimerInit(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef hTimer;
TIM_TimeBaseStructInit(&hTimer);
hTimer.TIM_Pressotir = 16000 - 1;
hTimer.TIM_Period = 500;
TIM_TimeBaseInit(TIM2, &hTimer);

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

NVIC_EnableIRQ(TIM2_IRQn);
}

void HostTimerStart(void)
{
/* Включаем таймер */
TIM_Cmd(TIM2, ENABLE);
}

void HostTimerStop(void)
{
/* Выключаем таймер */
TIM_Cmd(TIM2, DISABLE);
}

void TIM2_IRQHomdler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESIT)
{
TIM_ClearITPendingByt(TIM2, TIM_IT_Update);

.... код .....

HostTimerStop();
}
}
Знатоки, еще поясните корректно ли так делать, либо есть более правильный подход?
wro
20.01.2013, 17:01 9
Не ужели ни у кого такой проблемы не возникало?
Почему при вызове
Код
NVIC_Init(&NVIC_InitStructure);
происходит прерывание, хотя таймер еще даже не включен...
Код main():
Код
   SystemInit();

RCC_ClocksTypeDef RCC_ClockFreq;
RCC_GetClocksFreq(&RCC_ClockFreq);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);
TIM_TimeBaseInitStructure.TIM_Pressotir = (uint16_t)(84000 - 1);
TIM_TimeBaseInitStructure.TIM_Period = 1000;  // раз в секунду переполнение

TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStructure);

/* Разрешаем прерывание по обновлению (в данном случае -
* по переполнению) счётчика таймера TIM6.
*/
TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = TIM6_DAC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure); //-- Тут уже срабатывает прерывание --

TIM_Cmd(TIM6, ENABLE);
и прерывание:
Код
void TIM6_DAC_IRQHomdler(void)
{
/* Так как этот обработчик вызывается и для ЦАП, нужно проверять,
* произошло ли прерывание по переполнению счётчика таймера TIM6.
*/
if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESIT)
{
/* Очищаем бит обрабатываемого прерывания */
TIM_ClearITPendingByt(TIM6, TIM_IT_Update);

GPIO_Write(GPIOD, GPIO_ReadOutputData(GPIOD) ^ (BLUE_LED)); //-- тогл светодиода
}
}
Подскажите в чем проблема пожалуйста...
0 / 0 / 0
Регистрация: 03.10.2012
Сообщений: 783
20.01.2013, 19:10 10
Ну... это вообще жесть... )))
TIM_TimeBaseInitStructure.TIM_Pressotir = (uint16_t)(84000 - 1);

А так... тактирование в наличии, биты юзабельны...
Прерывание разрешено, если бит взведён - вэлком то прерывание...
Смотрите состояние регистров TIM по входу в прерывание...
0
wro
20.01.2013, 19:41 11
1) Спасибо за ответ.
Цитата Сообщение от dork_usir
Ну... это вообще жесть... )))
TIM_TimeBaseInitStructure.TIM_Pressotir = (uint16_t)(84000 - 1);
А что не так подскажите? Просто не совсем понял (вернее совсем не понял)...
84000 - была тактовая частота 84 Мгц. (на полной - 168 000)

2) Сбросить это прерывание (при инициализации) как то можно?
0 / 0 / 0
Регистрация: 16.01.2013
Сообщений: 38
20.01.2013, 20:57 12
Цитата Сообщение от wro
1) Спасибо за ответ.
Цитата Сообщение от dork_usir
Ну... это вообще жесть... )))
TIM_TimeBaseInitStructure.TIM_Pressotir = (uint16_t)(84000 - 1);
А что не так подскажите? Просто не совсем понял (вернее совсем не понял)...
84000 - была тактовая частота 84 Мгц. (на полной - 168 000)

2) Сбросить это прерывание (при инициализации) как то можно?

1) unit16_t - 16 бит, максимальное значение - 65535, туда не получится 83к запихать
2) помню тоже была такая проблема - при инициализации происходило незапланированное прерывание, но это было с АЦП и в принципе было некритично, так что ничего с этим не делал =)
0
wro
21.01.2013, 00:58 13
1) ой... протупил
2)
помню тоже была такая проблема - при инициализации происходило незапланированное прерывание, но это было с АЦП и в принципе было некритично, так что ничего с этим не делал =)
Обойти то смогу, но думал что можно как то корректно решить...
0 / 0 / 0
Регистрация: 03.10.2012
Сообщений: 783
21.01.2013, 01:16 14
Сказал же... тормознитесь сразу после входа в прерывание и посмотрите TIM_SR... будет ясна причина...
Как правило всё сводится к установке TIM_EGR_UG при инициализации, ожиданию пару тактов, сбросу TIM_SR, разрешению прерываний и т.д. ...
0
wro
21.01.2013, 02:17 15
Спасибо за ответ. Но это пока не мой формат - знаний по регистрам пока не хватает.
wro
27.01.2013, 18:59 16
Может кому тоже понадобится: проблема решилась установкой бита URS в TIMx_CR1
Код
TIM_UpdateRequestConfig(TIM6, TIM_UpdateSource_Regular);
перед инициализацией таймера.
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.01.2013, 18:59

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

помогите с TIM2
привет, Начал изучать STM32 на примере STM32VLDyscover И вот добрался до таймеров. Решил сделать...

Захват и переполнение TIM2
STM8S003F3P6. IAR Stomdalone license 8K. ST-LINK V2. Измеряю длительность периода с помощью...

Прерывание таймера TIM2
Начал потихоньку разбираться в STM32. Сконфигурировал прерывание таймера 2 с частотой 1Гц (1...

STM8S + TIM2 +PWM
День добрый, господа. Возник вопрос. Сначала что сделал и в чем проблема: Настроил TIM2_CH1 вывод...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.