打印
[其他ST产品]

STM32F1常用外设介绍

[复制链接]
楼主: 范德萨发额
手机看帖
扫描二维码
随时随地手机跟帖
101
范德萨发额|  楼主 | 2023-2-28 20:04 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
频率测量:
测频法:在闸门时间T内,对上升沿计次,得到N,则频率


使用特权

评论回复
102
范德萨发额|  楼主 | 2023-2-28 20:04 | 只看该作者
测频法:自定一个闸门时间T,通常设置为1s,在1s时间内,对信号上升沿计次,从0开始计,每来一个上升沿,计次+1,每来一个上升沿,其实就是来了一个周期的信号,在1s时间内,来个几个周期,频率就是多少Hz,(频率的定义:1s内出现了多少个重复的周期),这是一种直接按频率定义来测量的方法,闸门时间也可以是2s,计次值除2,就是频率

测频法测量的是一个闸门时间的多个周期自带一个均值滤波,如果在闸门时间内波形频率有变化,得到的其实是这一段时间的平均频率,测频法测量时间慢,测量结果是一段时间的平均值,值比较平滑

使用特权

评论回复
103
范德萨发额|  楼主 | 2023-2-28 20:05 | 只看该作者
测周法:两个上升沿内,以标准频率计次,得到N,则频率




使用特权

评论回复
104
范德萨发额|  楼主 | 2023-2-28 20:05 | 只看该作者
测周法:捕获信号的两个上升沿,测量之间持续的时间,使用一个已知的标准频率的计次时钟,来驱动计数器,从一个上升沿开始计,计数器从0开始,一直计到下一个上升沿,停止,计一个数的时间是1/fc,计N个数时间就是N/fc,N/fc就是周期,再取个倒数,就得到频率的公式,fx = fc/N

测周法只测量一个周期,就能出一次结果,出结果的速度取决于待测信号的频率,一般来说测周法结果更新更快,但是由于他只测量一个周期,所以结果值会受噪声的影响,波动比较大。

使用特权

评论回复
105
范德萨发额|  楼主 | 2023-2-28 20:05 | 只看该作者
测频法适合测高频信号,测周法适合测量低频信号

例如:定了1s为闸门周期,结果1s内一个上升沿都没有,但不能认为频率是0,计次N很少时,误差会非常大,所以测频法适合测量高频率的信号,测周法适合低频信号,低频信号,周期比较长,计次就会比较多,有助于减少误差。如果待测频率太高,那么一个周期内只能计一两个数,如果待测信号再高一些,甚至一个数也计不到,不能认为频率无穷大

使用特权

评论回复
106
范德萨发额|  楼主 | 2023-2-28 20:06 | 只看该作者
中界频率:测频法与测周法误差相等时的频率点(测频法和测周法的N相同)


计数次数越多,±1误差对结果的影响越小

待测频率<中界频率,测周法合适

待测频率>中界频率,测频法合适

使用特权

评论回复
107
范德萨发额|  楼主 | 2023-2-28 20:06 | 只看该作者
异或门:当输入引脚的任何一个引脚有电平翻转时,输出引脚就产生一次电平翻转


输入信号来到输入滤波器(对信号进行滤波,避免高频的毛刺信号误触发)和边沿检测器(可以选择高电平触发,或者低电平触发)

使用特权

评论回复
108
范德萨发额|  楼主 | 2023-2-28 20:06 | 只看该作者
有两套滤波和边沿检测电路,第一套电路:经过滤波和极性选择得到TI1FP1,输入给通道1的后续电路,第二套电路:经过另一个滤波和极性选择得到TI1FP2,输入给下面通道2的后续电路,同理下面TI2的信号进来,也经过两套滤波和极性选择,得到TI2FP1和TI2FP2,其中TI2FP1输入给上面,TI2FP2输入给下面,两个输入信号进来可以选择各走各的,也可以选择进行交叉,让CH2引脚输入给通道1,或者CH1引脚输入给通道2,这样做的目的可以灵活切换后续捕获电路的输入,通过数据选择器进行灵活选择,可以把一个引脚的输入,同时映射到两个捕获单元,这是不是PWMI的经典结构,

例如,第一个捕获通道,使用上升沿触发,用来捕获周期,第二个通道,使用下降沿触发,用来捕获占空比,两个通道同时对一个引脚进行捕获,就可以同时测量频率和占空比,这就是PWMI模式。

使用特权

评论回复
109
范德萨发额|  楼主 | 2023-2-28 20:06 | 只看该作者
TRC是为了无刷电机的驱动

输入信号进行滤波和极性选择后,来到预分频器,预分频器,每个通道各有一个,可以选择对前面的信号进行分频,分频之后的触发信号就可以触发捕获电路进行工作了,每来一个触发信号,CNT的值就会向CCR转运一次,转运的同时,会发送一个捕获事件,这个事件会在状态寄存器置标志位,同时也可以产生中断,如果需要再捕获期间处理事情就可以开启这个捕获中断

例如:配置上升沿触发捕获,每来一个上升沿,CNT转运到CCR一次,因为CNT计数器是由内部的标准时钟驱动的,所以CNT的数值,可以用来记录两个上升沿之间的时间间隔,这个时间间隔就是周期,再取个倒数就是测周法测量的频率了,

每次捕获后要把CNT清0,下次再上升沿再捕获的时候取出的CNT才是两个上升沿的时间间隔,可以用主从触发模式,自动来完成。

使用特权

评论回复
110
范德萨发额|  楼主 | 2023-2-28 20:07 | 只看该作者
数字滤波器:由一个事件计数器组成,记录到N个事件后会产生一个输出的跳变,简单来说滤波器的工作原理就是,以采样频率对输入信号进行采样,当连续N个值都为高电平,输出才为高电平,连续N个值都为低电平输出才为低电平,如果信号出现高频抖动,导致连续采样N个值不全都一样,那输出就不会变化,这样就可以达到滤波的效果,采样频率越低,采样个数N越大,滤波效果就越好。

使用特权

评论回复
111
范德萨发额|  楼主 | 2023-2-28 20:11 | 只看该作者
主从触发模式:(主模式、从模式和触发源选择三个功能的简称)

主模式:将定时器内部的信号映射到TRGO引脚,用于触发别的外设。

从模式:接收其他外设或者自身外设的一些信号,用于控制自身定时器的运行,也就是被别的信号控制。

触发源选择:选择从模式的触发信号源,也可以认为是从模式的一部分,触发源选择,选择一个指定的信号得到TRGI,TRGI去触发从模式,从模式可以在上述列表里,选择一项操作来自动执行。

使用特权

评论回复
112
范德萨发额|  楼主 | 2023-2-28 20:11 | 只看该作者
例如:让TI1FP11信号自动触发CNT清零,触发源选择可以选择TI1FP1,从模式执行的操作,就可以选择执行Reset的操作,这样TI1FP1的信号就可以自动触发从模式,从模式自动清零CNT,实现硬件全自动测量

使用特权

评论回复
113
范德萨发额|  楼主 | 2023-2-28 20:12 | 只看该作者
输入捕获基本结构:

使用特权

评论回复
114
范德萨发额|  楼主 | 2023-2-28 20:12 | 只看该作者
只使用了一个通道,目前只能测量频率,配置好时基单元,启动定时器,CNT就会在预分频之后的时钟驱动下,不断自增,这个CNT就是测周法用来计数计时的,经过预分频之后的时钟频率就是,驱动CNT的标准频率fc,(标准频率 = 72M/预分频系数),下面输入捕获通道1的GPIO口,输入一个上面的方波信号,经过滤波器和边沿检测,选择TI1FP1为上升沿触发,之后输入选择直连的通道分频器选择不分频,当TI1FP1出现上升沿之后,CNT的当前计数值转运到CCR1里,同时触发源选择,选择TI1FP1选择为触发信号,选中TI1FP1为触发信号,从模式选择复位操作,TI1FP1的上升沿也同样会通过上面的触发源选择那一路,取触发CNT清零,注意是先转运CNT的值到CCR里去,再出发从模式给CNT清零或者是非阻塞的同时转移,CNT的值转移到CCR,同时0转移到CNT里面去,不能是先清零CNT,再捕获,否则捕获值都是0了。

使用特权

评论回复
115
范德萨发额|  楼主 | 2023-2-28 20:12 | 只看该作者
例如:左上角图,信号产生一个上升沿,CCR1 = CNT,就是把CNT的值转运到CCR1里面去,这是输入捕获自动执行的让CNT = 0,清零计数器(从模式自动执行的),在一个周期之内,CNT在标准时钟的驱动下,不断自增,并且由于之前清零过了,所以CNT就是从上升沿开始,从0开始计数一直++,指导,下一次上升沿来临,然后执行相同的操作,CCR1 = CNT,CNT = 0,第二次捕获时CNT,继续执行操作

使用特权

评论回复
116
范德萨发额|  楼主 | 2023-2-28 20:13 | 只看该作者
如果信号频率太低,CNT的计数值可能会溢出

想使用从模式自动清除CNT,只能用通道1和通道2,对于通道3和通道4,就只能开启捕获中断,在中断里手动清零了。(这样做程序会处于频繁中断的状态,比较消耗软件资源)

使用特权

评论回复
117
范德萨发额|  楼主 | 2023-2-28 20:13 | 只看该作者

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;//通道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)
{
        return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}

使用特权

评论回复
118
范德萨发额|  楼主 | 2023-2-28 20:13 | 只看该作者
PWMI基本结构:

PWMI模式,使用了两个通道捕获一个引脚可以同时测量周期和占空比,TI1FP1配置上升沿触发,触发捕获和清零CNT,TI1FP2,配置为下降沿触发,通过交叉通道,去触发通道2的捕获单元,去触发通道2的捕获单元

例如:左上角图,最开始上升沿,CCR1捕获,同时清零CNT,之后CNT一直++,在下降沿这个时刻,触发CCR2捕获,这时CCR的值就是高电平期间的计数值,CCR2捕获不会触发CNT清零,CNT++,直到下一次上升沿,CCR1捕获周期,CNT清零,这样执行,CCR1就一整个周期的计数值,CCR2就是高电平期间的计数值,用CCR2/CCR1,就是占空比。

使用特权

评论回复
119
范德萨发额|  楼主 | 2023-2-28 20:13 | 只看该作者
单独写入PSC的函数

void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);

    1

输入捕获步骤

第一步,RCC开启时钟,把GPIO的TIM的时钟打开

第二步,GPIO初始化,把GPIO配置成输入模式,一般选择上拉输入或者浮空输入模式

第三步,配置时基单元,让CNT计数器在内部时钟的驱动下自增运行

第四步,配置输入捕获单元,包括滤波器、极性、直连通道还是交叉通道、分频器这些参数

第五步,选择从模式的触发源,触发源选择TI1FP1,调用一个库函数即可

第六步,选择触发之后执行的操作,执行Reset操作,调用一个库函数即可

第七步,调用TIM_Cmd函数,开启定时器

使用特权

评论回复
120
范德萨发额|  楼主 | 2023-2-28 20:14 | 只看该作者
输入捕获常用函数
结构体配置输入捕获单元的函数

输出比较每个通道占用一个函数,输入捕获4个通道是共用一个函数的,在结构体中有额外的参数来选择通道

void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则