STM32
直播中

颜立歆

7年用户 934经验值
擅长:控制/MCU
私信 关注
[问答]

怎么实现基于STM32频率计的设计?

怎么实现基于STM32频率计的设计?

回帖(1)

刘京

2021-12-2 10:14:29
前言

最近在了解电赛相关的东西,和指导老师交流一下,我决定先从最简单的频率计做起。
频率计是来检测信号的频率的,在做频率计的时候可以用信号发生器发出的信号来进行测试。
原理






这是最基础的方波,我们可以通过检测上升沿的方式来测量其频率。从周期的角度出发连续两个上升沿的时间就是这个方波的周期,那这个周期分之一就是这个方波的频率了。
在思考了一段时间~~(我是萌新。。)~~ 我觉得有两个方法可以实现,第一个是采用stm32定时器的输入捕获功能,第二个就是用外部中断来实现这个功能。正如标题,我这次采用外部中断的方法来实现这个功能。
具体原理如下:
将外部中断的引脚设置为上升沿检测并且配置为下拉模式。每当检测到上升沿,就将计数值加一,这样一秒钟之内计数器的值就是频率

代码的实现
我是采用cubemx的方式来编程的。(教学资源还是挺多的)


主函数部分


while (1)
  {
    pwm_value = 0;
                HAL_Delay(1000);
               
                printf("频率是 %d Hz",pwm_value);
               
    /* USER CODE END WHILE */


    /* USER CODE BEGIN 3 */
  }


外部中断部分


void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)
{
                if(GPIO_Pin == GPIO_PIN_1)
                        pwm_value++;
                       
}


一开始我是采用hal库自带的延时函数来进行定时1s的。正如上文所述,在上升沿到达的时候计数器pwm_value 的值执行加一操作。1s之后就是该方波的频率了



后来的完善

一开始我觉得是因为外部中断只能达到这个程度,但是后来我发现在150000hz的时候其实串口是有数据的,只不过串口不再是一行一行的发送数据,而是一个字一个字的发送,这引起了我的注意,后来得知这是因为串口的收发速度小于了当时进入外部中断的频率所导致的。
所以我决定配置一个1s钟的定时器,在定时器中断到来的时候进行串口发送数据。(定时器中断优先级大于外部中断的优先级)
定时器部分

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
        if (htim->Instance == htim1.Instance)
        {
                printf("频率为 %d hzrn",pwm_value);
                pwm_value=0;
        }
我把主函数的部分移动到了这个1s的定时器中断里。
采用定时器中断,这个频率计的精度提高了,并且可以检测1MHz的频率。
后续想法

这个量程范围还是不够的,我打算再用外部中断的方法来试试,然后我还会去学习一下输入捕获的知识,用输入捕获的方式来实现这个项目。
ps:当我将方波换成正弦信号的时候惊奇的发现上升沿检测的方式仍然可以使用,后来去查了一下上升沿检测的概念,发现只要到达一定阈值就可以被检测,而不是我想的那样需要一个上升沿的到来。(这个真是很大的收获!)
举报

更多回帖

发帖
×
20
完善资料,
赚取积分