STM32H7用hal库编程,使用定时器的编码器模式采集光栅尺的信号,一运行程序中断会有异常,没有计数就会进入更新中断,还会连续进入两次
.c文件
#include "bsp_encoder.h"
__IO int16_t Encoder_Overflow_Count = 0;
TIM_HandleTypeDef TIM_EncoderHandle;
static void Encoder_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
ENCODER_TIM_CH1_GPIO_CLK_ENABLE();
ENCODER_TIM_CH2_GPIO_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
//GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = ENCODER_TIM_CH1_PIN;
GPIO_InitStruct.Alternate = ENCODER_TIM_CH1_GPIO_AF;
HAL_GPIO_Init(ENCODER_TIM_CH1_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Pin = ENCODER_TIM_CH2_PIN;
GPIO_InitStruct.Alternate = ENCODER_TIM_CH2_GPIO_AF;
HAL_GPIO_Init(ENCODER_TIM_CH2_GPIO_PORT, &GPIO_InitStruct);
}
static void TIM_Encoder_Init(void)
{
TIM_Encoder_InitTypeDef Encoder_ConfigStructure;
ENCODER_TIM_CLK_ENABLE();
TIM_EncoderHandle.Instance = ENCODER_TIM;
TIM_EncoderHandle.Init.Prescaler = ENCODER_TIM_PRESCALER;
TIM_EncoderHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
TIM_EncoderHandle.Init.Period = ENCODER_TIM_PERIOD;
TIM_EncoderHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
TIM_EncoderHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
Encoder_ConfigStructure.EncoderMode = ENCODER_MODE;
Encoder_ConfigStructure.IC1Polarity = ENCODER_IC1_POLARITY;
Encoder_ConfigStructure.IC1Selection = TIM_ICSELECTION_DIRECTTI;
Encoder_ConfigStructure.IC1Prescaler = TIM_ICPSC_DIV1;
Encoder_ConfigStructure.IC1Filter = 0;
Encoder_ConfigStructure.IC2Polarity = ENCODER_IC2_POLARITY;
Encoder_ConfigStructure.IC2Selection = TIM_ICSELECTION_DIRECTTI;
Encoder_ConfigStructure.IC2Prescaler = TIM_ICPSC_DIV1;
Encoder_ConfigStructure.IC2Filter = 0;
HAL_TIM_Encoder_Init(&TIM_EncoderHandle, &Encoder_ConfigStructure);
__HAL_TIM_SET_COUNTER(&TIM_EncoderHandle, 0);
__HAL_TIM_CLEAR_IT(&TIM_EncoderHandle,TIM_IT_UPDATE);
__HAL_TIM_ENABLE_IT(&TIM_EncoderHandle,TIM_IT_UPDATE);
__HAL_TIM_URS_ENABLE(&TIM_EncoderHandle);
HAL_NVIC_SetPriority(ENCODER_TIM_IRQn, 5, 1);
HAL_NVIC_EnableIRQ(ENCODER_TIM_IRQn);
HAL_TIM_Encoder_Start(&TIM_EncoderHandle, TIM_CHANNEL_ALL);
}
void Encoder_Init(void)
{
Encoder_GPIO_Init();
TIM_Encoder_Init();
}
void TIM4_IRQHandler(void)
{
if(__HAL_TIM_IS_TIM_COUNTING_DOWN(&TIM_EncoderHandle))
Encoder_Overflow_Count-=1;
else
Encoder_Overflow_Count+=1;
__HAL_TIM_CLEAR_IT(&TIM_EncoderHandle,TIM_IT_UPDATE);
}
#ifndef __BSP_ENCOEDER_H
#define __BSP_ENCOEDER_H
#include "stm32h7xx.h"
#define ENCODER_TIM TIM4
#define ENCODER_TIM_CLK_ENABLE() __HAL_RCC_TIM4_CLK_ENABLE()
#define ENCODER_TIM_PERIOD 65535
#define ENCODER_TIM_PRESCALER 0
#define ENCODER_TIM_IRQn TIM4_IRQn
#define ENCODER_TIM_IRQHandler TIM4_IRQHandler
#define ENCODER_TIM_CH1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define ENCODER_TIM_CH1_GPIO_PORT GPIOD
#define ENCODER_TIM_CH1_PIN GPIO_PIN_12
#define ENCODER_TIM_CH1_GPIO_AF GPIO_AF2_TIM4
#define ENCODER_TIM_CH2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define ENCODER_TIM_CH2_GPIO_PORT GPIOD
#define ENCODER_TIM_CH2_PIN GPIO_PIN_13
#define ENCODER_TIM_CH2_GPIO_AF GPIO_AF2_TIM4
#define ENCODER_MODE TIM_ENCODERMODE_TI12
#define ENCODER_IC1_POLARITY TIM_ICPOLARITY_FALLING
#define ENCODER_IC2_POLARITY TIM_ICPOLARITY_RISING
#define ENCODER_RESOLUTION 5000
#if ((ENCODER_MODE == TIM_ENCODERMODE_TI1) || (ENCODER_MODE == TIM_ENCODERMODE_TI2))
#define ENCODER_TOTAL_RESOLUTION (ENCODER_RESOLUTION * 2)
#else
#define ENCODER_TOTAL_RESOLUTION (ENCODER_RESOLUTION * 4)
#endif
extern __IO int16_t Encoder_Overflow_Count;
extern TIM_HandleTypeDef TIM_EncoderHandle;
void Encoder_Init(void);
#endif __BSP_ENCODER_H
调试的时候将断点放在中断void TIM4_IRQHandler(void)函数内部会直接进入,但是定时器的CNT没有变化,没有计数,一步一步调试会不断进入中断,Encoder_Overflow_Count有变化,去掉断点后,Encoder_Overflow_Count变化一会后就停止了
中断函数改成了现在的,以前是在HAL_TIM_PeriodElapsedCallback(),内部写的,一样的现象。
改过IO的初始化和编码器模式的初始化,不知道是不是初始化的问题,目前没能解决。
怎么能计数到一定值才进入更新中断呢,不想一开始不断进入中断。
报的错内容是什么啊
编译后没有报错,程序一启动就会不断进入编码器模式相应的定时器的更新中断,然后里边的程序就会运行,记录溢出次数的变量就会变化,导致在中断服务函数里什么都干不了