STM32-微项目05-输入检测测试PWM周期

一、微项目实现目标:

利用TIM2定时器产生的PWM波,输入到TIM3输入检测模块,在接收到输入的PWM信号,模块进行计算,在OLED上打印对应的频率

(总结来说,测周法,测试周期频率)

二、微项目硬件配置需求:

stm32F103C8T6核心板一块

0.96寸OLED显示,用于显示计数

三、前置知识:

整个项目由两大块组成:1,输出比较模式控制输出不同周期的PWM数据;2,输入比较模式下,检测输入的PWM波

1,输出比较模式控制输出不同周期的PWM数据:

 

①选择PWM1模块,在CNT计数值<CCR时刻,REF置为有效电平,在CNT计数值>=CCR,且小于ARR时刻,REF置为无效电平;

2,输入检测检测PWM周期

 ①时基单元:主要配置PSC/ARR数值,时钟源选择72MHZ内部时钟

②输入捕获单元的配置。

1-滤波器主要是对于信号进行滤波处理;

2-边沿检测极性选择主要来判断极性;

3-分频器,再一次进行分频处理;如果分频因子为2,则捕获两次上升沿,才认为有效

③从模式选择

 在识别上升沿后,触发从模式,清空CNT

输入捕获PWM周期的整体逻辑:

1,时基单元,按照设定的PSC,输入的时钟源信号进行计数处理,当收到输入捕获模式的触发源后,将CNT的数值转移CCR1寄存器中,CCR1的值就是本次计数的数据,在进行一轮计算就可以得到输入的频率,f_x=f_c / N

2,紧接着触发的从模式,会将CNT的数据进行清0,进行下一轮的计数。

3,每次产生触发都是从0开始计数的,所以转移的CNT值就是实际的两次上升沿之间的时间占比

四、代码逻辑分析

主要两大块

1,PWM输出比较模块

①开启TIM2时钟、PA0时钟

②配置时钟源

③配置时基模块参数

④配置输出比较模块参数

⑤配置PA0端口

⑥开启时钟

2,输入比较模块

①开启TIM3时钟、PA6时钟

②配置时钟源

③配置时基模块

④配置输入单元模块

⑤配置从模式

⑥配置GIPO端口

⑦开启时钟

五、代码示例:

1,PWM输出比较模块

①开启TIM2时钟、PA0时钟

//配置时钟RCC
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

②配置时钟源

//配置时钟源为RCC -72mhz
	TIM_InternalClockConfig(TIM2);

③配置时基模块参数

	//配置时基单元数值
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1 ;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up ;
	TIM_TimeBaseInitStruct.TIM_Period=100-1;  //ARR
	TIM_TimeBaseInitStruct.TIM_Prescaler=720-1;  //psc
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);

④配置输出比较模块参数

TIM_OCStructInit(&TIM_OCInitStruct);用于进行默认初始化,原因是,后面的初始化仅对部分参数进行设定,为防止bug,先进行一次默认初始化

	//输出比较单元配置
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1 ;
	
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High ;
	
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse=0;//设置CCR数值

	TIM_OC1Init(TIM2, &TIM_OCInitStruct);

⑤配置gpio_PA0端口  复用推挽输出

// 配置PA0端口
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStruct);
	

⑥开启时钟

	//启动定时器
	TIM_Cmd(TIM2,ENABLE);

⑦动态配置CCR的数值,输出不同占空比

动态配置psc的数值,输出不同频率

void pwm_setcompare( uint16_t compare)
{
	TIM_SetCompare1(TIM2, compare);
}
void pwm_setPerscaler(uint16_t prescaler )//修改psc的数值,达到修改pwm频率
{
	TIM_PrescalerConfig(TIM2,  prescaler, TIM_PSCReloadMode_Immediate);
	
}

2,输入比较模块

①开启TIM3时钟、PA6时钟

	//开启GPIO、TIM的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//tim3

②配置PA6端口的输入模式-上拉输入

//配置PA6端口
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

③配置时钟源 72mhz

//时基单元时钟源配置--系统时钟72MHZ
	TIM_InternalClockConfig(TIM3);

④配置时基单元

	//时基单元配置
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1 ;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up ;
	TIM_TimeBaseInitStruct.TIM_Period=65536-1; //ARR
	TIM_TimeBaseInitStruct.TIM_Prescaler=72-1; //PSC
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStruct);

⑤配置输入捕获模块

//配置输入捕获
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel=TIM_Channel_1 ;//输入捕获的端口
	TIM_ICInitStruct.TIM_ICFilter=0xf;//输入捕获的滤波器
	TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising ;//捕获的状态 上升沿/下降沿
	TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1 ;//分频器,如果是二分频,则两次输出一次
	TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;//属于直连通道还是交叉通道
	TIM_ICInit( TIM3, & TIM_ICInitStruct);

⑥从模式配置

//从模式触发源选择
	TIM_SelectInputTrigger( TIM3, TIM_TS_TI1FP1);
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);

⑦开启时钟

//开启时钟
	TIM_Cmd(TIM3, ENABLE);

⑧配置输出频率计算模块

f_x=f_c / N

uint32_t IC_getfreq(void)
{
	return 1000000/TIM_GetCapture1(TIM3);
}

最后在main函数中简单配置

#include "stm32f10x.h"                  // Device header
#include "delay.h"
#include "OLED.H"
#include "PWM.H"
#include "ic.H"

uint32_t freq=0;

int main()
{

	OLED_Init();
	OLED_ShowString(1,3,"freq:");
	pwm_init();
	ic_init();
	pwm_setcompare(50);//duty=CCR/100  占空比
	pwm_setPerscaler(720-1); //freq=72M/(psc+1)/100  频率
	while(1)
	{
		freq=IC_getfreq();
		OLED_ShowNum(2,1,freq,5);
		
	}
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值