OpenEdv-开源电子网

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

晚上2个小时的杰作,分享给大家,也给自己留作备份

[复制链接]

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2016-5-1 01:00:55 | 显示全部楼层 |阅读模式
本帖最后由 八度空间 于 2016-5-1 01:16 编辑

最近用到定时器捕获波形频率,参考了标准库自带的例程,貌像不怎么准,有时候还很离谱,于是自己对照手册弄了一个,有不对的还请高手指点
PWM波发生由STM32F030芯片输出(PWM占空比变化输出),STM32F103进行采集。
函数捕获的原理:
1、CC1是从波形的上升沿开始捕获,当下一个上升沿来临时,所计数的就是一个波形周期的时间
2、CC2是从波形的下降沿开始捕获,当下一个下降沿来临时,所计数的就是高电平期间的时间,计算占空比用到

函数原型
[mw_shl_code=applescript,true]/**
  *****************************************************************************
  *                                 PWM输入捕获
  *
  *                       (C) Copyright 2000-2020, ***
  *                             All Rights Reserved
  *****************************************************************************
  *
  * @File    : pwm_capture.c
  * @By      : 陈桂东
  * @Version : V1.0
  * @Date    : 2016 / 04 / 30
  *
  *****************************************************************************
  *
  *                                   Update
  *
  * @Version : V1.*
  * @By      : ***
  * @Date    : 20** / ** / **
  * @Brief   : ***
  *
  *****************************************************************************
**/


#include "pwm_capture.h"


/******************************************************************************
                                   定义变量
******************************************************************************/

uint16_t IC1Value = 0;  //捕获值存放,可用于计算频率,占空比等
uint16_t IC2Value = 0;

/**
  *****************************************************************************
  * @Name   : 计算捕获PWM频率、占空比
  *
  * @Brief  : none
  *
  * @Input  : TIMx_CLK: 定时器所在总线频率,单位Hz
  *
  * @Output : *Freq:    捕获的PWM频率
  *           *Duty:    捕获的PWM占空比
  *
  * @Return : none
  *****************************************************************************
**/
void PWM_CaptureGetFrequency_DutyCycle(uint32_t TIMx_CLK/* 单位Hz */, uint32_t * Freq/* 单位Hz */, uint8_t * Duty)
{
        uint32_t tmp = 0;
        
        //
        //得到捕获计数周期频率
        //
        tmp = TIMx_CLK / PWM_Capture_Prescaler;  //根据分频来计算,捕获的PWM频率由这个来决定
        
        *Freq = tmp / IC1Value;  //得到频率
        *Duty = (IC2Value * 100) / IC1Value;  //占空比 = (IC2Value / IC1Value) * 100;
}

/**
  *****************************************************************************
  * @Name   : PWM输入捕获初始化
  *
  * @Brief  : none
  *
  * @Input  : none
  *
  * @Output : none
  *
  * @Return : none
  *****************************************************************************
**/
void PWM_CaptureInit(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        
        RCC->APB2ENR|=1<<2;  //打开GPIOA时钟
        RCC->APB2ENR|=1<<0;  //打开AFIO时钟
        RCC->APB1ENR|=1<<0;  //打开TIM2时钟
        
        //
        //重映射
        //
        GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);  //TIM2部分重映射
        
        //
        //初始化IO PA.15 --> TIM2-CH1-ETR
        //
        GPIOA->CRH &= 0x0FFFFFFF;  //清除配置
        GPIOA->CRH |= 0x40000000;  //浮空输入
        GPIOA->ODR |= 1<<15;  //上拉
        
        //
        //配置定时器分频,计数周期
        //
         TIM2->ARR = PWM_Capture_Period - 1;  //计数器自动重装值
        TIM2->SC = PWM_Capture_Prescaler - 1;  //预分频器
        
        //
        //从模式控制寄存器
        //
        TIM2->SMCR |= 1<<7;  //触发输入(TRGI)
        TIM2->SMCR |= 5<<4;  //滤波后的定时器输入1(TI1FP1)
        TIM2->SMCR |= 4<<0;  //复位模式 – 选中的触发输入(TRGI)的上升沿重新初始化计数器,并且产生一个更新寄存器的信号
        //
        //初始化捕获寄存器参数 CC1
        //
        TIM2->CCMR1 |= 1<<0;  //CC1通道被配置为输入,IC1映射在TI1上
        TIM2->CCMR1 |= 3<<4;  //采样频率f SAMPLING =f CK_INT ,N=8
        TIM2->CCMR1 |= 0<<2;  //无预分频器,捕获输入口上检测到的每一个边沿都触发一次捕获
        TIM2->CCER  |= 0<<1;  //不反相:捕获发生在IC1的上升沿;当用作外部触发器时,IC1不反相
        TIM2->CCER  |= 1<<0;  //捕获使能
        
        //
        //CC2
        //
        TIM2->CCMR1 |= 2<<8;  //CC2通道被配置为输入,IC2映射在TI1上
        TIM2->CCER  |= 1<<5;  //CC2P = 1. 反相:捕获发生在IC2的下降沿;当用作外部触发器时,IC2反相
        TIM2->CCER  |= 1<<4;  //捕获使能
        
        //
        //中断配置
        //
        TIM2->DIER |= 1<<1;  //允许捕获/比较1中断
        
        //
        //使能定时器
        //
        TIM2->CR1 |= 1<<0;
        
        //
        //初始化中断优先级
        //
        NVIC_InitStructure.NVIC_IRQChannel                   = TIM2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}

/**
  *****************************************************************************
  * @Name   : 中断服务程序
  *
  * @Brief  : none
  *
  * @Input  : none
  *
  * @Output : none
  *
  * @Return : none
  *****************************************************************************
**/
void TIM2_IRQHandler(void)
{
        IC1Value = TIM2->CCR1;  //读取上一次输入捕获1事件(IC1)传输的计数器值CCR1,清CC1IF标志位
        IC2Value = TIM2->CCR2;  //读取上一次输入捕获2事件(IC2)传输的计数器值CCR2,清CC2IF标志位
        TIM2->SR &= ~(1<<1);  //清除中断标志位
}
[/mw_shl_code]

头文件内容
[mw_shl_code=applescript,true]/**
  *****************************************************************************
  *                                 PWM输入捕获
  *
  *                       (C) Copyright 2000-2020, ***
  *                             All Rights Reserved
  *****************************************************************************
  *
  * @File    : pwm_capture.h
  * @By      : 陈桂东
  * @Version : V1.0
  * @Date    : 2016 / 04 / 30
  *
  *****************************************************************************
  *
  *                                   Update
  *
  * @Version : V1.*
  * @By      : ***
  * @Date    : 20** / ** / **
  * @Brief   : ***
  *
  *****************************************************************************
**/



#ifndef _pwm_capture_h
#define _pwm_capture_h


/**
  ****************************** Support C++ **********************************
**/
#ifdef __cplusplus
        extern "C"{
#endif               
/**
  *****************************************************************************
**/


/******************************************************************************
                               外部函数头文件
******************************************************************************/

#include "sys.h"


/******************************************************************************
                              定义捕获计数周期
******************************************************************************/

//
//注意:CCRx寄存器是16位的,分频注意大小,计数太快会爆,根据所捕获的频率设置
//
#define PWM_Capture_Prescaler                    (uint16_t)72  //分频:72000 000 / 72 = 1000 000Hz
#define PWM_Capture_Period                       (uint16_t)1000  //计数:1000 --> 1KHz

/******************************************************************************
                               外部调用功能函数
******************************************************************************/

void PWM_CaptureInit                             (void);  //PWM输入捕获初始化
void PWM_CaptureGetFrequency_DutyCycle           (uint32_t TIMx_CLK/* 单位Hz */, uint32_t * Freq/* 单位Hz */, uint8_t * Duty);  //计算捕获PWM频率、占空比


/**
  ****************************** Support C++ **********************************
**/
#ifdef __cplusplus
        }
#endif
/**
  *****************************************************************************
**/


#endif  /* end pwm_capture.h */
[/mw_shl_code]


STM32F0.zip

514.45 KB, 下载次数: 888

现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-5-1 03:17:49 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
430
金钱
430
注册时间
2016-3-17
在线时间
95 小时
发表于 2016-5-1 11:33:14 | 显示全部楼层
学习中....
回复 支持 反对

使用道具 举报

0

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2016-3-28
在线时间
23 小时
发表于 2016-5-10 08:47:49 | 显示全部楼层
不错哦
回复 支持 反对

使用道具 举报

1

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2017-11-18
在线时间
11 小时
发表于 2017-11-21 07:55:08 | 显示全部楼层
膜拜
回复 支持 反对

使用道具 举报

64

主题

446

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1032
金钱
1032
注册时间
2017-7-26
在线时间
275 小时
发表于 2017-11-21 11:58:18 | 显示全部楼层
楼主这个程序,检测50K左右频率时误差有多少呢?
回复 支持 反对

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2017-11-21 12:31:36 | 显示全部楼层
a3748622 发表于 2017-11-21 11:58
楼主这个程序,检测50K左右频率时误差有多少呢?

具体没测,你可以测试一下
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

0

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2017-11-24
在线时间
18 小时
发表于 2017-11-26 18:47:08 | 显示全部楼层
捕获采集,好资料。学习
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 07:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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