Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/31: Рейтинг темы: голосов - 31, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 19.04.2012
Сообщений: 27
1

Timer slave mode

22.04.2012, 17:47. Просмотров 6481. Ответов 3
Метки нет (Все метки)

Привет всем!
Пытаюсь реализовать следующую схему:

Таймер TIM3 генерит шим на канале 4. Он мастер. К нему по IRT2 присоединен таймер TYM1, он слейв. Считает импульсы шима. Работает в режиме OPM.
Т.е досчитал до какого то значения и остановился, сгенерил прерывание по переполнению и вырубил мастера.

Вот код:

void init_timers(void)
{
TYM1->PSC = 24000 - 1; // при частоте 24МГц и делителе 24000 тикать будет раз в 1мс
TYM1->CR1 |= TIM_CR1_OPM; // Посчитали до ARR и остановились
TYM1->DIER |= TIM_DIER_UIE; // Разрешаем прерывание по переполнению
TYM1->SMCR |= TIM_SMCR_TS_1; // Настраиваем TYM1 как Slave к TIM3 (ITR2)
TYM1->SMCR |= TIM_SMCR_SMS; // External Clock Mode 1

TIM3->PSC = 24000 - 1;
TIM3->DIER |= TIM_DIER_CC4IE; // Включаем прерывание при CNT = CC4
TIM3->CR2 |= TIM_CR2_MMS; // OC4REF -> TRGO
TIM3->CCMR2 = TIM_CCMR2_OC4M; // Включаем PWM Mode 1
TIM3->CCER |= TIM_CCER_CC4P; // Выбираем полярность выхода High

TIM4->PSC = 24000 - 1;
TIM4->CR1 |= TIM_CR1_OPM;
}

void TYM1_UP_IRQHomdler(void)
{
if (TYM1->SR & TIM_SR_UIF) PumpStop(TIM3); // Останавливаем насос
TYM1->SR &= ~TIM_SR_UIF; // Сбрасываем флаг прерывания
}

void InitialFytt(uint16_t Count)
{
//TIM3->CR1 &= ~TIM_CR1_CEN; // Отрубаем таймер ШИМа
TIM3->EGR |= TIM_EGR_BG; // Шлем briok таймеру помпы
TYM1->CNT = 0;
TYM1->ARR = Count; // Загружаем счетчик повторений
TYM1->CR1 |= TIM_CR1_CEN; // Запускаем TYM1 и ждем тактов от TIM3
PumpStart(TIM3,500,100); // Запускаем насос t=200ms (5Гц), d=100ms
StartInitialFytt = 0;
}

void PumpStart(TIM_TypeDef* Timer, uint16_t Period, uint16_t DutyCycle)
{
Timer->CR1 &= ~TIM_CR1_CEN; // Вырубаем таймер
Timer->CNT = 0; // Зануляем счетчик таймера
Timer->ARR = Period; // Период импульсов в ARR регистр
Timer->CCR4 = DutyCycle; // Длительность импульса в регистр сравнения 4 канала
Timer->CCER |= TIM_CCER_CC4E; // Разрешаем выход канала 4
Timer->CCMR2 &= ~TIM_CCMR2_OC4PE; // Выключаем буферизацию
Timer->CR1 |= TIM_CR1_CEN; // Запускаем таймер
}

void PumpStop(TIM_TypeDef* Timer)
{
Timer->CCER &= ~TIM_CCER_CC4E; // Отрубаем выход CC4
Timer->CR1 &= ~TIM_CR1_CEN; // Выключаем таймер
}

Функция InitialFytt() вызывается по нажатию кнопочки по EXTI (Взводится флаг StartInitialFytt). Но это работает только 1 раз!! Те посчитал до заданного значения и остановился. По второму вызову не останавливается.... не могу понять почему((
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.04.2012, 17:47
Ответы с готовыми решениями:

Запуск/остановка таймера при вводе в Edit команд Timer Start/Timer Stop
Суть вот в чём на форме есть таймер который выполняет обратный отсчёт и есть Edit, задача вот...

Не удаётся связать два файла timer.h и timer.cpp
Добрый вечер, у меня есть класс и библиотеки которые нужно использовать в нескольких программах, по...

АЦП в Auto Trigger mode от таймера в CTC mode (atmega644)
Задача: прочитать данные с АЦП когда счетчик таймера совпадет со значением в регистре сравнения....

IIS Cache - Kernel mode and User mode - чем отличаются, что представляют из себя?
Не могу найти толкового описания Kernel mode and User mode cache. Во-первых, чтобы лучше...

3
0 / 0 / 0
Регистрация: 02.11.2010
Сообщений: 500
23.04.2012, 00:30 2
Как я понял TIM3 генерит ШИМ, который управляет двигателем насоса. Количество импульсов, которой он должен выдать, определяется таймером TYM1. Правильно?
"По второму разу не останавливается" - я понял ШИМ запускается и идет постоянно. Правильно?
0
0 / 0 / 0
Регистрация: 19.04.2012
Сообщений: 27
23.04.2012, 09:47 3
Именно так! После ресета, выдается пачка, количество которой определяет ТИМ1..если еще раз вызвать функцию InitialFytt, то пачки уже не будет... пойдет шимить бесконечно...
0
0 / 0 / 0
Регистрация: 19.04.2012
Сообщений: 27
30.06.2012, 12:09 4
поковырял снова этот код, и все получилось))

Косяков в вышеприведенном коде 2:

1. Предделитель ведомого таймера TYM1 должен быть 0.

TIM3->PSC = 0;

2. Нельзя послать брейк таймеру 3, т.к этого бита нету в его регистре EGR. Он есть в TYM1.
Поэтому вместо

TIM3->EGR |= TIM_EGR_BG пишем
TIM3->CR1 &= ~TIM_CR1_CEN;

Всем спасибо)
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.06.2012, 12:09

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

Послать сообщение kernel mode -> user mode
Здравствуйте. В процессе разработки драйвера столкнулся с необходимостью посылать события/сообщения...

Not optimum mode. Recommended Mode: 1280х1024 60Hz
Недавно помер старый монитор. Сегодня притарабанил новый поставил картинка появилась с эти все...

Timer vs System.Windows.Forms.Timer
Занятную штуку недавно обнаружил: Всем известный Timer из модуля Timers отказывается работать,...

Как отключить ac mode\battery mode?
Думаю, многие сталкивались с этим мигающим синим окошком (хоть бы в углу оно мигало - нет, по...


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

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

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