2014-03-24 07:39 AM
I'm working with STM32L151, and I'm trying to set the LSI clock as Timer 10 source. I tryed the following configuration but it didn't work properly (counts at system clock frequency). Can anyone help me to find the correct configuration?
Thank you!
// Enables LSI clock
RCC->CSR |= RCC_CSR_LSION;
// Waits LSI ready
while (!(RCC->CSR & RCC_CSR_LSIRDY)){__NOP();}
/* Enable TIM10 clocks */
RCC->APB2ENR|= RCC_APB2ENR_TIM10EN;
__DSB();
// Timer 10 Configuration
TIM10->CR1 = 0x0000; // tDTS = tCK_INT
// TIMx_ARR is not buffered
// Counter overflow and Setting the UG bit generate an UEV
// UEV enabled
// Counter disabled
TIM10->SMCR = 0x0000;
// ETR is non-inverted (Not used)
// External clock disable (counter is not clocked by edges on the ETRF)
// ETRP prescaler disabled
// ETRP not filtered
TIM10->SR = 0x0000; // Reset all Interrupt Flags
TIM10->DIER = TIM_DIER_UIE; // Capture Compare Interrupt DISABLED, Update Interrupt ENABLED
TIM10->CCER = 0x0000; // Ensure capture disabled (to modify TIM10->CCMR1 CC1S)
TIM10->CCMR1= TIM_CCMR1_CC1S_0;
TIM10->CCMR1= TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1PSC_1 | TIM_CCMR1_IC1PSC_0;
// Input mode:
// Sampling is done at fDTS
// Prescaler = 8
// CC1 channel is configured as input, IC1 is mapped on TI1
TIM10->CCER = TIM_CCER_CC1E; // Capture polarity non inverted/rising edge
// Capture enabled
TIM10->CNT = 0x0000; // Counter value
TIM10->PSC = 0x0000; // Prescaler = 1
TIM10->ARR = 0xFFFF; // Auto Reload Register
TIM10->CCR1 = 0x0000; // Compare Register
TIM10->OR = TIM_OR_TI1RMP_0; //Remap LSI to TIM10_CH1
// Initialize Interruption NVIC
NVIC_EnableIRQ(TIM10_IRQn);//Enable TIM10 Interruption
NVIC_SetPriority(TIM10_IRQn, NVIC_IPR0_PRI_0);//Priority 0
//Update Registers
TIM10->EGR = TIM_EGR_UG;
//TIM10 enable
TIM10->CR1 |= TIM_CR1_CEN;
#timer #lsi
2014-03-24 11:02 AM
Bit of a blind stab, but..
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_RTCAccessCmd(ENABLE);
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
/* TIM10 configuration *******************************************************/
/* Enable TIM10 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE);
/* Configure Time Base */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM10, &TIM_TimeBaseStructure);
/* Connect LSI clock to TIM10 Input Capture 1 */
TIM_RemapConfig(TIM10, TIM10_LSI);
/* Select External Source */
TIM_TIxExternalClockConfig(TIM10, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 0);
/* Enable TIM10 counter */
TIM_Cmd(TIM10, ENABLE);
2014-03-25 02:48 AM
It still does not work with this configuration.
In TIM10_IRQHandler a LED goes up and down each overflow to find the real frecuency. The result is 32MHz clock (HSI, the system used clock).int main(void)
{
//LED Config
RCC->AHBENR |= RCC_AHBENR_GPIOCEN;
GPIOC->MODER &= ~GPIO_MODER_MODER0;
GPIOC->MODER |= GPIO_MODER_MODER0_0;
GPIOC->OTYPER &= (uint16_t)~(GPIO_OTYPER_OT_0);
GPIOC->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0);
GPIOC->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR0_1 | GPIO_OSPEEDER_OSPEEDR0_0);
GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPDR0);
GPIOC->BSRRH = (uint16_t)GPIO_BSRR_BS_0; //VERD ON
GPIOC->BSRRL = (uint16_t)GPIO_BSRR_BS_0; //VERD OFF
DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM10_STOP;
/************************************************/
//Your code
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_RTCAccessCmd(ENABLE);
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
/* TIM10 configuration **************/
/* Enable TIM10 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE);
/* Configure Time Base */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM10, &TIM_TimeBaseStructure);
/* Connect LSI clock to TIM10 Input Capture 1 */
TIM_RemapConfig(TIM10, TIM10_LSI);
/* Select External Source */
TIM_TIxExternalClockConfig(TIM10, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 0);
/* Enable TIM10 counter */
TIM_Cmd(TIM10, ENABLE);
/**************** END ************************/
// Initialize Interruption NVIC
NVIC_EnableIRQ(TIM10_IRQn);//Enable TIM10 Interruption
NVIC_SetPriority(TIM10_IRQn, NVIC_IPR0_PRI_0);//Priority 0
TIM10->DIER = TIM_DIER_UIE; // Update Interrupt ENABLED
//Infinite loop
int i = 0;
while(1)
{
while( i < 255) i ++;
i = 0;
__NOP();
}
return 0;
}
void TIM10_IRQHandler (void)
{
TIM10->SR &= ~TIM_SR_UIF;
TIM10->SR &= ~TIM_SR_CC1IF;
if (LedState== 0) {
GPIOC->BSRRH = (uint16_t)GPIO_BSRR_BS_0; //LED ON
LedState= 1;
}
else
{
GPIOC->BSRRL = (uint16_t)GPIO_BSRR_BS_0; //LED OFF
LedState= 0;
}
}
This is the complete code. Any suggestions why the LSI don't work?
Thank you!
2014-03-25 05:42 AM
If you're doing register level access, be aware that TIM_SR only needs a write, not RMW
TIM10->SR &= ~TIM_SR_UIF;
TIM10->SR &= ~TIM_SR_CC1IF;
Should be TIM10->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
I'll rack up my code later
2014-03-25 09:35 AM
The block diagrams seems to suggest a level of functionality that the registers do not support. I can't see how to get this into ExternalMode1
2014-03-25 10:31 AM
WTF too!!
The TIM9 (Figure 140. TI2 external clock connection example) have TS bits that can configure this, but on TIM10 there are not these bits. (TIM9 can't work with LSI).2014-03-25 11:22 AM
I pushed into moderation for an explanation of the block diagram, because the multiplexor doesn't exist.
The LSI is not a crystal, it's a rough RC at 40 KHz The LSE should be able to clock the timer What are you trying to do with the LSI clock, can you do that with the RTC and changing the prescaler there?2014-04-07 01:59 AM
I want to clock a timer with low power source.
Is possible to use TIM11 and the MSI source? The multiplexor (in TIM11) exists? Any news about the bloc diagram?