2012-05-14 08:40 AM
hi,
i am working on the stm32discovery i am trying to increment a timer (timer2 channel 1) each time the signal on the pin PA.05 is rising but the timer is random incrementing and not at each rising edge of the signal i don't understand why ? here is my code : int main(void) { /* Configure Clocks for Application need */ RCC_Configuration(); /* Configure RTC Clocks */ //RTC_Configuration(); /* Configure SysTick IRQ and SysTick Timer to generate interrupts every 500µs */ RCC_GetClocksFreq(&RCC_Clocks); //SysTick_Config(RCC_Clocks.HCLK_Frequency / 2000); /* Enable GPIOs clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE); /*PA.05 TIM2 channel 1*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_TIM2); TIM_InitStruct.TIM_Period = 849; TIM_InitStruct.TIM_Prescaler = 0; TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2,&TIM_InitStruct); /*timer2 chanel 1 ETR pin PA5*/ TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStruct.TIM_ICFilter = 0x0; TIM_ICInit(TIM2, &TIM_ICInitStruct); /*enable the TIM counter*/ TIM_Cmd(TIM2, ENABLE); TIM_TIxExternalClockConfig(TIM2, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 0); TIM_ETRClockMode1Config(TIM2,TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted,0); while (1){ SysTick_Config(RCC_Clocks.HCLK_Frequency / 2000); bitStatut = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5); increment = TIM_GetCapture1(TIM2); Delay(100); } could you help me ? thanks2012-05-14 10:36 AM
I'd start by taking the SysTick_Config(RCC_Clocks.HCLK_Frequency / 2000); out of the loop, what's that supposed to do?
2012-05-14 10:46 AM
unfortunatelly that doesn't change a thing the timer is still incrementing random and not only on the rising edge maybe it is a initialisation missing ?
2012-05-14 12:30 PM
But what was the purpose of having that within the loop, I'm trying to understand why.
What is the nature of the input signal, please describe the frequency/period and duty cycle? If you are pushing a button, you might see contact bounce. Do you have any interrupt code servicing the SysTick? How long is Delay(100) ?2012-05-14 02:54 PM
Here's how I'd demonstrate this on an STM32 VL-Discovery with the Keil Evaluation, and serial cable attached to USART1. I don't have an STM32 L-Discovery board to hand, YMMV.
Counts clocks on TIM1_ETR from a clock source running at 1 Hz, in this case generated on TIM4_CH1 and looped back externally. It counts off seconds, wrapping at 3600 (1 Hour), shows also the delta between the last counter measurement if the printf eats too many cycles.// sourcer32@gmail.com - STM32 VLDiscovery 1HZ External clock demo
#include <
stdio.h
>
#include ''stm32F10x.h''
#include ''STM32vldiscovery.h''
/**************************************************************************************/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void TIM4_Configuration(void);
void TIM2_Configuration(void);
void USART_Configuration(void);
/**************************************************************************************/
int main(void)
{
uint16_t LastTick, CurrentTick;
RCC_Configuration();
USART_Configuration(); // For DEBUG
GPIO_Configuration();
TIM4_Configuration(); // 1Hz Output
TIM2_Configuration(); // Count input clock
// Pin PB.06 (TIM4_CH1) looped back to PA.00 (TIM2_ETR) externally
// Print a tick everytime the counter changes
LastTick = TIM_GetCounter(TIM2) - 1;
while(1)
{
CurrentTick = TIM_GetCounter(TIM2);
if (CurrentTick != LastTick)
{
printf(''Tick:%5u Delta:%5u
'', CurrentTick, (uint16_t)(CurrentTick - LastTick));
LastTick = CurrentTick;
}
}
}
/**************************************************************************************/
void RCC_Configuration(void)
{
// clock for GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// clock for TIM2 & TIM4
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM4, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// PB.06 TIM4_CH1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// PA.00 TIM2_ETR
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/**************************************************************************************/
void TIM4_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// Set up TIM4_CH1 to be a 1 Hz time base (1PPS)
TIM_TimeBaseStructure.TIM_Prescaler = 24000 - 1; // 24 MHz / 24000 = 1 KHz
TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 1 KHz / 1000 = 1 Hz
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
// Channel 1 configuration = PB.06 TIM4_CH1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (TIM_TimeBaseStructure.TIM_Period + 1) / 2; // 50% Duty
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
// turning on TIM4 and PWM outputs
TIM_Cmd(TIM4, ENABLE);
TIM_CtrlPWMOutputs(TIM4, ENABLE);
}
/**************************************************************************************/
void TIM2_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_Period = 3600 - 1; // 1 Hour in seconds
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// PA.00 TIM2_ETR
TIM_ETRClockMode1Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);
// TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_External1);
TIM_Cmd(TIM2, ENABLE);
}
/**************************************************************************************/
void USART_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA.09 USART1.TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA.10 USART1.RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* USART resources configuration (Clock, GPIO pins and USART registers) ----*/
/* USART configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Enable UART clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* USART configuration */
USART_Init(USART1, &USART_InitStructure);
/* Enable the USART1 */
USART_Cmd(USART1, ENABLE);
}
/**************************************************************************************/
#include <
rt_misc.h
>
#pragma import(__use_no_semihosting_swi)
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
int sendchar(char c)
{
while((USART1->SR & 0x80)==0); // 80 = TXE, 40 = TC
USART1->DR = c;
return(1);
}
int getkey(void)
{
while((USART1->SR & 0x20)==0); // 20 = RXNE
return(USART1->DR);
}
int fputc(int ch, FILE *f)
{
if ((char)ch == '
')
sendchar('
');
return (sendchar((char)ch));
}
int fgetc(FILE *f) {
return (getkey());
}
int ferror(FILE *f) {
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch)
{
if ((char)ch == '
')
sendchar('
');
sendchar((char)ch);
}
void _sys_exit(int return_code) {
label: goto label; /* endless loop */
}
/**************************************************************************************/
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d
'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/**************************************************************************************/
2012-05-14 11:29 PM
i am sending a square wave on the pin PA.05 and i simply want to increment it of 1 at each rising edge starting from 0
i put the delay of 100ms because the clock int the loop was too fast to be abble to detect my square wave2012-05-14 11:30 PM
the signal is a simply square wave of frequency 100Hz and a duty cycle of 50%
2012-05-15 01:36 AM
it is working in low frequency
thanks for the help2013-02-25 03:45 AM
I have almost the same problem:
I have a flowmeter that makes pulses that I want to count. The frequency is variable between 0 and 20kHz. During design I can control the flow. The board is a keil MBCSTM32 Board. To test the example on this thread I have connected my flow-signal both to ETR (PD2) and to TI1 (remaped to PC6). When I try to read the input bitwise through the GPIO i get the signal but doing the same through the timer, TIM3_GetValue(TIM3) returns 0. I have the feeling it is easy to solve but I am truly stuck. #include ''lcd.h'' #include ''stm32f10x_tim.h'' #include ''stm32f10x_gpio.h'' void hw_init();int main(void)
{ hw_init(); long count = 1; unsigned char last_bit = 0; long l_sum = 0; uint32_t l; while(1) { /* // l=GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6); // Testing pin input l=GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_2); // if(l!=last_bit && l==1) { l_sum++; } last_bit = l; */ if(!count --) { count = 1000000; l=TIM_GetCounter(TIM3); lcd_set_position(1,5); // lcd_write_int(l_sum); // Works lcd_write_int(l); } } } void hw_init() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD ,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); lcd_init(LCD_4_BIT_BUS,LCD_FONT_5x11); // Uses PC0-4 and PC10-12 // --- Timer3 --- // PC6 & PD2 are both connected to the same input signal from flowmeter GPIO_StructInit(&gpio_struct); gpio_struct.GPIO_Pin = GPIO_Pin_6 ; gpio_struct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init( GPIOC, &gpio_struct); GPIO_StructInit(&gpio_struct); gpio_struct.GPIO_Pin = GPIO_Pin_2 ; gpio_struct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init( GPIOD, &gpio_struct); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct); #ifdef USE_TRIGGER_INPUT_1 GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE); TIM_ETRClockMode2Config(TIM3,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0); TIM_ICInitTypeDef TIM_ICInitStruct; TIM_ICStructInit(&TIM_ICInitStruct); TIM_ICInit(TIM3,&TIM_ICInitStruct); TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 0); TIM_CCxCmd(TIM3,TIM_Channel_1,TIM_CCx_Enable); #else // USE_TRIGGER_INPUT_1 TIM_ETRClockMode1Config(TIM3,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0); #endif // TIM_ETRClockMode1Config(TIM3,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0); // TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_External1); TIM_Cmd(TIM3, ENABLE); }2013-02-25 09:13 AM
Counting button (B1) presses on the VL-Discovery, uses TIM2 CH1 PA0
void TIM2_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PA2 TIM2_CH1 BUTTON 1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_TIxExternalClockConfig(TIM2, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 0);
TIM_Cmd(TIM2, ENABLE);
}