- #ifndef __GENERALTIME_H
- #define __GENERALTIME_H
-
-
- #include "stm32f10x.h"
-
-
-
- // 获取捕获寄存器值函数宏定义
- #define GENERAL_TIM_GetCapturex_FUN TIM_GetCapture1
- // 捕获信号极性函数宏定义
- #define GENERAL_TIM_OCxPolarityConfig_FUN TIM_OC1PolarityConfig
-
- // 测量的起始边沿
- #define GENERAL_TIM_STRAT_ICPolarity TIM_ICPolarity_Rising
- // 测量的结束边沿
- #define GENERAL_TIM_END_ICPolarity TIM_ICPolarity_Falling
-
-
- // 定时器输入捕获用户自定义变量结构体声明
- typedef struct
- {
- uint8_t Capture_FinishFlag; // 捕获结束标志位
- uint8_t Capture_StartFlag; // 捕获开始标志位
- uint16_t Capture_CcrValue; // 捕获寄存器的值
- uint16_t Capture_Period; // 自动重装载寄存器更新标志
- }TIM_ICUserValueTypeDef;
-
- extern TIM_ICUserValueTypeDef TIM_ICUserValueStructure;
-
-
- void GENERAL_TIM_Init(void);
-
-
- #endif
-
-
-
- #include "generaltime.h"
-
- // 定时器输入捕获用户自定义变量结构体定义
- TIM_ICUserValueTypeDef TIM_ICUserValueStructure = {0,0,0,0};
-
- // 中断优先级配置
- static void GENERAL_TIM_NVIC_Config(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 设置中断组为0
- NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn ; // 设置中断来源
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;// 设置主优先级为 0
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 设置抢占优先级为3
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
-
-
- // 输入捕获通道 GPIO 初始化浮空输入
- static void GENERAL_TIM_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
-
-
-
- //配置定时器的5个结构体成员
- static void GENERAL_TIM_Mode_Config(void)
- {
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);// 开启定时器时钟,即内部时钟CK_INT=72M
-
- //时基结构体初始化
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_TimeBaseStructure.TIM_Period=0XFFFF; // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
- TIM_TimeBaseStructure.TIM_Prescaler= (72-1); // 驱动CNT计数器的时钟 = Fck_int/(psc+1)
- TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;// 时钟分频因子 ,配置死区时间时需要用到,这里没用
- TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 计数器计数模式,设置为向上计数
- TIM_TimeBaseStructure.TIM_RepetitionCounter=0;// 重复计数器的值,没用到不用管
- TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); // 初始化定时器
-
- //输入捕获结构体初始化
- TIM_ICInitTypeDef TIM_ICInitStructure;
- TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;// 配置输入捕获的通道,需要根据具体的GPIO来配置
- 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 = 0;// 输入的需要被捕获的信号的滤波系数
- TIM_ICInit(TIM5, &TIM_ICInitStructure); // 定时器输入捕获初始化
-
- TIM_ClearFlag(TIM5, TIM_FLAG_Update| TIM_IT_CC1); // 清除更新中断和捕获中断标志位
- TIM_ITConfig (TIM5, TIM_IT_Update | TIM_IT_CC1, ENABLE ); // 开启更新和捕获中断
-
- TIM_Cmd(TIM5, ENABLE);// 使能计数器
- }
-
- void GENERAL_TIM_Init(void)
- {
- GENERAL_TIM_GPIO_Config();
- GENERAL_TIM_NVIC_Config();
- GENERAL_TIM_Mode_Config();
- }
- //捕获脉冲的核心代码
- void TIM5_IRQHandler(void)
- {
- // 当要被捕获的信号的周期大于定时器的最长定时时,定时器就会溢出,产生更新中断
- // 这个时候我们需要把这个最长的定时周期加到捕获信号的时间里面去
- if ( TIM_GetITStatus (TIM5, TIM_IT_Update) != RESET )
- {
- TIM_ICUserValueStructure.Capture_Period ++;
- TIM_ClearITPendingBit(TIM5, TIM_FLAG_Update );
- }
-
- // 上升沿捕获中断
- if ( TIM_GetITStatus(TIM5,TIM_IT_CC1 ) != RESET)
- {
- // 第一次捕获
- if (TIM_ICUserValueStructure.Capture_StartFlag == 0 )
- {
- TIM_SetCounter (TIM5, 0);// 计数器清0
- TIM_ICUserValueStructure.Capture_Period = 0;// 自动重装载寄存器更新标志清0
- TIM_ICUserValueStructure.Capture_CcrValue = 0; // 存捕获比较寄存器的值的变量的值清0
- TIM_OC1PolarityConfig(TIM5, TIM_ICPolarity_Falling);// 当第一次捕获到上升沿之后,就把捕获边沿配置为下降沿
- TIM_ICUserValueStructure.Capture_StartFlag = 1; // 开始捕标志准置1
- }
- // 下降沿捕获中断
- else // 第二次捕获
- {
- // 获取捕获比较寄存器的值,这个值就是捕获到的高电平的时间的值
- TIM_ICUserValueStructure.Capture_CcrValue = TIM_GetCapture1 (TIM5);
-
- // 当第二次捕获到下降沿之后,就把捕获边沿配置为上升沿,好开启新的一轮捕获
- TIM_OC1PolarityConfig(TIM5, TIM_ICPolarity_Rising);
- TIM_ICUserValueStructure.Capture_StartFlag = 0;// 开始捕获标志清0
- TIM_ICUserValueStructure.Capture_FinishFlag = 1; // 捕获完成标志置1
- }
-
- TIM_ClearITPendingBit (TIM5,TIM_IT_CC1);
- }
- }
- #include "stm32f10x.h"
- #include "led.h"
- #include "key.h"
- #include "rcc.h"
- #include "exti.h"
- #include "systick.h"
- #include "usart.h"
- #include <stdio.h>
- #include "basetime.h"
- #include "advancetime.h"
- #include "generaltime.h"
-
- /*
- 通用定时器TIM5_CH1即PA0引脚测量脉冲,本身接wake_up按键,
- 按键按下接高电平,测量高电平脉冲时间,在串口上位机显示
-
- */
-
- int main(void)
- {
-
- uint32_t time;
- uint32_t TIM_PscCLK = 72000000 / ((72-1)+1); // TIM 计数器的驱动时钟
-
-
- USART_Config();//串口初始化
- GENERAL_TIM_Init();// 定时器初始化
-
- printf ( "\r\nSTM32 输入捕获实验\r\n" );
- printf ( "\r\n按下wake_up,测试按下的时间\r\n" );
-
- while (1){
- if(TIM_ICUserValueStructure.Capture_FinishFlag == 1)
- {
- // 计算高电平时间的计数器的值
- time = TIM_ICUserValueStructure.Capture_Period * (0XFFFF+1) +
- (TIM_ICUserValueStructure.Capture_CcrValue+1);
-
- // 打印高电平脉宽时间
- printf ( "\r\n测得高电平脉宽时间:%d.%d s\r\n",time/TIM_PscCLK,time%TIM_PscCLK );
-
- TIM_ICUserValueStructure.Capture_FinishFlag = 0;
- }
- }
- }
-
-
-
二 高级定时器捕获PWM的周期与占空比
-
- #include "generaltime3.h"
-
- /**
- * @brief 通用定时器PWM输出用到的GPIO初始化
- * @param 无
- * @retval 无
- */
- static void GENERAL_TIM_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- // 输出比较通道1 GPIO 初始化
- RCC_APB2PeriphClockCmd(GENERAL_TIM_CH1_GPIO_CLK, ENABLE);
- GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH1_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GENERAL_TIM_CH1_PORT, &GPIO_InitStructure);
-
- }
-
-
-
- static void GENERAL_TIM_Mode_Config(void)
- {
-
- GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK,ENABLE);// 开启定时器时钟,即内部时钟CK_INT=72M
-
- //时基结构体初始化 配置周期,这里配置为100K
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_PERIOD;// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
- TIM_TimeBaseStructure.TIM_Prescaler= (72-1); // 驱动CNT计数器的时钟 = Fck_int/(psc+1)
- 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); // 初始化定时器
-
- //输出比较结构体初始化
- TIM_OCInitTypeDef TIM_OCInitStructure;
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;// 配置为PWM模式1
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;// 输出使能
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;// 输出通道电平极性配置
- TIM_OCInitStructure.TIM_Pulse = 5;
- TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure);// 初始化输出比较通道 1
- TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);
-
- TIM_Cmd(GENERAL_TIM, ENABLE);// 使能计数器
- }
-
-
- void GENERAL_TIM3_Init(void)
- {
- GENERAL_TIM_GPIO_Config();
- GENERAL_TIM_Mode_Config();
- }
-
- #ifndef __ADVANCETIME1_H
- #define __ADVANCETIME1_H
-
-
- #include "stm32f10x.h"
-
-
-
-
- #define ADVANCE_TIM TIM1
- #define ADVANCE_TIM_APBxClock_FUN RCC_APB2PeriphClockCmd
- #define ADVANCE_TIM_CLK RCC_APB2Periph_TIM1
-
- // 输入捕获能捕获到的最小的频率为 72M/{ (ARR+1)*(PSC+1) }
- #define ADVANCE_TIM_PERIOD (1000-1)
- #define ADVANCE_TIM_PSC (72-1)
-
- // 中断相关宏定义
- #define ADVANCE_TIM_IRQ TIM1_CC_IRQn
- #define ADVANCE_TIM_IRQHandler TIM1_CC_IRQHandler
-
- // TIM1 输入捕获通道1
- #define ADVANCE_TIM_CH1_GPIO_CLK RCC_APB2Periph_GPIOA
- #define ADVANCE_TIM_CH1_PORT GPIOA
- #define ADVANCE_TIM_CH1_PIN GPIO_Pin_8
-
- #define ADVANCE_TIM_IC1PWM_CHANNEL TIM_Channel_1
-
-
- void ADVANCE_TIM1_Init(void);
-
-
- #endif
-
-
-
- #include "advancetime1.h"
-
-
- static void ADVANCE_TIM_NVIC_Config(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 设置中断组为0
- NVIC_InitStructure.NVIC_IRQChannel = ADVANCE_TIM_IRQ; // 设置中断来源
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 设置抢占优先级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 设置子优先级
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
-
-
- static void ADVANCE_TIM_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(ADVANCE_TIM_CH1_GPIO_CLK, ENABLE);
- GPIO_InitStructure.GPIO_Pin = ADVANCE_TIM_CH1_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(ADVANCE_TIM_CH1_PORT, &GPIO_InitStructure);
- }
-
-
-
- static void ADVANCE_TIM_Mode_Config(void)
- {
-
- ADVANCE_TIM_APBxClock_FUN(ADVANCE_TIM_CLK,ENABLE); //开启定时器时钟,即内部时钟CK_INT=72M
-
- //时基结构体初始化:用于测量频率那么你的时基就需要比信号高
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_TimeBaseStructure.TIM_Period=ADVANCE_TIM_PERIOD;// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
- TIM_TimeBaseStructure.TIM_Prescaler= ADVANCE_TIM_PSC;// 驱动CNT计数器的时钟 = Fck_int/(psc+1)
- TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;// 时钟分频因子 ,配置死区时间时需要用到
- TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 计数器计数模式,设置为向上计数
- TIM_TimeBaseStructure.TIM_RepetitionCounter=0;// 重复计数器的值,没用到不用管
- TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure); // 初始化定时器
-
- //输入捕获结构体初始化 使用PWM输入模式时,需要占用两个捕获寄存器,一个测周期,另外一个测占空比
- TIM_ICInitTypeDef TIM_ICInitStructure;
- TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;// 捕获通道IC1配置 ,选择捕获通道
- TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;// 设置捕获的边沿
- TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;// 设置捕获通道的信号来自于哪个输入通道,有直连和非直连两种
- TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;// 1分频,即捕获信号的每个有效边沿(上升沿)捕获
- TIM_ICInitStructure.TIM_ICFilter = 0x0;// 不滤波
- TIM_PWMIConfig(ADVANCE_TIM, &TIM_ICInitStructure);// 初始化PWM输入模式
-
- //直连与非直连区别仅仅是捕获寄存器1来捕获周期,2来捕获占空比。还是捕获寄存器2来捕获周期,1捕获占空比
- TIM_SelectInputTrigger(ADVANCE_TIM, TIM_TS_TI1FP1);// 选择输入捕获的触发信号:即捕获信号周期
-
- // 选择从模式: 即复位模式。 因为PWM输入模式时,从模式必须工作在复位模式,当捕获开始时,计数器CNT会被复位
- TIM_SelectSlaveMode(ADVANCE_TIM, TIM_SlaveMode_Reset);
- TIM_SelectMasterSlaveMode(ADVANCE_TIM,TIM_MasterSlaveMode_Enable);
- TIM_ITConfig(ADVANCE_TIM, TIM_IT_CC1, ENABLE);// 使能捕获中断,这个中断针对的是主捕获通道(测量周期那个)
- TIM_ClearITPendingBit(ADVANCE_TIM, TIM_IT_CC1);// 清除中断标志位
- TIM_Cmd(ADVANCE_TIM, ENABLE);// 使能高级控制定时器,计数器开始计数
- }
-
- void ADVANCE_TIM1_Init(void)
- {
- ADVANCE_TIM_GPIO_Config();
- ADVANCE_TIM_NVIC_Config();
- ADVANCE_TIM_Mode_Config();
- }
-
- __IO uint16_t IC2Value = 0;
- __IO uint16_t IC1Value = 0;
- __IO float DutyCycle = 0;
- __IO float Frequency = 0;
- void ADVANCE_TIM_IRQHandler(void)
- {
-
- TIM_ClearITPendingBit(ADVANCE_TIM, TIM_IT_CC1);/* 清除中断标志位 */
-
- /* 获取输入捕获值 */
- IC1Value = TIM_GetCapture1(ADVANCE_TIM);
- IC2Value = TIM_GetCapture2(ADVANCE_TIM);
-
- // 注意:捕获寄存器CCR1和CCR2的值在计算占空比和频率的时候必须加1
- if (IC1Value != 0)
- {
-
- DutyCycle = (float)((IC2Value+1) * 100) / (IC1Value+1);/* 占空比计算 */
- Frequency = (72000000/(ADVANCE_TIM_PSC+1))/(float)(IC1Value+1);/* 频率计算 */
- printf("占空比:%0.2f%% 频率:%0.2fHz\n",DutyCycle,Frequency);
- }
- else
- {
- DutyCycle = 0;
- Frequency = 0;
- }
- }
- #include "stm32f10x.h"
- #include "led.h"
- #include "key.h"
- #include "rcc.h"
- #include "exti.h"
- #include "systick.h"
- #include "usart.h"
- #include
- #include "basetime.h"
- #include "advancetime.h"
- #include "generaltime.h"
- #include "advancetime1.h"
- #include "generaltime3.h"
-
- /*
- 采样率不能低于信号频率,不然采集不到,
- 把通用定时器3产生100Khz占空比50的pwmPA6引脚接到高级定时器1输入捕获引脚PA8
- */
-
- int main(void)
- {
-
- USART_Config();
- GENERAL_TIM3_Init();//基本的事情配置输出100Khz占空比50信号
- ADVANCE_TIM1_Init();/* 高级定时器初始化 ,用户捕获PWM信号*/
-
- while (1){
-
- }
- }
-
-
-