当前位置: 代码网 > 科技>电脑产品>交换机 > 11、江科大stm32视频学习笔记——输入捕获模式测频率、PWMI模式测频率占空比

11、江科大stm32视频学习笔记——输入捕获模式测频率、PWMI模式测频率占空比

2024年08月01日 交换机 我要评论
江科大stm32视频学习笔记——输入捕获模式测频率、PWMI模式测频率占空比

目录

一、知识点

1、ic(input capture)输入捕获

2、通用定时器结构

(1)输出比较的执行逻辑

(2)四个输入捕获和输出比较通道

(3)输入捕获的执行流程和输出比较的区别

(4)输入捕获的作用

(5)输入捕获通道

(6)pwmi模式:同时测量频率和占空比

(7)主从触发模式:实现硬件全自动测量

3、测频法和测周法测量频率

(1)测频法和测周法的原理

(2)测频法和测周法的选择

(3)测频法和测周法的比较

(4)测频法和测周法的实现

4、主从触发模式

5、结构

(1)捕获输出基本结构

(2)pwmi基本结构

二、输入捕获模式测频率

1、原理图

2、改变pwm频率

3、单独修改psc的函数

4、设置1000hz,占空比为50%

5、工作步骤

6、ccr

7、 代码

(1)ic.c

(2)mian.c

三、pwmi模式频率占空比1、ic.c中不一样的地方

2、ic.c

3、main.c

四、知识点

测频率的性能


一、知识点

1、icinput capture)输入捕获

2、通用定时器结构

(1)输出比较的执行逻辑

(2)四个输入捕获和输出比较通道

(3)输入捕获的执行流程和输出比较的区别

(4)输入捕获的作用

(5)输入捕获通道

(6)pwmi模式:同时测量频率和占空比

(7)主从触发模式:实现硬件全自动测量

3、测频法和测周法测量频率

(1)测频法和测周法的原理

测频率法:定义一个t,如1s,在1s的时间内,有多少个周期,就是多少hz

测周法:周期的倒数就是频率,测出一个周期的时间,再取倒数,就是频率(测量时间的方法:定时器计次,使用一个已知频率fc的计次时钟,来驱动计数器,从一个上升沿开始计,计数器从0开始,一直计到下一个上升沿,停止,计一个数的时间是1/fc,计n个数,时间就是n/fc,n/fc就是周期,再取一个倒数,就得到公式fx=fc/n)

中界频率:测频率法的n=测周法的n,两者误差相等。

(2)测频法和测周法的选择

此时,当待测信号小于中界频率时,用测周法,当大于中界频率时,用测频法

(3)测频法和测周法的比较

测频法适合高频信号(因为若n很小,误差会很大),若闸门时间选为1s,那么每隔1s才能出结果,结果比较慢

测周法适合测量低频信号(周期比较长,计次就会比较多,有助于减少误差),测一个周期就能出现结果,而一般待测信号频率都比较大,故结果更新较快

(4)测频法和测周法的实现

a、测频法的思路:之前的对射式红外传感器计次计次,每来一个上升沿计次1,再用有一个定时器,每隔1s中断,再中断中,每隔1s取一次计次值,同时清0计次,为下一次做准备,这样每次读取的计次值就是频率

定时器外部时钟也同理,每隔1s取一次计次,就能实现

b、测周法:测量两个上升沿的时间(见本次代码)

4、主从触发模式

5、结构

(1)捕获输出基本结构

(2)pwmi基本结构

占空比:ccr2/ccr1 

二、输入捕获模式测频率

1、原理图

2、改变pwm频率

    tim_timebaseinitstructure.tim_period = 100 - 1;        //arr
    tim_timebaseinitstructure.tim_prescaler = 720 - 1;        //psc
    tim_ocinitstructure.tim_pulse = 0;        //ccr

这代码中,因为arr=100,所以ccr的值为占空比(该电平在周期的比例)

 3、单独修改psc的函数

void pwm_setprescaler(uint16_t prescaler)
{
	//第三个参数指定定时器预分屏器的重装模式
	//第一个 tim_pscreloadmode_update,预分频器在更新事件重装//等待周期结束
	// 第二个tim_pscreloadmode_immediate预分频器立即重装//可能一个周期没结束就切换
	tim_prescalerconfig(tim2, prescaler, tim_pscreloadmode_immediate);
}

4、设置1000hz,占空比为50%

	pwm_setprescaler(720 - 1);		//freq = 72m / (psc + 1) / 100  //1000hz
	pwm_setcompare1(50);			//duty = ccr / 100        //占空比为50%

5、工作步骤

6、ccr

7、 代码

(1)ic.c

#include "stm32f10x.h"                  // device header

void ic_init(void)
{
	//tim3
	rcc_apb1periphclockcmd(rcc_apb1periph_tim3, enable);
	rcc_apb2periphclockcmd(rcc_apb2periph_gpioa, enable);
	
	
	gpio_inittypedef gpio_initstructure;
	gpio_initstructure.gpio_mode = gpio_mode_ipu;//上拉模式
	gpio_initstructure.gpio_pin = gpio_pin_6;//pa6
	gpio_initstructure.gpio_speed = gpio_speed_50mhz;
	gpio_init(gpioa, &gpio_initstructure);
	
	
	tim_internalclockconfig(tim3);//tim3
	
	tim_timebaseinittypedef tim_timebaseinitstructure;
	tim_timebaseinitstructure.tim_clockdivision = tim_ckd_div1;
	tim_timebaseinitstructure.tim_countermode = tim_countermode_up;//向上计数
	tim_timebaseinitstructure.tim_period = 65536 - 1;		//arr最好大一些,防止溢出
	tim_timebaseinitstructure.tim_prescaler = 72 - 1;		//psc这个值决定了测周法的标准频率fc=1m
	tim_timebaseinitstructure.tim_repetitioncounter = 0;
	
	tim_timebaseinit(tim3, &tim_timebaseinitstructure);//tim3
	
	//第四步:配置输入捕获单元
	tim_icinittypedef tim_icinitstructure;
	tim_icinitstructure.tim_channel = tim_channel_1;//选择通道1
	tim_icinitstructure.tim_icfilter = 0xf;//数越大,滤波效果越好,滤波器计次不会改变信号原有的频率,一般滤波器的采样频率会远高于信号频率
	tim_icinitstructure.tim_icpolarity = tim_icpolarity_rising;//上升沿触发
	tim_icinitstructure.tim_icprescaler = tim_icpsc_div1;//分频器对信号本身进行计次,会改变频率。此处不分频
	tim_icinitstructure.tim_icselection = tim_icselection_directti;//直连通道
	tim_icinit(tim3, &tim_icinitstructure);
	
	//第五步:选择重模式的触发源
	tim_selectinputtrigger(tim3, tim_ts_ti1fp1);
	//选择触发之后执行的操作
	tim_selectslavemode(tim3, tim_slavemode_reset);
	
	//使能
	tim_cmd(tim3, enable);
}

uint32_t ic_getfreq(void)
{
	//fc除n(fc,标准频率=72m/预分频系数)
	return 1000000 / (tim_getcapture1(tim3) + 1);
}

(2)mian.c

#include "stm32f10x.h"                  // device header
#include "delay.h"
#include "oled.h"
#include "pwm.h"
#include "ic.h"

int main(void)
{
	oled_init();
	pwm_init();
	ic_init();
	
	oled_showstring(1, 1, "freq:00000hz");
	
	pwm_setprescaler(720 - 1);		//freq = 72m / (psc + 1) / 100  //1000hz
	pwm_setcompare1(50);			//duty = ccr / 100        //占空比为50%
	
	while (1)
	{
		oled_shownum(1, 6, ic_getfreq(), 5);
	}
}

三、pwmi模式频率占空比
1、ic.c中不一样的地方

//该函数会自动把剩下的一个通道初始化成相反的配置,第一个是通道1,直连、上升沿
//第二个是通道2,交叉、下降沿
tim_pwmiconfig(tim3, &tim_icinitstructure);

uint32_t ic_getduty(void)
{
	return (tim_getcapture2(tim3) + 1) * 100 / (tim_getcapture1(tim3) + 1);
}

2、ic.c

#include "stm32f10x.h"                  // device header

void ic_init(void)
{
	rcc_apb1periphclockcmd(rcc_apb1periph_tim3, enable);
	rcc_apb2periphclockcmd(rcc_apb2periph_gpioa, enable);
	
	gpio_inittypedef gpio_initstructure;
	gpio_initstructure.gpio_mode = gpio_mode_ipu;
	gpio_initstructure.gpio_pin = gpio_pin_6;
	gpio_initstructure.gpio_speed = gpio_speed_50mhz;
	gpio_init(gpioa, &gpio_initstructure);
	
	tim_internalclockconfig(tim3);
	
	tim_timebaseinittypedef tim_timebaseinitstructure;
	tim_timebaseinitstructure.tim_clockdivision = tim_ckd_div1;
	tim_timebaseinitstructure.tim_countermode = tim_countermode_up;
	tim_timebaseinitstructure.tim_period = 65536 - 1;		//arr
	tim_timebaseinitstructure.tim_prescaler = 72 - 1;		//psc
	tim_timebaseinitstructure.tim_repetitioncounter = 0;
	tim_timebaseinit(tim3, &tim_timebaseinitstructure);
	
	tim_icinittypedef tim_icinitstructure;
	tim_icinitstructure.tim_channel = tim_channel_1;
	tim_icinitstructure.tim_icfilter = 0xf;
	tim_icinitstructure.tim_icpolarity = tim_icpolarity_rising;
	tim_icinitstructure.tim_icprescaler = tim_icpsc_div1;
	tim_icinitstructure.tim_icselection = tim_icselection_directti;
	//该函数会自动把剩下的一个通道初始化成相反的配置,第一个是通道1,直连、上升沿
	//第二个是通道2,交叉、下降沿
	tim_pwmiconfig(tim3, &tim_icinitstructure);

	tim_selectinputtrigger(tim3, tim_ts_ti1fp1);
	tim_selectslavemode(tim3, tim_slavemode_reset);
	
	tim_cmd(tim3, enable);
}

uint32_t ic_getfreq(void)
{
	return 1000000 / (tim_getcapture1(tim3) + 1);
}

uint32_t ic_getduty(void)
{
	return (tim_getcapture2(tim3) + 1) * 100 / (tim_getcapture1(tim3) + 1);
}

3、main.c

#include "stm32f10x.h"                  // device header
#include "delay.h"
#include "oled.h"
#include "pwm.h"
#include "ic.h"

int main(void)
{
	oled_init();
	pwm_init();
	ic_init();
	
	oled_showstring(1, 1, "freq:00000hz");
	oled_showstring(2, 1, "duty:00%");
	
	pwm_setprescaler(720 - 1);			//freq = 72m / (psc + 1) / 100
	pwm_setcompare1(50);				//duty = ccr / 100
	
	while (1)
	{
		oled_shownum(1, 6, ic_getfreq(), 5);
		oled_shownum(2, 6, ic_getduty(), 2);
	}
}

四、知识点

测频率的性能

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com