stm32f103单片机测频率代码解释
时间: 2023-07-09 10:07:49 浏览: 89
以下是一个基于STM32F103单片机测量频率的示例代码,注释中有详细的解释:
```
#include "stm32f10x.h" // 包含STM32F10x系列单片机的头文件
TIM_ICInitTypeDef TIM_ICInitStructure; // 定义TIM_ICInitStructure结构体,用于配置输入捕获模式
uint16_t CCR1_Val = 0; // 定义CCR1_Val变量,用于存储捕获到的脉冲宽度值
uint16_t CCR2_Val = 0; // 定义CCR2_Val变量,用于存储捕获到的脉冲宽度值
uint16_t IC1ReadValue1 = 0; // 定义IC1ReadValue1变量,用于存储捕获到的输入捕获寄存器值
uint16_t IC1ReadValue2 = 0; // 定义IC1ReadValue2变量,用于存储捕获到的输入捕获寄存器值
uint16_t IC2ReadValue1 = 0; // 定义IC2ReadValue1变量,用于存储捕获到的输入捕获寄存器值
uint16_t IC2ReadValue2 = 0; // 定义IC2ReadValue2变量,用于存储捕获到的输入捕获寄存器值
volatile uint16_t CaptureNumber = 0; // 定义CaptureNumber变量,用于存储输入捕获的次数
volatile uint32_t Capture = 0; // 定义Capture变量,用于存储输入捕获的总时间
int main(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // 定义TIM_TimeBaseStructure结构体,用于配置定时器基本参数
GPIO_InitTypeDef GPIO_InitStructure; // 定义GPIO_InitStructure结构体,用于配置GPIO参数
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; // 配置GPIOA0和GPIOA1为输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; // 定时器周期为65535,最大值
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 定时器预分频为0
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; // 定时器时钟分频为0
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 定时器计数模式为向上计数
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 初始化TIM2
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; // 配置输入捕获通道为通道1
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿触发输入捕获
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // 直接映射到TI1上
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 不分频
TIM_ICInitStructure.TIM_ICFilter = 0x0; // 不进行滤波
TIM_ICInit(TIM2, &TIM_ICInitStructure); // 初始化输入捕获模式
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; // 配置输入捕获通道为通道2
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; // 下降沿触发输入捕获
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI; // 映射到TI2,需要通过TIM2_CCER寄存器配置
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 不分频
TIM_ICInitStructure.TIM_ICFilter = 0x0; // 不进行滤波
TIM_ICInit(TIM2, &TIM_ICInitStructure); // 初始化输入捕获模式
TIM_Cmd(TIM2, ENABLE); // 使能TIM2
while (1)
{
if (CaptureNumber == 4) // 当捕获次数达到4次时
{
Capture = (IC2ReadValue2 - IC2ReadValue1) + (IC1ReadValue2 - IC1ReadValue1); // 计算输入捕获的总时间
CCR1_Val = (uint16_t)(Capture >> 1); // 计算脉冲1的宽度
CCR2_Val = (uint16_t)(Capture >> 2); // 计算脉冲2的宽度
CaptureNumber = 0; // 重置捕获次数
Capture = 0; // 重置输入捕获的总时间
}
}
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) // 如果是通道1的输入捕获中断
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); // 清除中断标志位
if (CaptureNumber == 0) // 如果是第一次捕获
{
IC1ReadValue1 = TIM_GetCapture1(TIM2); // 获取输入捕获1的寄存器值
CaptureNumber = 1; // 捕获次数加1
}
else if (CaptureNumber == 1) // 如果是第二次捕获
{
IC1ReadValue2 = TIM_GetCapture1(TIM2); // 获取输入捕获1的寄存器值
CaptureNumber = 2; // 捕获次数加1
}
}
else if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) // 如果是通道2的输入捕获中断
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); // 清除中断标志位
if (CaptureNumber == 2) // 如果是第三次捕获
{
IC2ReadValue1 = TIM_GetCapture2(TIM2); // 获取输入捕获2的寄存器值
CaptureNumber = 3; // 捕获次数加1
}
else if (CaptureNumber == 3) // 如果是第四次捕获
{
IC2ReadValue2 = TIM_GetCapture2(TIM2); // 获取输入捕获2的寄存器值
CaptureNumber = 4; // 捕获次数加1
}
}
}
```
这段代码主要通过使用STM32F103单片机的定时器2的输入捕获模式来测量频率。在主函数中,首先进行了一些初始化操作,包括配置GPIO和定时器参数等。然后通过使用定时器2的输入捕获模式来捕获GPIOA0和GPIOA1输入的脉冲,分别计算它们的宽度,并将宽度存储在CCR1_Val和CCR2_Val变量中。最后,通过使用中断来实现输入捕获,并在捕获次数达到4次时计算输入捕获的总时间。
阅读全文