当前位置:网站首页>Stm32cubemx learning (5) input capture experiment
Stm32cubemx learning (5) input capture experiment
2022-06-25 08:08:00 【Xiaohui_ Super】
Personal learning record
List of articles
One 、 New project
Two 、 Choose chip model
The development board I use is a punctual atom STM32F103ZET6 Core board
3、 ... and 、 Configure clock
The development board is welded with an external crystal oscillator , So I RCC(Reset and Cock Control) Configuration selected Crystal/Ceramic Resonator( Quartz / Ceramic resonator ), When the configuration is complete , Dexter Pinout view The relevant pins in the are marked green .
After the external high-speed clock configuration is completed , Get into Clock Configuration Options , According to the actual situation , Configure the system clock to 72 MHz, The configuration steps are as follows , Finally press enter , The software will automatically adjust the frequency division and frequency doubling parameters .
Four 、 Configure debug mode
ST-Link Namely Serial Wire Debug mode , Be sure to set !!!
I used to use M0 Chip , There is no problem if this mode is not configured , But now this model , If you don't configure Serial Wire Pattern , Once the program is passed ST-Link Burn into the chip , Chips can no longer be ST-Link Identified .( Later I passed STMISP Tool burning program / After erasing, it will return to normal )
5、 ... and 、 Timer ( Input capture ) Parameter configuration
I will TIM2 The passage of 1 Capture the test channel as input ,STM32CubeMX The default configuration will be PA0 Captured as input IO mouth (PA0 It has the multiplexing function , And no re image is required , So automatically PA0 Set to TIM_CH1 Of GPIO), The parameter setting of the timer is shown in the figure below ( The configuration of input capture may not be changed , Default capture rising edge ):
The frequency division coefficient is 72-1, It means 72 frequency division (0 Express 1 frequency division ,1 Express 2 frequency division , And so on ),TIM2 The clock frequency of is 72 MHz( The following figure ,APB1 Timer clocks The clock frequency of is 72MHz,TIM2 Mounted on APB1 On ). Make it 72 After frequency division , Frequency becomes 1MHz, Count per second 1000000 Time . The cycle is set to 1000-1( One less here , Should be Because the minimum count value is 0), Represents a complete timing period of 1000 Times count , Combined with timer counting frequency , The time required for a timer to overflow is 1ms.【 The frequency determines the capture period of the input capture , The timing value is set to 1000 Just for the convenience of calculation 】
Input to capture the interrupt that needs to start the timer , Interrupts are required for both timing overflow and input capture .
6、 ... and 、 Generate Keil engineering
Set up IDE and Project catalogue and name :
Store the code of each peripheral in a different .c /.h In file , Easy to manage ( Otherwise, they will be put in main.c in ).
Here is the generation Keil The project is about TIM2( Input capture ) Initialized code :
/* TIM2 init function */
void MX_TIM2_Init(void)
{
/* USER CODE BEGIN TIM2_Init 0 */
/* USER CODE END TIM2_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {
0};
TIM_MasterConfigTypeDef sMasterConfig = {
0};
TIM_IC_InitTypeDef sConfigIC = {
0};
/* USER CODE BEGIN TIM2_Init 1 */
/* USER CODE END TIM2_Init 1 */
htim2.Instance = TIM2;
htim2.Init.Prescaler = 72 - 1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 1000 - 1;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &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(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM2_Init 2 */
/* USER CODE END TIM2_Init 2 */
}
7、 ... and 、 Where is the interrupt function written
When using the standard library , We write interrupt handling in the bottom interrupt handling function , Such as EXTI0_IRQHandler()
, but Hal The library adds a callback function , Will interrupt some necessary operations at the bottom “ hide ” Get up ( Such as clearing the interrupt ).
The order in which interrupts are called is ( With EXTI0 For example ):EXTI0_IRQHandler()
—> HAL_GPIO_EXTI_IRQHandler()
—> HAL_GPIO_EXTI_Callback()
.
TIM2 The interrupt service function of is already in stm32f1xx_it.c
In the definition of (STM32CubeMX Automatically generated )
/** * @brief This function handles TIM2 global interrupt. */
void TIM2_IRQHandler(void)
{
/* USER CODE BEGIN TIM2_IRQn 0 */
/* USER CODE END TIM2_IRQn 0 */
HAL_TIM_IRQHandler(&htim2);
/* USER CODE BEGIN TIM2_IRQn 1 */
/* USER CODE END TIM2_IRQn 1 */
}
HAL_TIM_IRQHandler()
yes HAL The timer of the library is always interrupted , There's a lot of code inside , It's not shown here , All we need to know is —— When TIM2 Count value overflows or other events occur ( Such as capture of rising / Falling edge signal ) when , The system will execute a series of interrupt callback functions , This includes what we will use Count overflow callback function HAL_TIM_PeriodElapsedCallback()
and Input capture callback function HAL_TIM_IC_CaptureCallback()
.
8、 ... and 、 Test examples
The serial port is used in the experiment , Not mentioned in the above configuration , For serial port configuration, please refer to STM32CubeMx Study (2)USART Serial port experiment
The core of my experimental code is the interrupt callback function :
// Timer count overflow interrupt processing callback function
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(IC_DONE_FLAG == 0) // Incomplete capture
{
if(IC_START_FLAG == 1) // High level has been captured
{
IC_TIMES++; // Capture times plus one
}
}
}
// Timer input capture interrupt processing callback function
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)// Execute when capture interrupt occurs
{
if(IC_DONE_FLAG == 0) // Incomplete capture
{
if(IC_START_FLAG == 1) // It turned out to be high level , Now capture a falling edge
{
IC_VALUE = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); // Get capture value
TIM_RESET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1); // First clear the original settings
TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);// Configured for rising edge capture
IC_START_FLAG = 0; // Flag reset
IC_DONE_FLAG = 1; // Complete a high level acquisition
}
else // Capture has not yet started , Capture the rising edge for the first time
{
IC_TIMES = 0; // The capture times are cleared
IC_VALUE = 0; // The capture value is cleared
IC_START_FLAG = 1; // Set the flag that captures the top edge
TIM_RESET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1); // First clear the original settings
TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);// Configured for falling edge capture
}
__HAL_TIM_SET_COUNTER(htim,0); // The timer count value is cleared
}
}
complete main.c
/* USER CODE BEGIN Header */
/** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2022 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include <stdio.h>
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint32_t IC_TIMES; // Capture times , Company 1ms
uint8_t IC_START_FLAG; // Capture start flag ,1: High level captured ;0: High level has not been captured yet
uint8_t IC_DONE_FLAG; // Capture completion flag ,1: A high level acquisition has been completed
uint16_t IC_VALUE; // Enter the capture value of the capture
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/** * @brief The application entry point. * @retval int */
int main(void)
{
/* USER CODE BEGIN 1 */
uint32_t time = 0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1); // Turn on TIM2 Capture channel for 1
__HAL_TIM_ENABLE_IT(&htim2,TIM_IT_UPDATE); // Enable update interrupt
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_Delay(10);
if(IC_DONE_FLAG == 1) // If a high level acquisition is completed
{
IC_DONE_FLAG = 0; // Sign clear
time = IC_TIMES * 1000; // The pulse time is the number of acquisition * 1000us
time += IC_VALUE; // Plus capture time ( Less than 1ms Part of )
printf("High level: %d us\n", time);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/** * @brief System Clock Configuration * @retval None */
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {
0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {
0};
/** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
// Timer count overflow interrupt processing callback function
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(IC_DONE_FLAG == 0) // Incomplete capture
{
if(IC_START_FLAG == 1) // High level has been captured
{
IC_TIMES++; // Capture times plus one
}
}
}
// Timer input capture interrupt processing callback function
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)// Execute when capture interrupt occurs
{
if(IC_DONE_FLAG == 0) // Incomplete capture
{
if(IC_START_FLAG == 1) // It turned out to be high level , Now capture a falling edge
{
IC_VALUE = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); // Get capture value
TIM_RESET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1); // First clear the original settings
TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);// Configured for rising edge capture
IC_START_FLAG = 0; // Flag reset
IC_DONE_FLAG = 1; // Complete a high level acquisition
}
else // Capture has not yet started , Capture the rising edge for the first time
{
IC_TIMES = 0; // The capture times are cleared
IC_VALUE = 0; // The capture value is cleared
IC_START_FLAG = 1; // Set the flag that captures the top edge
TIM_RESET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1); // First clear the original settings
TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);// Configured for falling edge capture
}
__HAL_TIM_SET_COUNTER(htim,0); // The timer count value is cleared
}
}
/* USER CODE END 4 */
/** * @brief This function is executed in case of error occurrence. * @retval None */
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#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 CODE BEGIN 6 */
/* 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) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
Experimental results :
PA0 It corresponds to a key on my development board , When touched ( Not pressed ) When this key is pressed , The serial port will keep printing some useless high-level duration , The duration of these useless pulses is very close to , All are 10ms about , It indicates that the duration of the jitter level of the key is about 10ms.
When you press and hold the key , Let go again , It will print the time when the key is pressed , For example, the data in the two red circles in the following figure , The first high level duration is 4.35s, The duration of the second high level is 1.59s.
边栏推荐
猜你喜欢
共话云原生数据库的未来
Allgero reports an error: program has encoded a problem and must exit The design will be saved as a . SAV file
Application of can optical transceiver of ring network redundant can/ optical fiber converter in fire alarm system
TCP 加速小记
电子学:第011课——实验 10:晶体管开关
Can transparent cloud gateway caniot and candtu record can messages and send and receive can data remotely
什么是SKU和SPU,SKU,SPU的区别是什么
STM32CubeMX 学习(5)输入捕获实验
剑指offer刷题(中等等级)
Apache CouchDB 代码执行漏洞(CVE-2022-24706 )批量POC
随机推荐
Not afraid of losing a hundred battles, but afraid of losing heart
C examples of using colordialog to change text color and fontdialog to change text font
【补题】2021牛客暑期多校训练营4-n
自制坡道,可是真的很香
Is it safe to open an account through the haircut account opening link now?
深度学习系列48:DeepFaker
Ffmpeg+sdl2 for audio playback
Static web server
洛谷P5994 [PA2014]Kuglarz(异或思维+MST)
Analysis of kinsing dual platform mining family virus
Electronics: Lesson 012 - Experiment 11: light and sound
协议和服务的区别?
Matlab code format one click beautification artifact
Dietary intervention reduces cancer treatment-related symptoms and toxicity
Atlas conflict Remote Code Execution Vulnerability (cve-2022-26134 vulnerability analysis and protection
洛谷P2048 [NOI2010] 超级钢琴(RMQ+优先队列)
飞机引气系统的建模与故障仿真
Apache CouchDB 代码执行漏洞(CVE-2022-24706 )批量POC
c#ColorDialog更改文本颜色和FontDialog更改文本字体的使用示例
PHP array function Encyclopedia