2020-07-08 11:56 AM
2020-07-08 12:13 PM
// STM32F429I-DISCO TIM3 (CH1 PA6) External Count Demo - sourcer32@gmail.com
#include "stm32f429i_discovery.h"
//****************************************************************************
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* pin configuration */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); // PA6 TIM3_CH1
}
//****************************************************************************
void TIM3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
int i;
/* Enable TIM3 Peripheral clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_Period = 100 - 1; // 100 (16-bit counter)
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 0);
TIM_Cmd(TIM3, ENABLE);
// Likely will interrupt initially unless we clear it
for(i=0; i<3; i++)
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
// Could also use compare mode, set the counter maximal and advance CCRx 100 ticks at a time
}
//****************************************************************************
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
/* Toggle LED3 */
STM_EVAL_LEDToggle(LED3);
}
}
//****************************************************************************
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM3 global 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);
}
//****************************************************************************
int main(void)
{
/* Initialize Leds mounted on STM32F429I-DISCO board */
STM_EVAL_LEDInit(LED3);
/* Turn on LED3 */
STM_EVAL_LEDOn(LED3);
NVIC_Configuration();
GPIO_Configuration();
TIM3_Configuration();
while(1); // Do not exit
}
//******************************************************************************
#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\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
//******************************************************************************
2020-07-08 12:09 PM
You should look at the corresponding Nucleo board examples, for timer and say input capture or external clock mode whichever closer to your needs.
2020-07-08 12:13 PM
// STM32F429I-DISCO TIM3 (CH1 PA6) External Count Demo - sourcer32@gmail.com
#include "stm32f429i_discovery.h"
//****************************************************************************
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* pin configuration */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); // PA6 TIM3_CH1
}
//****************************************************************************
void TIM3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
int i;
/* Enable TIM3 Peripheral clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_Period = 100 - 1; // 100 (16-bit counter)
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 0);
TIM_Cmd(TIM3, ENABLE);
// Likely will interrupt initially unless we clear it
for(i=0; i<3; i++)
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
// Could also use compare mode, set the counter maximal and advance CCRx 100 ticks at a time
}
//****************************************************************************
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
/* Toggle LED3 */
STM_EVAL_LEDToggle(LED3);
}
}
//****************************************************************************
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM3 global 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);
}
//****************************************************************************
int main(void)
{
/* Initialize Leds mounted on STM32F429I-DISCO board */
STM_EVAL_LEDInit(LED3);
/* Turn on LED3 */
STM_EVAL_LEDOn(LED3);
NVIC_Configuration();
GPIO_Configuration();
TIM3_Configuration();
while(1); // Do not exit
}
//******************************************************************************
#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\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
//******************************************************************************
2020-07-20 02:21 AM
thanks for yor reply
2020-09-08 08:57 AM
I thanks for your reply, but I'm using the HAL library on system workbench (I don't know which is the reference library of your example)
2020-09-08 01:43 PM
My take. No library.
// https://community.st.com/s/question/0D53W00000COHcsSAH/is-there-a-sample-code-showing-how-to-count-external-events-on-a-stm32f429i-discovery-using-timer-3-thanks-piero
// wek at efton dot sk
#include "stm32f4xx.h"
// 'F429 DISCO
// GREEN_LED PG13
// RED_LED PG14
#define GREEN_LED_PORT GPIOG
#define GREEN_LED_PIN 13
#define RED_LED_PORT GPIOG
#define RED_LED_PIN 14
// ------- defines missing from the device header -- normally I have the complete collection in a separate header, this is just to keep things in one file
// GPIOx_MODER - 2 bits per pin
#define GPIO_Mode_In 0x00 // GPIO Input Mode
#define GPIO_Mode_Out 0x01 // GPIO Output Mode
#define GPIO_Mode_AlternateFunction 0x02 // GPIO Alternate function Mode
#define GPIO_Mode_AF GPIO_Mode_AlternateFunction
#define GPIO_Mode_Analog 0x03 // GPIO Analog Mode
#define GPIO_PullNone 0x00
#define GPIO_PullUp 0x01
#define GPIO_PullDown 0x02
#define GPIO_AlternateFunction_TIM3 2
#define SHL <<
#define AND &
#define PIN_SET(pin) pin##_PORT->BSRR = (1 SHL (pin##_PIN + 0))
#define PIN_CLR(pin) pin##_PORT->BSRR = (1 SHL (pin##_PIN + 16))
#define PIN_GET(pin) ((pin##_PORT->IDR AND (1 SHL pin##_PIN)) ? 1 : 0)
#define TIM_CCMR_CCS__INPUT_TI1 1 // CC unit in capture mode, input from "own" pin (i.e. TI1 for CC1, TI2 for CC2, TI3 for CC3, TI4 for CC4)
#define TIM_SMCR_TS__TI1FP1 5 // TI1FP1 with the same polarity as if CH1 used for capturing in CC1
#define TIM_SMCR_SMS__EXT_CLK_1 7
#define TIM_CCMR_ICF__32_8S 15 // input filter - 8 samples, sampled by fDTS/32
// -------- utils/frameworks
// trivial loopdelay
static void LoopDelay(volatile uint32_t n) {
while(n > 0) n--;
}
#define DELAY_CONSTANT 1000000
// ---------------------------- MAIN ------------------------------
int main(void) {
RCC->AHB1ENR |= 0
| RCC_AHB1ENR_GPIOAEN // let's enable all GPIOs, we are going to use them all anyway, and don't plan to spare power significantly, so what
| RCC_AHB1ENR_GPIOBEN
| RCC_AHB1ENR_GPIOCEN
| RCC_AHB1ENR_GPIODEN
| RCC_AHB1ENR_GPIOEEN
| RCC_AHB1ENR_GPIOFEN
| RCC_AHB1ENR_GPIOGEN
| RCC_AHB1ENR_GPIOHEN
;
RCC->APB1ENR |= 0
| RCC_APB1ENR_TIM3EN
;
GPIOA->MODER = (GPIOA->MODER // assuming reset value
) | (0
| (GPIO_Mode_AF * GPIO_MODER_MODER6_0) // PA6 - TIM3_CH1
);
GPIOA->AFR[0] = 0 // AFRL
| (GPIO_AlternateFunction_TIM3 * GPIO_AFRL_AFRL6_0) // PA6 - TIM3_CH1
;
GPIOA->PUPDR = GPIOA->PUPDR
| (GPIO_PullUp * GPIO_PUPDR_PUPDR6_0) // pulled up, so can wiggle it by pulling it to GND
;
// PA6 is input so no need for OSPEEDR setting
GPIOG->MODER = (GPIOG->MODER
) | (0
| (GPIO_Mode_Out * GPIO_MODER_MODER13_0) // GREEN_LED
| (GPIO_Mode_Out * GPIO_MODER_MODER14_0) // RED_LED
);
// LEDs don't need to change OSPEEDR nor any other GPIO register
// now setup TIM3 for the external counter
// leave PSC and ARR at their defaults
TIM3->CCMR1 = 0
| (TIM_CCMR_CCS__INPUT_TI1 * TIM_CCMR1_CC1S_0) // input capture from "its own" pin
| (TIM_CCMR_ICF__32_8S * TIM_CCMR1_IC1F_0) // set the heaviest filtering here, as we are going to wiggle the pin using a loose wire
;
TIM3->CCER = 0
| (1 * TIM_CCER_CC1E) // enable TIM1_CH1
;
TIM3->SMCR = 0
| (TIM_SMCR_TS__TI1FP1 * TIM_SMCR_TS_0) // select TI1FP1 (filtered CH1) as TRGI source
| (TIM_SMCR_SMS__EXT_CLK_1 * TIM_SMCR_SMS_0) // and set external clock mode for slave controller
;
TIM3->CR1 = 0
| (1 * TIM_CR1_CEN) // enable counter
;
// for the laughs, enable interrupt from the capture
TIM3->DIER = 0
| (1 * TIM_DIER_CC1IE) // enable interrupt from CC1
;
NVIC_EnableIRQ(TIM3_IRQn);
while(1) {
PIN_SET(RED_LED);
LoopDelay(DELAY_CONSTANT);
PIN_CLR(RED_LED);
LoopDelay(DELAY_CONSTANT);
__asm("nop");
}
}
// interrupt handler
void TIM3_IRQHandler(void) {
uint32_t sr;
sr = TIM3->SR;
TIM3->SR = ~sr; // clear flags
if (sr & TIM_SR_CC1IF) {
if (PIN_GET(GREEN_LED)) {
PIN_CLR(GREEN_LED);
} else {
PIN_SET(GREEN_LED);
}
}
}
JW