OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2609|回复: 10

STM32对输入频率为一点几赫兹的信号计数错误

[复制链接]

1

主题

5

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2018-4-24
在线时间
2 小时
发表于 2018-4-24 21:30:37 | 显示全部楼层 |阅读模式
5金钱
个人做一个基于STM32F103ZET6的心率检测系统的设计,传感器将周期为600-800ms的方波信号输入开发板,通过定时器3的上升沿输入捕获采集捕获到两个上升沿时计数器的值并作差计算频率,定时六秒测出平均频率并显示输出。
我改写的程序很不稳定,从0-1000多不等,偶尔可以测的正确值。求大神指教是哪里出了问题需要如何修改,以下是代码。

//定时器3通道1输入捕获配置
TIM_ICInitTypeDef  TIM3_ICInitStructure;

void TIM3_Cap_Init(u16 arr,u16 psc)
{         
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
           NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        //使能定时器时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能引脚时钟
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;  //PA6
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA6 输入
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOA,GPIO_Pin_6);                                                //PA6 下拉
       
        //初始化TIM3       

  TIM_InternalClockConfig(TIM3);
       
        TIM_TimeBaseStructure.TIM_Period = arr; //自动装载值
        TIM_TimeBaseStructure.TIM_Prescaler =psc;         //预分频
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分割TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定参数初始化时间基数单位

        //初始化输入捕获参数
        TIM3_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01        
  TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿
  TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1
  TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //不分频
  TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000不滤波¨
  TIM_ICInit(TIM3, &TIM3_ICInitStructure);
       
        //中断分组初始化
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);  //
       
        TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新
       
  TIM_Cmd(TIM3,ENABLE );         //



}

float FAN_Frequency=0;//频率                                   
u16        TIM3CH1_CAPTURE_VAL1=0,TIM3CH1_CAPTURE_VAL2=0,CaptureNumber=0;//捕获值记录1、2、捕获次数
u32 TIM3Capture=0;//最终值

//定时器中断服务程序         
void TIM3_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
        {
                TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
        }
        else if(TIM_GetITStatus(TIM3,TIM_IT_CC1)==SET)
        {
                TIM_ClearITPendingBit(TIM3,TIM_IT_CC1);
                if(CaptureNumber==0)
                {
                        TIM3CH1_CAPTURE_VAL1=TIM_GetCapture1(TIM3);
                        CaptureNumber=1;
                }
                else if(CaptureNumber==1)
                {
                        TIM3CH1_CAPTURE_VAL2=TIM_GetCapture1(TIM3);
                        if(TIM3CH1_CAPTURE_VAL2>TIM3CH1_CAPTURE_VAL1)
                        {
                                TIM3Capture=(TIM3CH1_CAPTURE_VAL2-TIM3CH1_CAPTURE_VAL1);
                        }
                        else
                        {
                                TIM3Capture=((0xffff-TIM3CH1_CAPTURE_VAL1)+TIM3CH1_CAPTURE_VAL2);
                        }
                        CaptureNumber=0;
                }
                FAN_Frequency=(u32)1000000/(TIM3Capture);//频率
               
        }

    TIM_ClearFlag(TIM3, TIM_FLAG_CC1); //清除中断标志

}





部分主程序
int BPM;    //心率值


void HeartRate(void);

extern float FAN_Frequency;       //频率                                 
extern u16        TIM3CH1_CAPTURE_VAL1,TIM3CH1_CAPTURE_VAL2,CaptureNumber;       //捕获值记录1、2、次数
extern u32 TIM3Capture;          //最终值

int main(void)
{       

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
TIM3_Cap_Init(59999,71);
while(1)
{
HeartRate();
}
void HeartRate(void)
{
         int i;
         float j;
         TIM_Cmd(TIM3,ENABLE);
         for(i=1;i<=10;i++)
         {
           j+=FAN_Frequency;
                 _delay_ms(500);
         }
         TIM_Cmd(TIM3,DISABLE);
         j=(j/10)*60;
         BPM=j;
         
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2018-4-25 01:12:34 | 显示全部楼层
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2018-4-24
在线时间
2 小时
 楼主| 发表于 2018-4-25 12:08:27 | 显示全部楼层
别沉啊
回复

使用道具 举报

15

主题

406

帖子

0

精华

高级会员

Rank: 4

积分
795
金钱
795
注册时间
2015-3-26
在线时间
151 小时
发表于 2018-4-25 16:16:31 | 显示全部楼层
几赫兹的信号不可能计数失败的
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2018-4-24
在线时间
2 小时
 楼主| 发表于 2018-4-25 18:48:02 | 显示全部楼层
xyl210xyl 发表于 2018-4-25 16:16
几赫兹的信号不可能计数失败的

请问问题出在哪里呢,系统时钟有10KHz,而被测的只有几赫兹而已,是这个差距太大么
回复

使用道具 举报

7

主题

200

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1279
金钱
1279
注册时间
2017-7-18
在线时间
257 小时
发表于 2018-4-25 19:00:43 | 显示全部楼层
可以用示波器看一下波形,是不是有毛刺影响了计数。
回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8021
金钱
8021
注册时间
2014-8-13
在线时间
1595 小时
发表于 2018-4-25 20:23:44 | 显示全部楼层
TIM3_Cap_Init(59999,71);这里是每60ms中断一次吗?
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2018-4-24
在线时间
2 小时
 楼主| 发表于 2018-4-26 09:10:50 | 显示全部楼层
周易八索连山 发表于 2018-4-25 19:00
可以用示波器看一下波形,是不是有毛刺影响了计数。

我先用信号源模拟的
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2018-4-24
在线时间
2 小时
 楼主| 发表于 2018-4-26 09:12:10 | 显示全部楼层
mack13013 发表于 2018-4-25 20:23
TIM3_Cap_Init(59999,71);这里是每60ms中断一次吗?

一开始是6s中断一次的,改为60ms反而测量变大了
回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8021
金钱
8021
注册时间
2014-8-13
在线时间
1595 小时
发表于 2018-4-26 11:51:30 | 显示全部楼层
我的执着B 发表于 2018-4-26 09:12
一开始是6s中断一次的,改为60ms反而测量变大了

原理没怎么看懂。TIM3进入中断的时候记录TIM3的计数值?谁来测外部信号?

为什么我觉得应该是两次外部上升中断时,读取TIM3的计数值,然后前后值做差求出时间间隔?

没看见你外部中断的处理过程啊
回复

使用道具 举报

15

主题

406

帖子

0

精华

高级会员

Rank: 4

积分
795
金钱
795
注册时间
2015-3-26
在线时间
151 小时
发表于 2018-4-27 11:10:09 | 显示全部楼层
我的执着B 发表于 2018-4-25 18:48
请问问题出在哪里呢,系统时钟有10KHz,而被测的只有几赫兹而已,是这个差距太大么

系统时钟仅供参考,因为还要分频,系统时钟也不可能是10khz这个数。问题出在你计数器的配置,和中断的处理
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-7 16:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表