Здравствуйте. Программирую СТМки и в силу своих скудных знаний столкнулся с проблемой.
Контроллер STM32F100C6(на RB на плате Discovery аналогичное поведение).
Подаю, к примеру, на ETR 200 герц скважность 2.
1. Настраиваю Таймер Т2 на счет импульсов со входа ETR (частотомер), период задается таймером Т3 1 сек(мастер для Т2). Счет работает.
Код:
|
void EXT_FrequencyCounterConfig(void)
{
// TIM3 master counter, period 0.1, 1, 10, 100 sec
EXT_Timer2_ResetRegisters();
RCC-›APB1ENR |= RCC_APB1ENR_TIM3EN;
TIM3-›CR1 &= ~TIM_CR1_CEN;
NVIC_DisableIRQ(TIM3_IRQn);
TIM3-›PSC = 2400-1; // TIM3 clock 10 kHz
TIM3-›ARR = 10000-1; // TIM3 count 10000 so period 1 sec
TIM3-›CR1 |= TIM_CR1_DIR; // count down to 0
TIM3-›CR1 |= TIM_CR1_OPM; //counter stops counting at the next update event
TIM3-›CR2 |= TIM_CR2_MMS_0; //COUNTER_ENABLE signal to TIM1, used as trigger output (TRGO)
TIM3-›DIER |= TIM_DIER_UIE; //enable interrupt
// TIM2 slave counter, count impulses from TIM2_ETR
RCC-›APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2-›CR1 &= ~TIM_CR1_CEN;
NVIC_DisableIRQ(TIM2_IRQn);
TIM2-›PSC = 0;
TIM2-›ARR = 0xFFFF; //counter max value
TIM2-›CR1 = 0 ;
TIM2-›CR2 = TIM_CR2_MMS_1; //update event is selected as trigger output to TIM1
TIM2-›SMCR = TIM_SMCR_ECE | TIM_SMCR_TS_1 | TIM_SMCR_SMS_0 | TIM_SMCR_SMS_2; //ext. clock mode2 enabled, counter is clocked by ETRF signal
// TIM1 additional counter for TIM2 to make 32 bit counter
RCC-›APB2ENR |= RCC_APB2ENR_TIM1EN;
TIM1-›CR1 &= ~TIM_CR1_CEN;
TIM1-›PSC = 0;
TIM1-›ARR = 0xFFFF; //counter max value
TIM1-›CR1 &= ~TIM_CR1_DIR; //used as upcounter
TIM1-›SMCR &= ~TIM_SMCR_ETPS; //no external trigger prescaller
TIM1-›SMCR &= ~TIM_SMCR_ETF; //no external trigger filter
TIM1-›SMCR |=TIM_SMCR_TS_0;
TIM1-›SMCR |= TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_2; //TIM1 (TRGI) clock the counter
return;
}
//
void EXT_FrequencyCounterRun(void)
{
NVIC_DisableIRQ(TIM2_IRQn);
NVIC_EnableIRQ(TIM3_IRQn);
TIM1-›CR1 |= TIM_CR1_CEN;
TIM2-›CR1 |= TIM_CR1_CEN;
TIM3-›CR1 |= TIM_CR1_CEN;
}
// |
2. Пробую запустить таймер Т2 для измерения периода между импульсами и заполнение(скважность) - работает.
Код:
|
void EXT_PeriodCounterConfig(void)
{
EXT_Timer2_ResetRegisters();
// TIM2 count period and duty on TI1 input
RCC-›APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2-›CR1 &= ~TIM_CR1_CEN;
TIM2-›PSC = 240-1; // TIM2 clock 100 kHz
TIM2-›ARR = 0xffff;
// TIM2-›CR1 |= TIM_CR1_OPM; //counter stops counting at the next update event
TIM2-›CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_1;
// TIM2-›SMCR |= TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | TIM_SMCR_SMS_2; //
TIM2-›SMCR |= TIM_SMCR_TS_2 | TIM_SMCR_TS_0 ; //
TIM2-›SMCR |= TIM_SMCR_SMS_2; //
TIM2-›CCER |= TIM_CCER_CC2P | TIM_CCER_CC2E | TIM_CCER_CC1E ;
TIM2-›DIER |= TIM_DIER_CC1IE;//enable interrupt
return;
}
//
void EXT_PeriodCounterRun(void)
{
NVIC_DisableIRQ(TIM3_IRQn);
NVIC_EnableIRQ(TIM2_IRQn);
TIM3-›CR1 &= ~TIM_CR1_CEN;
TIM1-›CR1 &= ~TIM_CR1_CEN;
TIM2-›CR1 |= TIM_CR1_CEN;
RCC-›APB1ENR &= ~RCC_APB1ENR_TIM3EN;
RCC-›APB2ENR &= ~RCC_APB2ENR_TIM1EN;
RCC-›APB1ENR |= RCC_APB1ENR_TIM2EN;
} |
Обработчики прерываний таймеров 2 и 3:
Код:
|
void TIM3_IRQHandler(void)
{
TIM3-›SR &= ~TIM_SR_UIF; //reset interrupt flag
RawFreq = ((u32)(TIM1-›CNT) ‹‹ 16) | ((u32)(TIM2-›CNT));
DataReady = SET;
TIM2-›CNT = 0;
TIM1-›CNT = 0;
TIM3-›CR1 |= TIM_CR1_CEN; //another circle
iii++;
}
//
void TIM2_IRQHandler(void)
{
if((TIM2-›SR & (TIM_SR_CC1IF | TIM_SR_CC1OF))==(TIM_SR_CC1IF))
{
if(TIM2-›CCR1 !=0)
{
RawPeriod = (uint32_t)TIM2-›CCR1;
RawDuty = (uint32_t)TIM2-›CCR2;
DataReadyP = SET;
error = 0;
jjj++;
}
}
else if ((TIM2-›SR & TIM_SR_CC1OF) != 0) /* Check the overflow */
{
error = ERROR_OVERFLOW;
DataReadyP = SET;
TIM2-›SR &= ~(TIM_SR_CC1OF | TIM_SR_CC1IF); /* Clear the flags */
return;
}
else
{
error = ERROR_UNEXPECTED_IT; /* Report an error */
}
return;
}
// |
3. При попытке переключить таймер Т2 из режима измерения периода на режим измерения числа пришедших импульсов таймер считает, но гораздо медленнее(как будто включается скрытый делитель на входе ЕТR). В отладчике регистр TIM2-›CNT принимает значение 1, хотя в случае (1) показывает значения в районе 200.
для запуска счета импульсов (1) в основном коде запускаю
Код:
|
EXT_FrequencyCounterConfig();
EXT_FrequencyCounterRun(); |
для вычисления периода (2)запускаю
Код:
|
EXT_PeriodCounterConfig();
EXT_PeriodCounterRun(); |
Когда стал разбираться, в начале программы попробовал настроить таймер на режим (2), через некоторое время перенастраивал на режим (1).
Код:
|
EXT_PeriodCounterConfig();
EXT_PeriodCounterRun();
countFnotT=FALSE;
Delay_us(14030);
EXT_FrequencyCounterConfig();
EXT_FrequencyCounterRun();
countFnotT=TRUE;
__enable_irq(); |
При этом если задержку (в коде выше функция Delay_us()) делать небольшую - таймер считает правильно, если увеличивать задержку - включается непонятный "делитель и измеренное количество импульсов оказывается гораздо меньше"
В отладчике при сравнении значений регистров таймеров режима 1 и режима 3 (переключение из режима 2 в режим 1) они одинаковы.
Вопрос - подскажите, кто может, где я неправильно меняю настройки таймера Т2.
Программу пишу в кейл 4.73, проект прилагаю.