kil00 0 25 февраля, 2013 Опубликовано 25 февраля, 2013 · Жалоба Здравствуйте! Использую stm32f107vc. Пытаюсь синхронизировать два таймера (TIM3 и TIM5), как включающиеся синхронно от внешнего импульса. Настроил их, как написано в RM0008 стр.386: void TIM3(void) { RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // подача тактов на TIM3 от шины тактирования APB1 TIM3->PSC = 70 - 1; TIM3->ARR = 25000 - 1; TIM3->DIER &=~ TIM_DIER_UIE; TIM3->CR1 |= TIM_CR1_ARPE; // сброс по достижении максимального значения // в мастер-режиме передаёт данные о своих Enable, как триггерный выход (MMS=001) TIM3->CR2 |= TIM_CR2_MMS_0; /*!<Bit 0 */ TIM3->CR2 &=~ TIM_CR2_MMS_1; /*!<Bit 1 */ TIM3->CR2 &=~ TIM_CR2_MMS_2; /*!<Bit 2 */ // в подчиненном режиме, чтобы получить входной триггер TI1 (TS=100) TIM3->SMCR &=~ TIM_SMCR_TS_0; /*!<Bit 0 */ TIM3->SMCR &=~ TIM_SMCR_TS_1; /*!<Bit 1 */ TIM3->SMCR |= TIM_SMCR_TS_2; /*!<Bit 2 */ // в режиме триггера (SMS=110) TIM3->SMCR &=~ TIM_SMCR_SMS_0; /*!<Bit 0 */ TIM3->SMCR |= TIM_SMCR_SMS_1; /*!<Bit 1 */ TIM3->SMCR |= TIM_SMCR_SMS_2; /*!<Bit 2 */ // установка задержки для того, чтоб таймеры очень хорошо синхронизировались (MSM=1) TIM3->SMCR |= TIM_SMCR_MSM; TIM3->CNT = 0; // обнулить счётчик, чтобы его значение после синхронизации равнялось 0x00 } void TIM5 (void) { RCC->APB1ENR |= 1<<3; // TIM5EN подача тактов на TIM5 от шины тактирования APB1 TIM5->PSC = 70 - 1; TIM5->ARR = 25000 - 1; TIM5->DIER &=~ TIM_DIER_UIE; TIM5->CR1 |= TIM_CR1_ARPE; // сброс по достижении максимального значения // получаем входной триггер от TIM3 (TS=001) как в Table 86 TIM5->SMCR |= TIM_SMCR_TS_0; /*!<Bit 0 */ TIM5->SMCR &=~ TIM_SMCR_TS_1; /*!<Bit 1 */ // TS=001 TIM5->SMCR &=~ TIM_SMCR_TS_2; /*!<Bit 2 */ // в режиме триггера (SMS=110) TIM5->SMCR &=~ TIM_SMCR_SMS_0; /*!<Bit 0 */ TIM5->SMCR |= TIM_SMCR_SMS_1; /*!<Bit 1 */ TIM5->SMCR |= TIM_SMCR_SMS_2; /*!<Bit 2 */ TIM5->CNT = 0; // обнулить счётчик, чтобы его значение после синхронизации равнялось 0x00 } В итоге, снимая по запросу значения регистров CNT из обоих таймеров, по USART'у получаю такие значения: при TIM5->ARR = 25000 - 1; и TIM3->ARR = 25000 - 1; значения регистров CNT одинаковые (например, 0x5936 и 0x5936 или 0x728 и 0x728), и так с любыми одинаковыми значениями регистров ARR таймеров. а при TIM5->ARR = 50000 - 1; и TIM3->ARR = 25000 - 1; значения регистров CNT, по идее, должны отличаться на 25000 (0х61A8), а реально они, например, вот такие - 0x22D4 и 0x216F или такие - 0x556D и 0xB5B0. В чём может быть проблема? Может быть, что-то не так настроил? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maksimp 0 25 февраля, 2013 Опубликовано 25 февраля, 2013 · Жалоба Ответа не знаю но варианты: 1. Уберите TIM5->CR1 |= TIM_CR1_ARPE; - это совсем про другое чем вы пишете в комметариях. Bit 7 ARPE: Auto-reload preload enable 0: TIMx_ARR register is not buffered 1: TIMx_ARR register is buffered buffered - значит первый раз используется предыдущее значение, сохранённое в теневом регистре. 2. Чаще выводите CNT через UART и смотрите как они изменяются. Сначала оба нарастают от 0, потом TIM5->CNT приближается к 25000 - что дальше? Для замедления и удобства наблюдения можно увеличить PSC обоих таймеров. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kil00 0 26 февраля, 2013 Опубликовано 26 февраля, 2013 · Жалоба 1. Уберите TIM5->CR1 |= TIM_CR1_ARPE; - это совсем про другое чем вы пишете в комметариях. Зачем убирать этот бит, если он отвечает за значение, до которого таймер считает, без него, как раз, гикак. А комментарий я уберу. Да, это я перед тем как создать тему немного откорректировал свои комментарии и не заметил этих строк, поэтому вышла ошибка. 2. Чаще выводите CNT через UART и смотрите как они изменяются. Сначала оба нарастают от 0, потом TIM5->CNT приближается к 25000 - что дальше? Для замедления и удобства наблюдения можно увеличить PSC обоих таймеров. Спасибо. Буду пробовать. Вчера возникла идея, что проблема из-за битового поля TS регистра SMCR. Начал просто перебирать возможные значения, но только при значении TS=001 оба счётчика работают, во всех других вариантах счётчик TIM5 всё время равен 0. В общем, cегодня попробую поменять местами TIM5 и TIM3. Не очень понятна эта таблица 86 (RM0008 стр.386). Из описания следует, что Slave TIM, в моём варианте, - это TIM5 (стр. 386), находим TIM3 и получаем - ITR1 (TS = 001). Вроде бы всё верно, но попробую поменять таймеры местами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maksimp 0 26 февраля, 2013 Опубликовано 26 февраля, 2013 · Жалоба Зачем убирать этот бит, если он отвечает за значение, до которого таймер считает, без него, как раз, гикак. А комментарий я уберу. В том то и дело что когда бит TIM_CR1_ARPE выствлен то таймер будет 1 раз считать до _не того_ значения. Когда этот бит выставлен, то регистр ARR существует в двух экземплярах - видимый для процессор и теневой, с которым работает таймер. И они могут быть не равны друг другу. Теневой становится равным тому который видимый для процессора _после_ каждого досчёта до конца. То есть первый раз будет использовано не то что туда записали, а то что там было ранее. Смотрите рисунок 108 "Counter timing diagram, Update event when ARPE=1 (TIMx_ARR preloaded)" на странице 354 в reference manual. Там в ARR записали 0x36, но считает всё равно до 0xf5. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kil00 0 28 февраля, 2013 Опубликовано 28 февраля, 2013 (изменено) · Жалоба Спасибо. Буду разбираться. Выставление бита ARPE в ноль в обоих таймерах ничего не изменяет.. Пока что единственное решение этого вопроса - это включить ОБА таймера по приходу внешнего сигнала, не синхронизируя их. Но очередная проблема с таймерами в STM32 останется не решённой... Изменено 28 февраля, 2013 пользователем MarYuriy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kil00 0 5 марта, 2013 Опубликовано 5 марта, 2013 · Жалоба В попытках найти ответ на свой вопрос, я получил правильный ответ от Железнякова Дениса (www.ziblog.ru), причём ответил он втечение 20 минут. За что я ему очень благодарен! Вот сам ответ: Вы используете предварительные делители у обоих таймеров. Оба предделителя буфферизированны, т.е. просто запись значения ничего не меняет, изменения происходят только после события обновления. Следовательно вам необходимо добавить: TIM4->PSC = 70 - 1; TIM4->EGR |= TIM_EGR_UG; Это действие: а) сбросит их б) установить новый модуль счета И всё работает, как надо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sidy 1 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба У меня возник вопрос. Если при достижении таймером TIM1 переполнения я хочу сбросить таймер TIM4 могу ли я написать следующим образом TIM4->CNT=0? Или же если мне нужно не сбросить а продолжить счет TIM4 с определенного значения могу ли я записать TIM4->CNT=X? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kil00 0 7 марта, 2013 Опубликовано 7 марта, 2013 · Жалоба У меня возник вопрос. Если при достижении таймером TIM1 переполнения я хочу сбросить таймер TIM4 могу ли я написать следующим образом TIM4->CNT=0? Или же если мне нужно не сбросить а продолжить счет TIM4 с определенного значения могу ли я записать TIM4->CNT=X? Насколько я понимаю, сначала нужно выключить счётчик TIM4->CR1 &=~ TIM_CR1_CEN, потом внести значение в регистр CNT, после чего счётчик включить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться