Ich habe das Blockdiagramm des Timers 3 noch einmal überprüft
Es sieht so aus, als gäbe es keine Verbindung zwischen channel 4
und dem Triggereingang TRGI
. Ist das richtig?
Kann ich Kanal 4 für den Gated-Modus verwenden?
Ich habe das folgende Signal mit unterschiedlicher Impulsbreite. (hoch)
Ich möchte die Impulsbreite mit einem STM32F030F4 messen (Link wegen Reputationslimit entfernt).
Das Signal wird an Pin 14, PB1 angeschlossen. Ich habe überprüft, dass das Signal direkt am Pin des µC erfasst werden kann, also sollte es dort sein. Ich möchte Timer 3 verwenden, weil sein Kanal 4 mit diesem Pin verbunden ist.
Kapitel 13.3.19 TIMx und externe Trigger-Synchronisation des Referenzhandbuchs beschreibt einen Modus, der genau das ist, was ich suche.
Slave-Modus: Gated-Modus
Der Zähler kann abhängig vom Pegel eines ausgewählten Eingangs aktiviert werden.
Auch dafür gibt es ein Beispiel:
A.8.13 Codebeispiel für den Gated-Modus
/* (1) Configure channel 1 to detect low level on the TI1 input by writing CC1S = ‘01’, and configure the input filter duration by writing the IC1F[3:0] bits in the TIMx_CCMR1 register (if no filter is needed, keep IC1F=0000). */ /* (2) Select polarity by writing CC1P=1 in the TIMx_CCER register */ /* (3) Configure the timer in gated mode by writing SMS=101 Select TI1 as the trigger input source by writing TS=101 in the TIMx_SMCR register. */ /* (4) Set prescaler to 12000-1 in order to get an increment each 250us */ /* (5) Enable the counter by writing CEN=1 in the TIMx_CR1 register. */ TIMx->CCMR1 |= TIM_CCMR1_CC1S_0; /* (1)*/ TIMx->CCER |= TIM_CCER_CC1P; /* (2) */ TIMx->SMCR |= TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0 | TIM_SMCR_TS_2 | TIM_SMCR_TS_0; /* (3) */ TIMx->PSC = 11999; /* (4) */ TIMx->CR1 |= TIM_CR1_CEN; /* (5) */
Ich habe versucht, das Beispiel an meine Bedürfnisse anzupassen und es sieht so aus:
// based on example A.8.13
/* (1) Configure channel 4 to detect low level on the TI4 input
* by writing CC4S = ‘01’,
* and configure the input filter duration by writing the IC1F[3:0]
* bits in the TIMx_CCMR1 register (if no filter is needed,
* keep IC1F=0000). */
/* (2) Select polarity by writing CC4P=1 in the TIMx_CCER register */
/* (3) Configure the timer in gated mode by writing SMS=101
* Select TI1 as the trigger input source by writing TS=101
* in the TIMx_SMCR register. */
/* (4) Set prescaler to 12000-1 in order to get an increment each 250us */
/* (5) Enable the counter by writing CEN=1 in the TIMx_CR1 register. */
TIM3->CCMR2 |= TIM_CCMR2_CC4S_0; /* (1) */
TIM3->CCER |= TIM_CCER_CC4P; /* (2) */
TIM3->SMCR |= TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0 | TIM_SMCR_TS_2 | TIM_SMCR_TS_0; /* (3) */
TIM3->PSC = 11999; /* (4) */
TIM3->CR1 |= TIM_CR1_CEN; /* (5) */
Ich würde erwarten, dass sich das Zählerregister von Timer 3 TIM3->CNT
im Laufe der Zeit ändert, wenn die Impulse hereinkitzeln.
Ändert sich jedoch TIM3->CNT
überhaupt nicht.
Hier ist die Konfiguration, von der ich vermute, dass sie fehlerhaft ist
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(tim_baseHandle->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspInit 0 */
/* USER CODE END TIM3_MspInit 0 */
/* Peripheral clock enable */
__TIM3_CLK_ENABLE();
/**TIM3 GPIO Configuration
PB1 ------> TIM3_CH4
*/
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN TIM3_MspInit 1 */
/* USER CODE END TIM3_MspInit 1 */
}
}
/* TIM3 init function */
void MX_TIM3_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_SlaveConfigTypeDef sSlaveConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_IC_InitTypeDef sConfigIC;
htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 0;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_IC_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED;
sSlaveConfig.InputTrigger = TIM_TS_ITR0;
if (HAL_TIM_SlaveConfigSynchronization(&htim3, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
}
Beim Debuggen kann ich sehen, wie sich die Konfigurationsregister ändern und ihre Werte lesen/schreiben, aber das Zählerregister erhöht sich nicht.
Es sieht so aus, als wäre die Verwendung des Eingangserfassungsmodus nicht möglich, da Kanal 4 nicht als Trigger verwendet werden kann.
Ich gebe auf. Zu viele verschiedene Beispiele im Web mit zu vielen verschiedenen Konfigurationstools, Toolchains usw.
Bence Kaulics
__TIM3_CLK_ENABLE();
?kreuzen
Bence Kaulics
kreuzen
Bence Kaulics
Bence Kaulics
HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
kreuzen
ITR0
die Triggerquelle in meinem Code ist, da der Beispielcode die Triggerquelle explizit auf setztTS=101
(siehe Kommentare). Wie auch immer, es gibt keinen Wert im Referenzhandbuch für die Triggerquelle, um Kanal 4 zu verwenden, was mich vermuten lässt, dass dies unmöglich ist. Wie wirdHAL_TIM_IC_Start
es funktionieren?Bence Kaulics
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED; sSlaveConfig.InputTrigger = TIM_TS_ITR0;
. ITR0 scheint also der Auslöser zu sein. Entschuldigung, ich habe mich mit dem Trigger-Controller geirrt, er treibt nur den CNT-Zähler an, der von allen Kanälen erfasst werden kann.