2014-03-18 08:35 AM
Hello all,
I’ve been fighting for 2 days with a STM32F4-Discovery board to get the Timer 3 counting properly in External Counting Mode 2 but I can’t figure out what’s wrong in my code or in the MCU config.
I’m trying to implement a function that counts up to N top of an external signal (f≈600KHz) and toggles timer channel 3 (Channel 1 and 2 corresponding GPIO Pins are already used on evaluation board) when CNT=N (using output compare mode).
I wrote some code to test my function at low speed: The idea is to generate a “clock�? using the user button on the board to generate a clock on GPIO B1. This clock is connected to TIM3_ETR (GPIO D2). At each push on the button CNT should increase and channel 3 output (GPIO B0) should be properly toggled when the CNT equals to CCR3 value. In the main I added CNT value change capture code in order to set a breakpoint in debug mode when counter increases.
With the test code below CNT is increasing one time and remain blocked at 0x0
Does anybody see anything wrong in the code or any hardware configuration issue I could have made?
Regards
/**
******************************************************************************
* File Name : main.c
* Date : 17/03/2014 12:20:04
* Description : Main program body
******************************************************************************
*
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include ''stm32f4xx.h''
#include ''stm32f4xx_rcc.h''
#include ''stm32f4xx_tim.h''
#include ''STM32F4-Discovery/stm32f4_discovery.h''
/* USER CODE BEGIN 0 */
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void PeriphClock_EN(void);
static void GPIO_Config(void);
static void TIM3_Init(void);
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
STM_EVAL_PBInit(BUTTON_USER,BUTTON_MODE_GPIO);
/* Enable peripheral clocks */
PeriphClock_EN();
/* Initialize all configured peripherals */
GPIO_Config();
/* Initialize Timers */
TIM3_Init();
/* USER CODE END 1 */
/* USER CODE BEGIN 2 */
int i=0;
uint32_t cnt = 0;
/* USER CODE END 2 */
/* USER CODE BEGIN 3 */
/* Infinite loop */
while (1)
{
//Toggling GPIO and LED3 when phushing button
if(STM_EVAL_PBGetState(BUTTON_USER)){
STM_EVAL_LEDToggle(LED3);
GPIO_ToggleBits(GPIOB,GPIO_Pin_1);
//Avoiding multiple toggle for one push
for (i=0;i<
500000
;i++);
}
//Counter Increase Capture to set debug breakpoint
if(cnt != TIM_GetCounter(TIM3)){
cnt
=
TIM_GetCounter
(TIM3);
}
}
}
void PeriphClock_EN(void){
// Enable TIM3 Clocks
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
//Enabling Port B Clocks
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
//Enabling Port D Clocks
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
}
void GPIO_Config(void){
/**TIM3 GPIO Configuration**************************
PB0 ------> TIM3_CH3
PD2 ------> TIM3_ETR
*/
//PB0 ------> TIM3_CH3
GPIO_InitTypeDef gpioStructure;
gpioStructure.GPIO_Pin = GPIO_Pin_0;
gpioStructure.GPIO_Mode = GPIO_Mode_AF;
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz;
gpioStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpioStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3);
//PD2 GPIO Configuration as Input For Test
/* gpioStructure.GPIO_Pin = GPIO_Pin_2;
gpioStructure.GPIO_Mode = GPIO_Mode_IN;
gpioStructure.GPIO_Speed = GPIO_Speed_2MHz;
gpioStructure.GPIO_OType = GPIO_OType_PP;
gpioStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOD, &gpioStructure);*/
//PD2 ------> TIM3_ETR
gpioStructure.GPIO_Pin = GPIO_Pin_2;
gpioStructure.GPIO_Mode = GPIO_Mode_AF;
gpioStructure.GPIO_Speed = GPIO_Speed_2MHz;
gpioStructure.GPIO_OType = GPIO_OType_PP;
gpioStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOD, &gpioStructure);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_TIM3);
//Setting PB1 in output Mode
gpioStructure.GPIO_Pin = GPIO_Pin_1;
gpioStructure.GPIO_Mode = GPIO_Mode_OUT;
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz;
gpioStructure.GPIO_OType = GPIO_OType_PP;
gpioStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOB, &gpioStructure);
}
void TIM3_Init(void){
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* Enable the TIM3 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TIM3 configuration */
TIM_TimeBaseStructure.TIM_Period = 3; // 133
TIM_TimeBaseStructure.TIM_Prescaler = 100;
TIM_TimeBaseStructure.TIM_ClockDivision = 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0000;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// External Trigger set to External Clock, Mode 2
TIM_ETRClockMode2Config (TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);
TIM_OCStructInit(&TIM_OCInitStructure);
/* Output Compare Timing Mode configuration: Channel 3 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; // Active
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_Pulse = 2;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Disable);
TIM_UpdateDisableConfig(TIM3,ENABLE);
/* Clear TIM2 update pending flag */
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
/* Enable TIM2 Capture Compare 3 interrupt */
TIM_ITConfig(TIM3, TIM_IT_CC3, DISABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM3, ENABLE);
}
// TIM3 callback handler
void TIM3_IRQHandler()
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
int i=0;
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
// toggle bit
STM_EVAL_LEDToggle(LED4);
for (i=0;i<1000000;i++);
}
}
#stm32f4 #discovery #timers
2014-03-18 09:00 AM
Large prescaler, and line numbers aren't helping you here.
2014-03-18 10:25 AM
Thank you clive1, indeed with no prescaler and no clock division it seems to work as expected.
Anyway I'm not be sure of understanding what was the problem induced by the prescaler. Regards2014-03-18 12:05 PM
You'd need 101 external clock pulses to advance the counter. If you really want to 404 pulses, the set the Prescaler to zero, and Period to 403