6.1江科大STM32学习之TIM输入捕获测频率和占空比

 1.硬件原理

通过PA0端口产生输出PWM波形,PA6口输入频率从而达到捕获的目的

2.输出PWM波形部分思路:

PA0产生输出PWM波形

其中我们用通用定时器,所以我们选择是TIM2,也就是通用定时器2

a.通过定时器2通道产生

其中通用定时器2,3,4,5都在同一个APB2总线上

a.所以使能定时器2和GPIOA

b.初始化GPIOA

c.配置时钟源和时基单元初始化

d.PA0输出比较初始化

e.使能定时器

f.控制PWM频率大小

3.输出波形部分代码

1.受外设控制的引脚,均需要配置为复用模式,并且输出,所以PA_0模式要设置成推挽输出模式

2.因为是内部输出,要把TIM2配置成内部时钟

3.因为

(ARR+1)一更改影响三个参数所以不该ARR,频率该PSC+1,占空比更改CCR

4.因为结构体值没赋完所以通过TIM_OCStructInit先给所有结构体内的值赋一个初始值,然后对其内部的一些值进行更改

输出比较配置成PWM模式1,输出为高电平,输出使能打开,初始CCR设为0,

5.使能定时器

6.

 TIM_PrescalerConfig:设置PSC的值

the update event:更新事件重装

immediately:立刻重装

TIM_SetCompare1:设置CCR1的值 

比如:

PA口就能输出一个频率1KHz,占空比50%的待测信号

4.输入捕获代码

1.RCC开启时钟:开启GPIO和TIM时钟

2.GPIO初始化:把GPIO设置成输入模式一般为上拉输入和浮空输入(容易受影响)

3.配置时基单元:用于自增

4.配置输入捕获模块:配置滤波器、极性、分频器、直连通道还是交叉通道

5.从模式触发源选择:这里选择为TI1FP1

6.触发源触发操作选择:执行reset(复位)操作

7.使能TIM3,使其运行

8.库函数

TIM.h库函数

TIM_ICInit:

结构体配置输入捕获单元函数,输入捕获和输出比较都有四个通道,输入捕获因为可能有交叉通道存在所以没有用OCInit一样有四个通道配置函数

第一个参数选择哪个定时器,第二个参数就是包含各个配置的结构体第一个参数选择哪个定时器,第二个参数就是包含各个配置的结构体

TIM_PWMIConfig:如果用ICinit的话只能配置一路,但是用TIM_PWMIConfig两路可以同时配置

这个函数将外设电路一次性配置成PWMI模式(通过这个函数配置能把另一个通道配置成相反的函数)在这个整体中,他配置为通道2,交叉,下降沿触发

TIM_SelectInputTrigger:选择输入触发源TRGI(从模式触发源选择)

调用这个函数就能选择从模式的触发源了。我们本节要用的TI1FP1

 TIM_SelectSlaveMode:选择从模式响应功能

TIM_SelectOutputTrigger:选择输出触发源TRGO(主模式输出触发源选择)

读写的都是CCR寄存器。

输出比较模式下,CCR是只写的,要用TIM_SetCompare1写入。

输入捕获模式下,CCR是只读的,要用TIM_GetCapture1读出

输入捕获代码实现

第一步开启RCC时钟

因为TIM2输出PWM。所以输入捕获的定时器要换一个,所以我们用TIM3。TIM3也是APB1的外设,所以函数还是APB1


 

由上图可以看到TIM3的通道1和通道2对应PA6和PA7。通道3和通道4对应PB0和PB1,因为我们本次代码计划用TIM3的通道1引脚,所以引脚就是PA6。

我们计划用PA6的TIM3_CH1通道,所以开启GPIOA的时钟。

所以我们开启RCC时钟为:

第二步GPIO初始化:上拉输入,GPIOA_6

第三步时基单元配置

接下来就是时基单元,选择内部时钟,定时器要换成TIM3。

然后是时基单元的参数,ARR自动重装值,为防止计数溢出。这里我们就给最大值65536-1,也就是十六位的计数,可以满量程计数。因为更新频率=72M/PSC+1/ARR+1,

fc(标准)=72M/PSC+1

fx=fc/N

arr越大N的范围就越大,从而使其计数越界的范围越小

由于我们要配置PA6所以我们选择TIM3通道1

TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;

直连的话是TI1FP1

交叉的话是TI1FP2

由于不是直连,交叉就是ch2数据选择器是由ch1捕获的了

TIM_PWMIConfig()

使用这个函数,只需要传入一个通道的参数就行了,在这个函数里会自动把剩下的一个通道初始化成相反的配置

比如这里传入通道1,直连,上升沿,那函数里面就会顺带配置通道2,交叉,下降沿。

如果传入通道2,直连,上升沿,函数就会顺带配置通道1,交叉,下降沿。

这个函数只支持通道1和通道2的配置,不要传入通道3和通道4。

参考文章《stm32学习笔记---TIM输入捕获(代码部分)输入捕获模式测频率/PWMI模式测频率占空比

  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是STM32F103 TIM1输入捕获频率,周期和占空比的代码示例: 1. 配置TIM1为输入捕获模式: ```c TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; 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 = 0x0; TIM_ICInit(TIM1, &TIM_ICInitStructure); TIM_Cmd(TIM1, ENABLE); ``` 2. 定义变量存储捕获的值: ```c uint16_t IC1Value = 0; uint16_t IC2Value = 0; ``` 3. 在TIM1输入捕获中断处理函数中获取捕获的值: ```c void TIM1_CC_IRQHandler(void) { if(TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); IC1Value = TIM_GetCapture1(TIM1); } else if(TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC2); IC2Value = TIM_GetCapture2(TIM1); } } ``` 4. 计算量值: ```c uint32_t TIM1Freq = SystemCoreClock / (TIM_GetPrescaler(TIM1) + 1); uint32_t TIM1Period = (IC2Value - IC1Value + 0xFFFF) % 0xFFFF; float TIM1DutyCycle = 100.0 * (IC2Value - IC1Value) / TIM1Period; ``` 其中,`SystemCoreClock`为系统时钟频率。 完整代码示例: ```c #include "stm32f10x.h" uint16_t IC1Value = 0; uint16_t IC2Value = 0; int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; 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 = 0x0; TIM_ICInit(TIM1, &TIM_ICInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; TIM_ICInit(TIM1, &TIM_ICInitStructure); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ITConfig(TIM1, TIM_IT_CC1 | TIM_IT_CC2, ENABLE); TIM_Cmd(TIM1, ENABLE); while(1); } void TIM1_CC_IRQHandler(void) { if(TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); IC1Value = TIM_GetCapture1(TIM1); } else if(TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC2); IC2Value = TIM_GetCapture2(TIM1); } uint32_t TIM1Freq = SystemCoreClock / (TIM_GetPrescaler(TIM1) + 1); uint32_t TIM1Period = (IC2Value - IC1Value + 0xFFFF) % 0xFFFF; float TIM1DutyCycle = 100.0 * (IC2Value - IC1Value) / TIM1Period; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值