my_capture.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#ifndef __MY_CAPTURE_H
#define __MY_CAPTURE_H
#include "stm32f10x.h"
#define GENERAL_CAPTURE_TIM TIM5
#define GENERAL_CAPTURE_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd
#define GENERAL_CAPTURE_TIM_CLK RCC_APB1Periph_TIM5
#define GENERAL_CAPTURE_TIM_PERIOD 0XFFFF
#define GENERAL_CAPTURE_TIM_PSC (72-1)
// TIM 输入捕获通道GPIO相关宏定义
#define GENERAL_CAPTURE_TIM_CH1_GPIO_CLK RCC_APB2Periph_GPIOA
#define GENERAL_CAPTURE_TIM_CH1_PORT GPIOA
#define GENERAL_CAPTURE_TIM_CH1_PIN GPIO_Pin_0
#define GENERAL_CAPTURE_TIM_CHANNEL_x TIM_Channel_1
// 中断相关宏定义
#define GENERAL_CAPTURE_TIM_IT_CCx TIM_IT_CC1
#define GENERAL_CAPTURE_TIM_IRQ TIM5_IRQn
#define GENERAL_CAPTURE_TIM_INT_FUN TIM5_IRQHandler
// 获取捕获寄存器值函数宏定义
#define GENERAL_CAPTURE_TIM_GetCapturex_FUN TIM_GetCapture1
// 捕获信号极性函数宏定义
#define GENERAL_CAPTURE_TIM_OCxPolarityConfig_FUN TIM_OC1PolarityConfig
// 测量的起始边沿
#define GENERAL_CAPTURE_TIM_STRAT_ICPolarity TIM_ICPolarity_Rising
// 测量的结束边沿
#define GENERAL_CAPTURE_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 CAPTURE_TIM_Init(void);
#endif
my_capture.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "my_capture.h"
// 定时器输入捕获用户自定义变量结构体定义
TIM_ICUserValueTypeDef TIM_ICUserValueStructure = {0,0,0,0};
/**
* @brief NVIC配置
* @param 无
* @retval 无
*/
static void GENERAL_TIM_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// 设置中断组为0
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
// 设置中断来源
NVIC_InitStructure.NVIC_IRQChannel = GENERAL_CAPTURE_TIM_IRQ ;
// 设置主优先级为 0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// 设置抢占优先级为3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief GPIO配置
* @param 无
* @retval 无
*/
static void GENERAL_TIM_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 输入捕获通道 GPIO 初始化
RCC_APB2PeriphClockCmd(GENERAL_CAPTURE_TIM_CH1_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = GENERAL_CAPTURE_TIM_CH1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GENERAL_CAPTURE_TIM_CH1_PORT, &GPIO_InitStructure);
}
/**
* @brief TIM配置
* @param 无
* @retval 无
*/
static void GENERAL_TIM_Mode_Config(void)
{
// 开启定时器时钟,即内部时钟CK_INT=72M
GENERAL_CAPTURE_TIM_APBxClock_FUN(GENERAL_CAPTURE_TIM_CLK,ENABLE);
/*--------------------时基结构体初始化-------------------------*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
TIM_TimeBaseStructure.TIM_Period=GENERAL_CAPTURE_TIM_PERIOD;
// 驱动CNT计数器的时钟 = Fck_int/(psc+1)
TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_CAPTURE_TIM_PSC;
// 时钟分频因子 ,配置死区时间时需要用到
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数器计数模式,设置为向上计数
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 重复计数器的值,没用到不用管
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
// 初始化定时器
TIM_TimeBaseInit(GENERAL_CAPTURE_TIM, &TIM_TimeBaseStructure);
/*--------------------输入捕获结构体初始化-------------------*/
TIM_ICInitTypeDef TIM_ICInitStructure;
// 配置输入捕获的通道,需要根据具体的GPIO来配置
TIM_ICInitStructure.TIM_Channel = GENERAL_CAPTURE_TIM_CHANNEL_x;
// 输入捕获信号的极性配置
TIM_ICInitStructure.TIM_ICPolarity = GENERAL_CAPTURE_TIM_STRAT_ICPolarity;
// 输入通道和捕获通道的映射关系,有直连和非直连两种
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
// 输入的需要被捕获的信号的分频系数
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
// 输入的需要被捕获的信号的滤波系数
TIM_ICInitStructure.TIM_ICFilter = 0;
// 定时器输入捕获初始化
TIM_ICInit(GENERAL_CAPTURE_TIM, &TIM_ICInitStructure);
// 清除更新和捕获中断标志位
TIM_ClearFlag(GENERAL_CAPTURE_TIM, TIM_FLAG_Update|GENERAL_CAPTURE_TIM_IT_CCx);
// 开启更新和捕获中断
TIM_ITConfig (GENERAL_CAPTURE_TIM, TIM_IT_Update | GENERAL_CAPTURE_TIM_IT_CCx, ENABLE );
// 使能计数器
TIM_Cmd(GENERAL_CAPTURE_TIM, ENABLE);
}
void CAPTURE_TIM_Init(void)
{
GENERAL_TIM_GPIO_Config();
GENERAL_TIM_NVIC_Config();
GENERAL_TIM_Mode_Config();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* @brief TIM Input Capture Init structure definition
*/
typedef struct
{
uint16_t TIM_Channel; /*!< Specifies the TIM channel.
This parameter can be a value of @ref TIM_Channel */
uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal.
This parameter can be a value of @ref TIM_Input_Capture_Polarity */
uint16_t TIM_ICSelection; /*!< Specifies the input.
This parameter can be a value of @ref TIM_Input_Capture_Selection */
uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler.
This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
uint16_t TIM_ICFilter; /*!< Specifies the input capture filter.
This parameter can be a number between 0x0 and 0xF */
} TIM_ICInitTypeDef;
TIM_Channel
1
2
3
4
5
6
7
8
/** @defgroup TIM_Channel
* @{
*/
#define TIM_Channel_1 ((uint16_t)0x0000)
#define TIM_Channel_2 ((uint16_t)0x0004)
#define TIM_Channel_3 ((uint16_t)0x0008)
#define TIM_Channel_4 ((uint16_t)0x000C)
TIM_ICPolarity
1
2
3
4
5
6
7
/** @defgroup TIM_Input_Capture_Polarity
* @{
*/
#define TIM_ICPolarity_Rising ((uint16_t)0x0000) //上升沿触发
#define TIM_ICPolarity_Falling ((uint16_t)0x0002) //下降沿触发
#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A) //边沿跳变触发
TIM_ICSelection
1
2
3
4
5
6
7
/** @defgroup TIM_Input_Capture_Selection
* @{
*/
#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to IC1, IC2, IC3 or IC4, respectively */ //CCx通道被配置为输入,ICx映射在TIx上
#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to IC2, IC1, IC4 or IC3, respectively. *///CCx通道被配置为输入,IC1,IC2,IC3,IC4映射在TI2,TI1,TI4,TI3上
#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. *///:CCx通道被配置为输入,ICx映射在TRC上。此模式仅工作在内部触发器输入被选中时(由TIMx_SMCR寄存器的TS位选择)
注:CCXS仅在通道关闭时(TIMx_CCER寄存器的CCXE=’0’)才是可写的
TIM_ICPrescaler
1
2
3
4
5
6
7
8
/** @defgroup TIM_Input_Capture_Prescaler
* @{
*/
#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. *///无预分频器,捕获输入口上检测到的每一个边沿都触发一次捕获
#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. *///每2个事件触发一次捕获
#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. *///每4个事件触发一次捕获
#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. *///每8个事件触发一次捕获
TIM_ICFilter
范围0-15
ICxF[3:0] | 采样频率 | 数字滤波器长度 |
---|---|---|
0000 | fDTS | 无 |
0001 | fck_INT | 2 |
0010 | fck_INT | 4 |
0011 | fck_INT | 8 |
0100 | fDTS/2 | 6 |
0101 | fDTS/2 | 8 |
0110 | fDTS/4 | 6 |
0111 | fDTS/4 | 8 |
1000 | fDTS/8 | 6 |
1001 | fDTS/8 | 8 |
1010 | fDTS/16 | 5 |
1011 | fDTS/16 | 6 |
1100 | fDTS/16 | 8 |
1101 | fDTS/32 | 5 |
1110 | fDTS/32 | 6 |
1111 | fDTS/32 | 8 |
stm32f10x_it.c
#include "my_capture.h"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/**
* @brief This function handles TIM interrupt request.
* @param None
* @retval None
*/
void GENERAL_CAPTURE_TIM_INT_FUN(void)
{
// 当要被捕获的信号的周期大于定时器的最长定时时,定时器就会溢出,产生更新中断
// 这个时候我们需要把这个最长的定时周期加到捕获信号的时间里面去
if ( TIM_GetITStatus ( GENERAL_CAPTURE_TIM, TIM_IT_Update) != RESET )
{
TIM_ICUserValueStructure.Capture_Period ++;
TIM_ClearITPendingBit ( GENERAL_CAPTURE_TIM, TIM_FLAG_Update );
}
// 上升沿捕获中断
if ( TIM_GetITStatus (GENERAL_CAPTURE_TIM, GENERAL_CAPTURE_TIM_IT_CCx ) != RESET)
{
// 第一次捕获
if ( TIM_ICUserValueStructure.Capture_StartFlag == 0 )
{
// 计数器清0
TIM_SetCounter ( GENERAL_CAPTURE_TIM, 0 );
// 自动重装载寄存器更新标志清0
TIM_ICUserValueStructure.Capture_Period = 0;
// 存捕获比较寄存器的值的变量的值清0
TIM_ICUserValueStructure.Capture_CcrValue = 0;
// 当第一次捕获到上升沿之后,就把捕获边沿配置为下降沿
GENERAL_CAPTURE_TIM_OCxPolarityConfig_FUN(GENERAL_CAPTURE_TIM, GENERAL_CAPTURE_TIM_END_ICPolarity);
// 开始捕获标准置1
TIM_ICUserValueStructure.Capture_StartFlag = 1;
}
// 下降沿捕获中断
else // 第二次捕获
{
// 获取捕获比较寄存器的值,这个值就是捕获到的高电平的时间的值
TIM_ICUserValueStructure.Capture_CcrValue =
GENERAL_CAPTURE_TIM_GetCapturex_FUN (GENERAL_CAPTURE_TIM);
// 当第二次捕获到下降沿之后,就把捕获边沿配置为上升沿,好开启新的一轮捕获
GENERAL_CAPTURE_TIM_OCxPolarityConfig_FUN(GENERAL_CAPTURE_TIM, GENERAL_CAPTURE_TIM_STRAT_ICPolarity );
// 开始捕获标志清0
TIM_ICUserValueStructure.Capture_StartFlag = 0;
// 捕获完成标志置1
TIM_ICUserValueStructure.Capture_FinishFlag = 1;
}
TIM_ClearITPendingBit (GENERAL_CAPTURE_TIM,GENERAL_CAPTURE_TIM_IT_CCx);
}
}
通道 | 捕获计数函数 | 更改捕获边沿函数 |
---|---|---|
Channel | TIM_GetCapture1 | TIM_OC1PolarityConfig |
Channe2 | TIM_GetCapture2 | TIM_OC2PolarityConfig |
Channe3 | TIM_GetCapture3 | TIM_OC3PolarityConfig |
Channe4 | TIM_GetCapture4 | TIM_OC4PolarityConfig |
main.c
和调用初始化main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "stm32f10x.h"
#include "my_gpio.h"
#include "my_usart.h"
#include "my_data_queue.h"
#include "my_process_data.h"
#include "my_adc.h"
#include "my_tim.h"
#include "my_advance_pwm.h"
#include "my_general_pwm.h"
#include "my_capture.h"
extern __IO uint16_t ADC_ConvertedValue[NOFCHANEL];
Channel ch[2];
float VREF,VSENSE;
float temp;
float adcValue;
__IO uint32_t time = 0; // ms 计时变量
uint32_t freq;
uint8_t duty1,duty2,duty3,duty4;
int main(void)
{
uint32_t capture_time;
uint32_t TIM_PscCLK = 72000000 / (GENERAL_CAPTURE_TIM_PSC+1);
/* LED 端口初始化 */
LED_GPIO_Config();
Key_GPIO_Config();
/* 初始化USART 配置模式为 9600 8-N-1 */
USART_Config();
/*初始化接收数据队列*/
RX_Queue_Init();
/*初始化ADC*/
ADCx_Init();
/*初始化TIM 1ms*/
MY_TIM_Init();
/*初始化PWM 1MHz 50%*/
ADVANCE_PWM_Init();
/*初始化PWM 10KHz 50% 40% 30% 20%*/
GENERAL_PWM_Init();
/*初始化输入捕获*/
CAPTURE_TIM_Init();
freq=10000;
duty1=50;
duty2=40;
duty3=30;
duty4=20;
printf( "\r\n Print current Temperature \r\n");
while (1)
{
if(TIM_ICUserValueStructure.Capture_FinishFlag == 1)
{
// 计算高电平时间的计数器的值
capture_time = TIM_ICUserValueStructure.Capture_Period * (GENERAL_CAPTURE_TIM_PERIOD+1) +
(TIM_ICUserValueStructure.Capture_CcrValue+1);
// 打印高电平脉宽时间
printf ( "\r\n duty time:%d.%d s\r\n",capture_time/TIM_PscCLK,capture_time%TIM_PscCLK );
TIM_ICUserValueStructure.Capture_FinishFlag = 0;
}
if ( time >= 1000 ) /* 1000 * 1 ms = 1s 时间到 */
{
time = 0;
/* LED1 取反 */
LED1_TOGGLE;
VREF=1.2f*4096/ADC_ConvertedValue[2];
VSENSE=VREF*ADC_ConvertedValue[1]/4096;
temp=(1.43f-VSENSE)/4.3+25;
adcValue=VREF*ADC_ConvertedValue[0]/4096;
printf( "\r\n The IC current tem= %.2fC\r\n", temp);
printf( "\r\n The IC current VDDA= %.2fV\r\n", VREF);
printf( "\r\n The IC current ADC= %.2fV\r\n", adcValue);
freq-=1000;
if(freq<=1000)
{
freq=10000;
}
duty1+=10;
duty2-=10;
duty3+=5;
duty4-=5;
if(duty1>=100)
{
duty1=10;
}
if(duty2<=10)
{
duty2=100;
}
if(duty3>=100)
{
duty3=5;
}
if(duty4<=5)
{
duty4=100;
}
Set_General_PWM_FREQ(freq,duty1,duty2,duty3,duty4);
}
Process_Usart_Data(ch);
if(ch[0].state==1&&ch[0].start_up==0)
{
ch[0].stop_up=0;
ch[0].start_up=1;
LED1(ON);
}
if(ch[0].state==2&&ch[0].stop_up==0)
{
ch[0].stop_up=1;
ch[0].start_up=0;
LED1(OFF);
}
if(ch[1].state==1&&ch[1].start_up==0)
{
ch[1].stop_up=0;
ch[1].start_up=1;
LED2(ON);
}
if(ch[1].state==2&&ch[1].stop_up==0)
{
ch[1].stop_up=1;
ch[1].start_up=0;
LED2(OFF);
}
}
}