234 lines
7.1 KiB
C
234 lines
7.1 KiB
C
/**
|
||
******************************************************************************
|
||
* @file bsp_basic_tim.c
|
||
* @author STMicroelectronics
|
||
* @version V1.0
|
||
* @date 2015-xx-xx
|
||
* @brief 基本定时器定时范例
|
||
******************************************************************************
|
||
* @attention
|
||
*
|
||
* 实验平台:野火 STM32 H750 开发板
|
||
* 论坛 :http://www.firebbs.cn
|
||
* 淘宝 :https://fire-stm32.taobao.com
|
||
*
|
||
******************************************************************************
|
||
*/
|
||
|
||
#include "./tim/bsp_advance_tim.h"
|
||
#include "./led/bsp_led.h"
|
||
|
||
TIM_HandleTypeDef TIM_PWMOUTNPUT_Handle;
|
||
TIM_HandleTypeDef TIM_PWMINPUT_Handle;
|
||
|
||
|
||
|
||
__IO uint16_t ChannelPulse = 5000;
|
||
|
||
__IO uint16_t IC2Value = 0;
|
||
__IO uint16_t IC1Value = 0;
|
||
__IO float DutyCycle = 0;
|
||
__IO float Frequency = 0;
|
||
/**
|
||
* @brief 高级定时器 TIMx,x=[1,8]通道引脚初始化
|
||
* @param 无
|
||
* @retval 无
|
||
*/
|
||
static void TIMx_GPIO_Configuration(void)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStruct;
|
||
//使能高级定时器的引脚时钟
|
||
ADVANCE_TIM_CHx_CLK();
|
||
//使能通用定时器的引脚时钟
|
||
GENERAL_TIM_CHx_CLK();
|
||
|
||
|
||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH ;
|
||
|
||
GPIO_InitStruct.Pin = GENERAL_TIM_CHx_PIN;
|
||
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
|
||
HAL_GPIO_Init(GENERAL_TIM_CHx_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = ADVANCE_TIM_CHx_PIN;
|
||
GPIO_InitStruct.Alternate = GPIO_AF3_TIM8;
|
||
HAL_GPIO_Init(ADVANCE_TIM_CHx_PORT, &GPIO_InitStruct);
|
||
}
|
||
|
||
/*
|
||
* 注意: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]才有(高级定时器)
|
||
*-----------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* @brief 通用定时器TIMx初始化函数
|
||
* @param 无
|
||
* @retval 无
|
||
*/
|
||
static void TIMx_Output_Configuration(void)
|
||
{
|
||
TIM_OC_InitTypeDef sConfig;
|
||
//使能TIMx的时钟
|
||
GENERAL_TIM_CLK_ENABLE();
|
||
//TIMx的外设寄存器基地址
|
||
TIM_PWMOUTNPUT_Handle.Instance = GENERAL_TIM;
|
||
//计数模式为向上计数,递增
|
||
TIM_PWMOUTNPUT_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||
/* 累计 TIM_Period个后产生一个更新或者中断*/
|
||
//当定时器从0计数到9999,即为10000次,为一个定时周期
|
||
TIM_PWMOUTNPUT_Handle.Init.Period = 10000 - 1;
|
||
//时钟不分频,即一个TIM_CLK时钟计1次
|
||
TIM_PWMOUTNPUT_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||
//定时器时钟源TIMxCLK = 2 * PCLK1
|
||
// PCLK1 = HCLK / 4
|
||
// => TIMxCLK=HCLK/2=SystemCoreClock/2=200MHz
|
||
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=1000000Hz
|
||
TIM_PWMOUTNPUT_Handle.Init.Prescaler = 200 - 1;
|
||
// 初始化定时器TIM
|
||
HAL_TIM_PWM_Init(&TIM_PWMOUTNPUT_Handle);
|
||
|
||
/* 配置TIM为互补输出模式 */
|
||
//互补输出,PWM1模式
|
||
//计数值CNT小于比较值CCR(sConfig.Pulse),通道x为有效电平
|
||
//计数值CNT大于比较值CCR(sConfig.Pulse),通道x为无效电平
|
||
sConfig.OCMode = TIM_OCMODE_PWM1;
|
||
//CHx的有效电平为高电平
|
||
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||
//CHx在空闲状态下为低电平
|
||
sConfig.OCIdleState = TIM_OCNIDLESTATE_RESET;
|
||
//CHxN在空闲状态下为高电平(必须与CHx相反)
|
||
sConfig.OCNIdleState = TIM_OCIDLESTATE_SET;
|
||
//CHxN的有效电平为高电平
|
||
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
|
||
//比较器CCR的值
|
||
sConfig.Pulse = ChannelPulse;
|
||
//初始化输出比较通道
|
||
HAL_TIM_OC_ConfigChannel(&TIM_PWMOUTNPUT_Handle, &sConfig, GENERAL_TIM_CH);
|
||
|
||
//主动输出CHx使能
|
||
HAL_TIM_OC_Start(&TIM_PWMOUTNPUT_Handle, GENERAL_TIM_CH);
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief 通用定时器TIMx初始化函数
|
||
* @param 无
|
||
* @retval 无
|
||
*/
|
||
static void TIMx_Input_Configuration(void)
|
||
{
|
||
|
||
TIM_IC_InitTypeDef TIM_IC_Config;
|
||
TIM_SlaveConfigTypeDef TIM_SlaveConfig;
|
||
|
||
//使能TIMx的时钟
|
||
ADVANCE_TIM_CLK_ENABLE();
|
||
//TIMx的外设寄存器基地址
|
||
TIM_PWMINPUT_Handle.Instance = ADVANCE_TIM;
|
||
//计数模式为向上计数,递增
|
||
TIM_PWMINPUT_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||
/* 累计 TIM_Period个后产生一个更新或者中断*/
|
||
//当定时器从0计数到9999,即为10000次,为一个定时周期
|
||
TIM_PWMINPUT_Handle.Init.Period = 10000;
|
||
//时钟不分频,即一个TIM_CLK时钟计1次
|
||
TIM_PWMINPUT_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||
//定时器时钟源TIMxCLK = 2 * PCLK1
|
||
// PCLK1 = HCLK / 4
|
||
// => TIMxCLK=HCLK/2=SystemCoreClock/2=200MHz
|
||
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100Hz
|
||
TIM_PWMINPUT_Handle.Init.Prescaler = 200 - 1;
|
||
// 初始化定时器TIM
|
||
HAL_TIM_PWM_Init(&TIM_PWMINPUT_Handle);
|
||
|
||
/* IC1捕获:上升沿触发TI1FP1 */
|
||
TIM_IC_Config.ICPolarity = TIM_ICPOLARITY_RISING;
|
||
TIM_IC_Config.ICFilter = 0;
|
||
TIM_IC_Config.ICPrescaler = TIM_ICPSC_DIV1;
|
||
TIM_IC_Config.ICSelection = TIM_ICSELECTION_DIRECTTI;
|
||
HAL_TIM_IC_ConfigChannel(&TIM_PWMINPUT_Handle, &TIM_IC_Config, ADVANCE_TIM_IC_CH1);
|
||
/* IC2捕获:上升沿触发TI1FP2 */
|
||
TIM_IC_Config.ICPolarity = TIM_ICPOLARITY_FALLING;
|
||
TIM_IC_Config.ICFilter = 0;
|
||
TIM_IC_Config.ICPrescaler = TIM_ICPSC_DIV1;
|
||
TIM_IC_Config.ICSelection = TIM_ICSELECTION_INDIRECTTI;
|
||
HAL_TIM_IC_ConfigChannel(&TIM_PWMINPUT_Handle, &TIM_IC_Config, ADVANCE_TIM_IC_CH2);
|
||
/* 选择从模式: 复位模式 */
|
||
TIM_SlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
|
||
/* 选择定时器输入触发: TI1FP1 */
|
||
TIM_SlaveConfig.InputTrigger = TIM_TS_TI1FP1;
|
||
HAL_TIM_SlaveConfigSynchronization(&TIM_PWMINPUT_Handle,&TIM_SlaveConfig);
|
||
|
||
HAL_TIM_IC_Start_IT(&TIM_PWMINPUT_Handle,ADVANCE_TIM_IC_CH1);
|
||
HAL_TIM_IC_Start_IT(&TIM_PWMINPUT_Handle,ADVANCE_TIM_IC_CH2);
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief TIM中断优先级配置函数
|
||
* @param 无
|
||
* @retval 无
|
||
*/
|
||
static void ADVANCE_TIM_NVIC_Config(void)
|
||
{
|
||
HAL_NVIC_SetPriority(ADVANCE_TIM_IRQ, 0, 0);
|
||
HAL_NVIC_EnableIRQ(ADVANCE_TIM_IRQ);
|
||
}
|
||
/**
|
||
* @brief 初始化基本定时器定时,1ms产生一次中断
|
||
* @param 无
|
||
* @retval 无
|
||
*/
|
||
void TIM_Advance_Init(void)
|
||
{
|
||
//TIM通道引脚初始化
|
||
TIMx_GPIO_Configuration();
|
||
//高级定时器中断配置
|
||
ADVANCE_TIM_NVIC_Config();
|
||
//通用TIM外设初始化
|
||
TIMx_Output_Configuration();
|
||
//高级TIM外设初始化
|
||
TIMx_Input_Configuration();
|
||
}
|
||
|
||
/**
|
||
* @brief 输入捕获完成中断回调函数
|
||
* @param TIM_Handle : ADC句柄
|
||
* @retval 无
|
||
*/
|
||
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
|
||
{
|
||
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
|
||
{
|
||
/* 获取输入捕获值 */
|
||
IC1Value = HAL_TIM_ReadCapturedValue(&TIM_PWMINPUT_Handle,TIM_CHANNEL_1);
|
||
IC2Value = HAL_TIM_ReadCapturedValue(&TIM_PWMINPUT_Handle,TIM_CHANNEL_2);
|
||
if (IC1Value != 0)
|
||
{
|
||
/* 占空比计算 */
|
||
DutyCycle = (float)((IC2Value+1) * 100) / (IC1Value+1);
|
||
|
||
/* 频率计算 */
|
||
Frequency = 200000000/200/(float)(IC1Value+1);
|
||
|
||
}
|
||
else
|
||
{
|
||
DutyCycle = 0;
|
||
Frequency = 0;
|
||
}
|
||
|
||
}
|
||
}
|
||
/*********************************************END OF FILE**********************/
|
||
|