本文记录STM32F103PWM频率信号采集cube配置过程,及simulink模型配置,代码生成。希望能够帮助到有需要的小伙伴~
目录
STM32频率信号采集介绍:
TIM_ClockDivision的寄存器:主要是给滤波器和死区用的时钟
DTS时间是增加,相当于频率降低
这样我们就清楚了时钟分割的用处了,就在这3个方面
1.外部触发输入:这个实际用得少,就不说了
2.输入捕获:一般是测量一个信号的频率、占空比、脉宽等
3.死区时间设定
配置参数:
//定时器相关
TIM_TimeBaseStructure.TIM_Prescaler =72-1;//时钟频率
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;//自动装载值ARR
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分割
TIM_RepetitionCounter 应该是在本次定时结束后,再重装载定时 1次,
是否使用重复定时器,当该值不为0的时候,计数器计数值达到周期数时,该值减1,计数器重新计数,当该值减到0的时候才会产生事件
ARPE:自动重装载预装载允许位 (Auto-reload preload enable)
0: TIMx_ARR寄存器没有缓冲;
1: TIMx_ARR寄存器被装入缓冲器。
1. auto-reload precload=Disable:自动重装载寄存器ARR写入新值后,计数器立即产生计数溢出,然后开始新的计数周期
2. auto-reload precload=Enable:自动重装载寄存器ARR写入新值后,计数器完成当前旧的计数后,再开始新的计数周期
//输入捕获相关
TIM_ICInitStructure.TIM_Channel = TIM_Channel_8;//通道
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge; //上升沿触发和下降沿触发
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;
// Div:1, every edge
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//不分频,输入预分频。意思是控制在多少个输入周期做一次捕获,如果 //输入的信号频率没有变,测得的周期也不会变。比如选择4分频,则每四个输入周期才做一次捕获
TIM_ICInitStructure.TIM_ICFilter = 15;//滤波器位值=15
我们看到以上配置中有2个配置:配置分割系数,滤波器数值
(1)不分割就是说明CK_INT=72/72=1MHz,那么fTDS=1MHZ,tTDS=1us;
(2)滤波器数值=15,这要回到对应的寄存器中TIM1->CCMR1中,即IC1F[3:0]=1111b(2进制),可以到计算出采样频率fSAMPLING=fTDS/32=1MHz/32=31.25KHz
根据奈奎斯特采样定律可知(至少2倍采样信号频率),被采样的频率最大为31.25KHz/2=15.625KHz,如果大于这个频率信号将不能被正常识别;
N什么意思呢,手册中说:数字滤波器由事件计数器组成,每 N 个事件才视为一个有效边沿;
其实是指读取的电平信号持续多长时间才认为是有效电平信号,看下图
这里计数频率是1MHz,即t=1us,N=8即说明采集到高电平信号持续8us才能认为是有效高电平
设定分割频率,根据滤波系数决定的采样频率和N事件有利于滤除高频干扰信号
测量思路:
输入捕获触发中断时,记录当时的计数值
首先设定为上升沿触发,当进入中断之后(rising)记录与上次中断(rising_last)之间的间隔(周期,其倒数就是频率)。再设定为下降沿,进入中断之后与上升沿时刻之差即为高电平时间(falling-rising_last),高电平时间除周期即为占空比
还有一种方案:利用两个通道,但是需要自己改代码,simulink代码生成的就是第一种
1. 每个定时器有四个输入捕获通道IC1、IC2、IC3、IC4。且IC1 IC2一组,IC3 IC4一组。并且可是设置管脚和寄存器的对应关系。
2. 同一个TIx输入映射了两个ICx信号。
3. 这两个ICx信号分别在相反的极性边沿有效。
4. 两个边沿信号中的一个被选为触发信号,并且从模式控制器被设置成复位模式。
5. 当触发信号来临时,被设置成触发输入信号的捕获寄存器,捕获“一个PWM周期(即连续的两个上升沿或下降沿)”,它等于包含TIM 时钟周期的个数(即捕获寄存器中捕获的为TIM的计数个数n)。
6. 同样另一个捕获通道捕获触发信号和下一个相反极性的边沿信号的计数个数m,即(即高电平的周期或低电平的周期)
7. 由此可以计算出PWM的时钟周期和占空比了
frequency=f(TIM时钟频率)/n。
duty cycle=(高电平计数个数/n),
若m为高电平计数个数,则duty cycle=m/n
若m为低电平计数个数,则duty cycle=(n-m)/n
频率采集配置:
cube配置:
选择TIM8采集频率,通道1设置为输入捕获
TIM8用的时钟源为APB2,也是72M
分频系数72-1,得到TIM8时钟为72/72=1M
CounterMode选择向上计数
TIM_Period = 65535;//自动装载值ARR
其他默认
输入捕获模式选择上升沿触发(后面要改,需要改为上升或下降沿触发,这个地方改不了)
simulink配置:
cube配置好后保存,打开simulink模块库,选择TIM模块,选择通道8(cube配置好后才可以选),
CH1Value是转换频率和占空比为字符串发送出去的,这个库在demo中有,或者下载我的工程中也有。
我是通过串口1发送的,整个模块放在0.5s周期函数内运行。
理论上频率高于15.26HZ的都可以采集,实际我测试不太准,只有频率高一点才准。
cube中配置上升沿触发,simulink中也会是rising触发,无法配置成上升或下降沿触发。而tlc文件中判断的又是rising_falling,导致没法测量
占空比,生成的代码也是错的。暂时把tlc文件改了,通道一改为定值,上升沿下降沿触发,TLC文件在D:\MATLAB\STM32-MAT\STM32\blks\mex\tlc_c下的TIMERS_Config(具体看自己的STM-MAT安装路径)
如果其他通道也要用的话,都需要改
配置完后就可以生成代码,测试了。之前我测试过1KHZ的频率还比较准,频率低的话会不准。
有问题可以评论区回复或直接联系:QQ/WX:953909472
欢迎点赞分享~
附件