/*GeneralTim.c 文件*/
#include "GeneralTim.h"
#include <stdio.h>
// 用户自定义变量结构体
TIM_ICUserValueTypeDef TIM_ICUserValueStructure = {0,0,0,0};
//TIM 计数器的驱动定时
uint32_t TIM_PscCLK = 72000000 / (GENERAL_TIM_PSC+1);
//
static void GENERAL_TIM_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// 设置中断组为0
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
// 设置中断源
NVIC_InitStructure.NVIC_IRQChannel = GENERAL_TIM_IRQ;
// 设置主优先级 0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// 设置抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
static void GENERAL_TIM_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 输入捕获通道 GPIO 初始化
RCC_APB2PeriphClockCmd(GENERAL_TIM_CH1_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GENERAL_TIM_CH1_PORT, &GPIO_InitStructure);
}
///*
// * 注意TIM_TimeBaseInitTypeDef结构体里又5个成员,TIM6和TIM7的寄存器里只有
// * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需要初始化这两个成员即可
// * 另外三个成员是通用定时器和高级定时器才有
// *-----------------------------------------------------------------------------
// *typedef struct
// *{ TIM_Prescaler 都有
// * TIM_CounterMode TIMx,x[6,7]没有,其他都有
// * TIM_Period 都有
// * TIM_ClockDivision TIMx,x[6,7]没有,其他都有
// * TIM_RepetitionCounter TIMx,x[1,8,15,16,17]才有
// *}TIM_TimeBaseInitTypeDef;
// *-----------------------------------------------------------------------------
// */
/* ---------------- PWM信号 周期和占空比的计算--------------- */
// ARR 自动重装载寄存器的值
// CLK_cnt:计数器的时钟,等于 Fck_int / (psc+1) = 72M/(psc+1)
// PWM 信号的周期 T = ARR * (1/CLK_cnt) = ARR*(PSC+1) / 72M
// 占空比P=CCR/(ARR+1)
static void GENERAL_TIM_Mode_Config(void)
{
//时基结构初始化
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//输入捕获结构初始化
TIM_ICInitTypeDef TIM_ICInitStructure;
/*--------------------时基结构初始化-------------------------*/
//开启定时器时钟,及内部时钟CK_INT=72M
GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK,ENABLE);
//自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或中断
TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_PERIOD;
// 驱动CNT计数器的时钟 = Fck_int/(psc+1)
TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_PSC;
//时钟分频因子,配置死区时间时需要用到
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数器计数模式,设置为向上计数
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
//重复计数器的值,没用到不用管
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
// 初始化定时器
TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure);
/*--------------------输入捕获结构体初始化-------------------*/
// 配置输入捕获通道,需要根据具体的GPIO来配置
TIM_ICInitStructure.TIM_Channel = GENERAL_TIM_CHANNEL_x;
// 输入捕获信号的极性
TIM_ICInitStructure.TIM_ICPolarity = GENERAL_TIM_STRAT_ICPolarity; //上升沿捕获
//TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //下降沿捕获
// 输入通道和捕获通道的映射关系,有直连和非直连关系
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
// 输入的需要被捕获的信号的分频系数
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
// 输入的需要被捕获的信号的滤波系数
TIM_ICInitStructure.TIM_ICFilter = 0;
// 定时器输入捕获初始化
TIM_ICInit(GENERAL_TIM, &TIM_ICInitStructure);
// 清楚和更新中断标志位
TIM_ClearFlag(GENERAL_TIM, TIM_FLAG_Update|GENERAL_TIM_IT_CCx);
// 开启更新和捕获中断
TIM_ITConfig (GENERAL_TIM, TIM_IT_Update | GENERAL_TIM_IT_CCx, ENABLE );
// 使能计数器
TIM_Cmd(GENERAL_TIM, ENABLE);
}
void pulse_width() //计算高电平的持续时间
{
uint32_t time=0;
if(TIM_ICUserValueStructure.Capture_FinishFlag == 1) //捕获标志位置1,捕获开始
{
// 计算高电平时间的计数器的值
time = TIM_ICUserValueStructure.Capture_Period * (GENERAL_TIM_PERIOD+1) +
(TIM_ICUserValueStructure.Capture_CcrValue+1);
printf("\检测高电平脉宽时间 US\r\n",time%TIM_PscCLK );
TIM_ICUserValueStructure.Capture_FinishFlag = 0; //捕获结束,标志位清零
}
SysTick_Delay_Us(500); //500微妙采样一次 这里的延时函数我就不贴出来(自己写一个粗略延时即可)
}
void GENERAL_TIM_Init(void)
{
GENERAL_TIM_GPIO_Config();
GENERAL_TIM_NVIC_Config();
GENERAL_TIM_Mode_Config();
}
/*********************************************END OF FILE**********************/
/*main 函数*/
#include "stm32f10x.h"
#include "GeneralTim.h"
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main(void)
{
/* 定时器初始化 */
GENERAL_TIM_Init();
while( 1 )
{
pulse_width(); //脉冲宽度
}
}