学前班
最后登录1970-1-1
在线时间 小时
注册时间2019-10-22
|
开了5定时器,5个中断捕获PWM信号时,第3,4信号出错,有没有大神看下哪里有问题!!!
附上代码:
/*
* model_airplane.c
*
* Created on: 2019年10月23日
* Author: mjjol
*/
#include "model_airplane.h"
#include "model_airplane_def.h"
#include "Utility.h"
#include "stm32f4xx_tim.h"
#include "model_airplane_irq.h"
//PA8有干扰,不建议使用, TIM2用于PWM输出,PC9不能用
const PwmInConfigPro PwmInCfg[ModelAirPlaneKeyNum] =
{
//高级定时器 Elevator
{GPIO_Pin_5, GPIOI, RCC_AHB1Periph_GPIOI, GPIO_PinSource5, GPIO_AF_TIM8, TIM_Channel_1,
TIM8, RCC_APB2Periph_TIM8, TIM8_CC_IRQn, High_Tim},
//通用定时器 Aileron
{GPIO_Pin_6, GPIOA, RCC_AHB1Periph_GPIOA, GPIO_PinSource6, GPIO_AF_TIM3, TIM_Channel_1,
TIM3, RCC_APB1Periph_TIM3, TIM3_IRQn, Normarl_Tim},
//高级定时器 Throttle
{GPIO_Pin_0, GPIOA, RCC_AHB1Periph_GPIOA, GPIO_PinSource0, GPIO_AF_TIM5, TIM_Channel_1,
TIM5, RCC_APB1Periph_TIM5, TIM5_IRQn, Normarl_Tim},
//高级定时器 Rudder
{GPIO_Pin_6, GPIOB, RCC_AHB1Periph_GPIOB, GPIO_PinSource6, GPIO_AF_TIM4, TIM_Channel_1,
TIM4, RCC_APB1Periph_TIM4, TIM4_IRQn, Normarl_Tim},
//高级定时器 Gear
{GPIO_Pin_8, GPIOA, RCC_AHB1Periph_GPIOA, GPIO_PinSource8, GPIO_AF_TIM1, TIM_Channel_1,
TIM1, RCC_APB2Periph_TIM1, TIM1_CC_IRQn, High_Tim},
};
/**
* @brief 配置TIM复用输出PWM时用到的I/O
* @param 无
* @retval 无
*/
static void TIMx_GPIO_Config(uint32_t RCC_AHB1Periph, GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF, uint32_t GPIO_Pin)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/*开启LED相关的GPIO外设时钟*/
RCC_AHB1PeriphClockCmd (RCC_AHB1Periph, ENABLE);
/* 定时器复用引脚 */
GPIO_PinAFConfig(GPIOx, GPIO_PinSource, GPIO_AF);
/* 通用定时器PWM输出引脚 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOx, &GPIO_InitStructure);
}
/**
* @brief 高级控制定时器 TIMx,x[1,8]中断优先级配置
* @param 无
* @retval 无
*/
static void TIMx_NVIC_Configuration(uint8_t NVIC_IRQChannel)
{
NVIC_InitTypeDef NVIC_InitStructure;
// 设置中断组为0
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// 设置中断来源
NVIC_InitStructure.NVIC_IRQChannel = NVIC_IRQChannel;
// 设置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// 设置子优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*
* 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
* TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
* 另外三个成员是通用定时器和高级定时器才有.
*-----------------------------------------------------------------------------
* TIM_Prescaler 都有
* TIM_CounterMode TIMx,x[6,7]没有,其他都有(基本定时器)
* TIM_Period 都有
* TIM_ClockDivision TIMx,x[6,7]没有,其他都有(基本定时器)
* TIM_RepetitionCounter TIMx,x[1,8]才有(高级定时器)
*-----------------------------------------------------------------------------
*/
static void TIM_PWMOUTPUT_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// 开启TIMx_CLK,x[2,3,4,5,12,13,14]
RCC_APB1PeriphClockCmd(GENERAL_TIM_CLK, ENABLE);
/* 累计 TIM_Period个后产生一个更新或者中断*/
//当定时器从0计数到9999,即为10000次,为一个定时周期
TIM_TimeBaseStructure.TIM_Period = 10000-1;
// 通用定时器2时钟源TIMxCLK = HCLK/2=90MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
TIM_TimeBaseStructure.TIM_Prescaler = 900-1;
// 采样时钟分频
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数方式
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 初始化定时器TIMx, x[1,8]
TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure);
/* PWM输出模式配置 */
/* 配置为PWM模式1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
/* PWM脉冲宽度 */
TIM_OCInitStructure.TIM_Pulse = 3000-1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* 使能通道1 */
TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure);
/*使能通道1重载*/
TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);
// 使能定时器
TIM_Cmd(GENERAL_TIM, ENABLE);
}
static void TimPwmInputConfig(uint32_t tim_clk, TIM_TypeDef* TIMx, uint16_t tim_channel, TimProperty tim_property)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
// 开启TIMx_CLK,x[1,8]
// RCC_APB2PeriphClockCmd(tim_clk, ENABLE);
// 高级控制定时器时钟源TIMxCLK = HCLK=180MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
if (tim_property == High_Tim)
{
RCC_APB2PeriphClockCmd(tim_clk, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF-1;
TIM_TimeBaseStructure.TIM_Prescaler = 1800-1;
}
else if (tim_property == Normarl_Tim)
{
RCC_APB1PeriphClockCmd(tim_clk, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 10000-1;
TIM_TimeBaseStructure.TIM_Prescaler = 900-1;
}
else if (tim_property == Normarl_APB2_Tim)
{
RCC_APB2PeriphClockCmd(tim_clk, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 10000-1;
TIM_TimeBaseStructure.TIM_Prescaler = 900-1;
}
// 计数方式
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 初始化定时器TIMx, x[1,8]
TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);
/* IC1捕获:上升沿触发 TI1FP1 */
TIM_ICInitStructure.TIM_Channel = tim_channel;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(TIMx, &TIM_ICInitStructure);
// /* IC2捕获:下降沿触发 TI1FP2 */
// TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
// TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
// TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;
// TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
// TIM_ICInitStructure.TIM_ICFilter = 0x0;
// TIM_PWMIConfig(TIMx, &TIM_ICInitStructure);
/* 选择定时器输入触发: TI1FP1 */
TIM_SelectInputTrigger(TIMx, TIM_TS_TI1FP1);
/* 选择从模式: 复位模式 */
TIM_SelectSlaveMode(TIMx, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIMx,TIM_MasterSlaveMode_Enable);
/* 使能高级控制定时器 */
TIM_Cmd(TIMx, ENABLE);
/* 使能捕获/比较2中断请求 */
TIM_ITConfig(TIMx, TIM_IT_CC1, ENABLE);
TIM_ClearITPendingBit(TIMx, TIM_IT_CC1);
}
void ModelAirPlaneInit(void)
{
uint8_t i;
ModelAirPlaneIrqInit();
//PWM输出
TIMx_GPIO_Config(GENERAL_OCPWM_GPIO_CLK, GENERAL_OCPWM_GPIO_PORT, GENERAL_OCPWM_PINSOURCE, GENERAL_OCPWM_AF, GENERAL_OCPWM_PIN);
TIM_PWMOUTPUT_Config();
//PWM输入
for (i = 0; i < ModelAirPlaneKeyNum; i++)
{
TIMx_GPIO_Config(PwmInCfg.GPIO_CLK, PwmInCfg.GPIOx, PwmInCfg.GPIO_PinSource, PwmInCfg.GPIO_AF, PwmInCfg.GPIO_Pin);
TIMx_NVIC_Configuration(PwmInCfg.NVIC_IRQChannel);
TimPwmInputConfig(PwmInCfg.tim_clk, PwmInCfg.TIMx, PwmInCfg.tim_channel, PwmInCfg.tim_property);
}
}
/*
* model_airplane.h
*
* Created on: 2019年10月23日
* Author: mjjol
*/
#ifndef USER_MIDDLE_MODEL_AIRPLANE_MODEL_AIRPLANE_H_
#define USER_MIDDLE_MODEL_AIRPLANE_MODEL_AIRPLANE_H_
#include "stm32f4xx.h"
typedef enum
{
Normarl_Tim = 0,
High_Tim,
Normarl_APB2_Tim,
} TimProperty;
typedef struct
{
uint32_t GPIO_Pin;
GPIO_TypeDef* GPIOx;
uint32_t GPIO_CLK;
uint16_t GPIO_PinSource;
uint8_t GPIO_AF;
uint16_t tim_channel;
TIM_TypeDef* TIMx;
uint32_t tim_clk;
uint8_t NVIC_IRQChannel;
TimProperty tim_property;
} PwmInConfigPro;
extern const PwmInConfigPro PwmInCfg[];
extern void ModelAirPlaneInit(void);
#endif /* USER_MIDDLE_MODEL_AIRPLANE_MODEL_AIRPLANE_H_ */
/*
* model_airplane_def.h
*
* Created on: 2019年10月23日
* Author: mjjol
*/
#ifndef USER_MIDDLE_MODEL_AIRPLANE_MODEL_AIRPLANE_DEF_H_
#define USER_MIDDLE_MODEL_AIRPLANE_MODEL_AIRPLANE_DEF_H_
#define INVALID_IC_VALUE 0xFFFF
/* 通用定时器PWM输出 */
/* PWM输出引脚 */
#define GENERAL_OCPWM_PIN GPIO_Pin_5
#define GENERAL_OCPWM_GPIO_PORT GPIOA
#define GENERAL_OCPWM_GPIO_CLK RCC_AHB1Periph_GPIOA
#define GENERAL_OCPWM_PINSOURCE GPIO_PinSource5
#define GENERAL_OCPWM_AF GPIO_AF_TIM2
/* 通用定时器 */
#define GENERAL_TIM TIM2
#define GENERAL_TIM_CLK RCC_APB1Periph_TIM2
/************************************IRQ****************************************/
/*
* 此处中断需与
*/
#define ElevatorServo_IRQHandler TIM8_CC_IRQHandler //ElevatorServo
#define AileronServo_IRQHandler TIM3_IRQHandler //AileronServo
#define ThrottleServo_IRQHandler TIM5_IRQHandler //ThrottleServo
#define RudderServo_IRQHandler TIM4_IRQHandler //RudderServo
#define GearServo_IRQHandler TIM1_CC_IRQHandler //GearServo
/*******************************************************************************/
typedef enum
{
ElevatorServo = 0,
AileronServo,
ThrottleServo,
RudderServo,
GearServo,
ModelAirPlaneKeyNum,
} ModelAirPlaneKey;
#endif /* USER_MIDDLE_MODEL_AIRPLANE_MODEL_AIRPLANE_DEF_H_ */
/*
* model_airplane_irq.c
*
* Created on: 2019年10月23日
* Author: mjjol
*/
#include "stm32f4xx_it.h"
#include "model_airplane_def.h"
#include "model_airplane.h"
#include "model_airplane_irq.h"
PwmICValue PwmIn[ModelAirPlaneKeyNum];
PwmICValue ElevatorServoPwmIn, AileronServoPwmIn;
float DutyCycle = 0, Frequency = 0;
uint8_t IrqLock = 0;
/**
* @brief This function handles TIM interrupt request.
* @param None
* @retval None
*/
void ElevatorServo_IRQHandler (void)
{
uint8_t elevatorServo_index = ElevatorServo;
/* 清除定时器捕获/比较1中断 */
// TIM_ClearITPendingBit(PwmInCfg[elevatorServo_index].TIMx, TIM_IT_CC1);
PwmInCfg[elevatorServo_index].TIMx->SR = (uint16_t)~TIM_IT_CC1;
PwmIn[elevatorServo_index].ic1_value = PwmInCfg[elevatorServo_index].TIMx->CCR1;
PwmIn[elevatorServo_index].ic2_value = PwmInCfg[elevatorServo_index].TIMx->CCR2;
//
// /* 获取输入捕获值 */
// PwmIn[elevatorServo_index].ic1_value = TIM_GetCapture1(PwmInCfg[elevatorServo_index].TIMx);
// PwmIn[elevatorServo_index].ic2_value = TIM_GetCapture2(PwmInCfg[elevatorServo_index].TIMx);
printf("ElevatorServo: IC1Value = %d IC2Value = %d ",PwmIn[elevatorServo_index].ic1_value,PwmIn[elevatorServo_index].ic2_value);
//
// if (PwmIn[elevatorServo_index].ic1_value != 0)
// {
// /* 占空比计算 */
// PwmIn[elevatorServo_index].duty_clcye = (float)(PwmIn[elevatorServo_index].ic2_value * 100) / PwmIn[elevatorServo_index].ic1_value;
//
// /* 频率计算 */
// PwmIn[elevatorServo_index].frequency = 180000000/1800/(float)PwmIn[elevatorServo_index].ic1_value;
// printf("ElevatorServo: 占空比:%0.2f%% 频率:%0.2fHz\r\n",PwmIn[elevatorServo_index].duty_clcye,PwmIn[elevatorServo_index].frequency);
// }
// else
// {
// PwmIn[elevatorServo_index].duty_clcye = 0;
// PwmIn[elevatorServo_index].frequency = 0;
// }
}
uint16_t tt_c1, tt_c2;
/**
* @brief This function handles TIM interrupt request.
* @param None
* @retval None
*/
void AileronServo_IRQHandler (void)
{
uint8_t aileronServo_index = AileronServo;
/* 清除定时器捕获/比较1中断 */
// TIM_ClearITPendingBit(PwmInCfg[aileronServo_index].TIMx, TIM_IT_CC1);
PwmInCfg[aileronServo_index].TIMx->SR = (uint16_t)~TIM_IT_CC1;
PwmIn[aileronServo_index].ic1_value = PwmInCfg[aileronServo_index].TIMx->CCR1;
PwmIn[aileronServo_index].ic2_value = PwmInCfg[aileronServo_index].TIMx->CCR2;
//
// /* 获取输入捕获值 */
// PwmIn[aileronServo_index].ic1_value = TIM_GetCapture1(PwmInCfg[aileronServo_index].TIMx);
// PwmIn[aileronServo_index].ic2_value = TIM_GetCapture2(PwmInCfg[aileronServo_index].TIMx);
printf("AileronServo: IC1Value = %d IC2Value = %d ",PwmIn[aileronServo_index].ic1_value,PwmIn[aileronServo_index].ic2_value);
//
// if (PwmIn[aileronServo_index].ic1_value != 0)
// {
// /* 占空比计算 */
// PwmIn[aileronServo_index].duty_clcye = (float)(PwmIn[aileronServo_index].ic2_value * 100) / PwmIn[aileronServo_index].ic1_value;
//
// /* 频率计算 */
// PwmIn[aileronServo_index].frequency = 180000000/1800/(float)PwmIn[aileronServo_index].ic1_value;
// printf("AileronServo: 占空比:%0.2f%% 频率:%0.2fHz\r\n",PwmIn[aileronServo_index].duty_clcye,PwmIn[aileronServo_index].frequency);
// }
// else
// {
// PwmIn[aileronServo_index].duty_clcye = 0;
// PwmIn[aileronServo_index].frequency = 0;
// }
}
/**
* @brief This function handles TIM interrupt request.
* @param None
* @retval None
*/
void ThrottleServo_IRQHandler (void)
{
uint8_t ThrottleServo_index = ThrottleServo;
/* 清除定时器捕获/比较1中断 */
// TIM_ClearITPendingBit(PwmInCfg[ThrottleServo_index].TIMx, TIM_IT_CC1);
PwmInCfg[ThrottleServo_index].TIMx->SR = (uint16_t)~TIM_IT_CC1;
PwmIn[ThrottleServo_index].ic1_value = PwmInCfg[ThrottleServo_index].TIMx->CCR1;
PwmIn[ThrottleServo_index].ic2_value = PwmInCfg[ThrottleServo_index].TIMx->CCR2;
//
// /* 获取输入捕获值 */
// PwmIn[ThrottleServo_index].ic1_value = TIM_GetCapture1(PwmInCfg[ThrottleServo_index].TIMx);
// PwmIn[ThrottleServo_index].ic2_value = TIM_GetCapture2(PwmInCfg[ThrottleServo_index].TIMx);
printf("ThrottleServo: IC1Value = %d IC2Value = %d ",PwmIn[ThrottleServo_index].ic1_value,PwmIn[ThrottleServo_index].ic2_value);
//
// if (PwmIn[ThrottleServo_index].ic1_value != 0)
// {
// /* 占空比计算 */
// PwmIn[ThrottleServo_index].duty_clcye = (float)(PwmIn[ThrottleServo_index].ic2_value * 100) / PwmIn[ThrottleServo_index].ic1_value;
//
// /* 频率计算 */
// PwmIn[ThrottleServo_index].frequency = 180000000/1800/(float)PwmIn[ThrottleServo_index].ic1_value;
// printf("ThrottleServo: 占空比:%0.2f%% 频率:%0.2fHz\r\n",PwmIn[ThrottleServo_index].duty_clcye,PwmIn[ThrottleServo_index].frequency);
// }
// else
// {
// PwmIn[ThrottleServo_index].duty_clcye = 0;
// PwmIn[ThrottleServo_index].frequency = 0;
// }
}
/**
* @brief This function handles TIM interrupt request.
* @param None
* @retval None
*/
void RudderServo_IRQHandler (void)
{
uint8_t RudderServo_index = RudderServo;
/* 清除定时器捕获/比较1中断 */
// TIM_ClearITPendingBit(PwmInCfg[RudderServo_index].TIMx, TIM_IT_CC1);
PwmInCfg[RudderServo_index].TIMx->SR = (uint16_t)~TIM_IT_CC1;
PwmIn[RudderServo_index].ic1_value = PwmInCfg[RudderServo_index].TIMx->CCR1;
PwmIn[RudderServo_index].ic2_value = PwmInCfg[RudderServo_index].TIMx->CCR2;
// /* 获取输入捕获值 */
// PwmIn[RudderServo_index].ic1_value = TIM_GetCapture1(PwmInCfg[RudderServo_index].TIMx);
// PwmIn[RudderServo_index].ic2_value = TIM_GetCapture2(PwmInCfg[RudderServo_index].TIMx);
printf("RudderServo: IC1Value = %d IC2Value = %d ",PwmIn[RudderServo_index].ic1_value,PwmIn[RudderServo_index].ic2_value);
//
// if (PwmIn[RudderServo_index].ic1_value != 0)
// {
// /* 占空比计算 */
// PwmIn[RudderServo_index].duty_clcye = (float)(PwmIn[RudderServo_index].ic2_value * 100) / PwmIn[RudderServo_index].ic1_value;
//
// /* 频率计算 */
// PwmIn[RudderServo_index].frequency = 180000000/1800/(float)PwmIn[RudderServo_index].ic1_value;
// printf("RudderServo: 占空比:%0.2f%% 频率:%0.2fHz\r\n",PwmIn[RudderServo_index].duty_clcye,PwmIn[RudderServo_index].frequency);
// }
// else
// {
// PwmIn[RudderServo_index].duty_clcye = 0;
// PwmIn[RudderServo_index].frequency = 0;
// }
}
/**
* @brief This function handles TIM interrupt request.
* @param None
* @retval None
*/
void GearServo_IRQHandler (void)
{
uint8_t GearServo_index = GearServo;
/* 清除定时器捕获/比较1中断 */
// TIM_ClearITPendingBit(PwmInCfg[GearServo_index].TIMx, TIM_IT_CC1);
PwmInCfg[GearServo_index].TIMx->SR = (uint16_t)~TIM_IT_CC1;
PwmIn[GearServo_index].ic1_value = PwmInCfg[GearServo_index].TIMx->CCR1;
PwmIn[GearServo_index].ic2_value = PwmInCfg[GearServo_index].TIMx->CCR2;
/* 获取输入捕获值 */
// PwmIn[GearServo_index].ic1_value = TIM_GetCapture1(PwmInCfg[GearServo_index].TIMx);
// PwmIn[GearServo_index].ic2_value = TIM_GetCapture2(PwmInCfg[GearServo_index].TIMx);
printf("GearServo: IC1Value = %d IC2Value = %d ",PwmIn[GearServo_index].ic1_value,PwmIn[GearServo_index].ic2_value);
//
// if (PwmIn[GearServo_index].ic1_value != 0)
// {
// /* 占空比计算 */
// PwmIn[GearServo_index].duty_clcye = (float)(PwmIn[GearServo_index].ic2_value * 100) / PwmIn[GearServo_index].ic1_value;
//
// /* 频率计算 */
// PwmIn[GearServo_index].frequency = 180000000/1800/(float)PwmIn[GearServo_index].ic1_value;
// printf("GearServo: 占空比:%0.2f%% 频率:%0.2fHz\r\n",PwmIn[GearServo_index].duty_clcye,PwmIn[GearServo_index].frequency);
// }
// else
// {
// PwmIn[GearServo_index].duty_clcye = 0;
// PwmIn[GearServo_index].frequency = 0;
// }
}
void ModelAirPlaneIrqInit(void)
{
uint8_t i;
for (i = 0; i < ModelAirPlaneKeyNum; i++)
{
PwmIn.ic1_value = INVALID_IC_VALUE;
PwmIn.ic2_value = INVALID_IC_VALUE;
}
}
|
|