打印

测频率,程序怎么写?

[复制链接]
8069|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sdouen|  楼主 | 2009-2-24 13:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
需要测30-70HZ方波的频率,并显示出频率(动态显示)。用PIC16F676,程序怎么写比较好?是不是每隔1MS读一下引脚的信号,采样信号高、低、高计算一次,然后显示出来?谢谢
沙发
chen3bing| | 2009-2-24 13:41 | 只看该作者

1MS时间太长了

1MS最多能测50Hz.

使用特权

评论回复
板凳
headwolf| | 2009-2-24 14:59 | 只看该作者

如果CCP就很简单,1US为单位,捕捉一下。

没有的话,开2个定时器,一个1US,一个做计数器,应该就可以了。估计你也是搞发电机上用的频率计,最多再多几个按键,直接在主程序查询和去抖,在主程序刷新显示就可以了。

使用特权

评论回复
地板
machunshui| | 2009-2-24 15:14 | 只看该作者

方法很多

方法很多:

计数器测频率,

捕获测频率,

外部中断测频率,

模拟比较器测频率,

使用特权

评论回复
5
ddb_21ic| | 2009-2-24 17:43 | 只看该作者

其实就是两种方法:测周期 和 计数

使用特权

评论回复
6
谈的元| | 2009-2-24 19:34 | 只看该作者

简单的就是定时一定时间读TCC计数器的数值

使用特权

评论回复
7
暮然| | 2009-3-4 22:05 | 只看该作者

虽然现在不做了

以前老做表,现在不做了。
测频率,采用ccp,最简单精确的应该是测一段时间内脉冲的个数,即省单片机硬件资源,又省单片机运行资源。

使用特权

评论回复
8
bobo1957| | 2009-5-12 01:01 | 只看该作者

主要就两种方法

测频率有两种方法,一个就是在一个固定的时间计数被测频率的脉冲个数,计算的到频率,另外一种就是在一个被测频率周期内,计数标准脉冲的个数,第一种方法适合频率较高场合,第二种适合频率低的场合,我用FPGA做过,两个方法配合使用,测出频率精度很高

使用特权

评论回复
9
殷华| | 2009-9-26 21:25 | 只看该作者
怎么没程序的????

使用特权

评论回复
10
jason_77chen| | 2009-9-28 13:34 | 只看该作者
8楼说得对,9楼你不能老想要人家的程式啊

使用特权

评论回复
11
李冬发| | 2009-9-30 21:08 | 只看该作者
工频频率计?
周期法。

使用特权

评论回复
12
backupyan| | 2009-12-21 19:56 | 只看该作者
//  CCP捕捉例子1,测量某方波的周期(假设小于65536us)
//  MCU主频4MHz,TMR1不分频时,每个计数值代表1us,1000000us代表1s


#include "pic.h"
#include "delay.h"
#include "seg74.h"

  __CONFIG (HS & LVPDIS & WDTDIS);

unsigned int LastCaptureData=0; //上一次捕捉数据
unsigned int NewCaptureData=0;  // 本次捕捉数据
unsigned int g_Period=0;        // 保存周期的变量=两次捕捉数据之差
unsigned int g_Frequency=0;     // 保存频率的变量


void InitCCP1()
{
  TRISC2=1; // RC2做为捕捉输入引脚
  CCP1IF=0; // 捕捉标志位清零
  CCP1IE=1; //  捕捉中断使能
  PEIE=1;   // 外围中断使能
  GIE=1;    // 总中断使能
  T1CKPS1=0; // 预分频比1:1
  T1CKPS0=0;
  T1OSCEN=0; //关闭独立时钟振荡器
  TMR1CS=0; // 时钟来源于Fosc/4
  TMR1ON=1; // 使能定时器计数
  //以上五条语句建议写为:T1CON=0b00000001; // 内部定时器方式,无分频
  CCP1M3=0; //0101:捕捉模式1:1 , 每个上升沿触发
  CCP1M2=1;
  CCP1M1=0;
  CCP1M0=1;
  //以上四条语句建议写为:CCP1CON=0b00000101;
}

void interrupt CCP1INT(void)
{
  if(CCP1IF==1) // 是CCP中断
  {
    CCP1IF=0;  // 清CCP中断标志
    if(LastCaptureData==0)  // 说明是第一个上升沿
    {
      LastCaptureData=CCPR1H; //获得捕捉数据的高8位
      //高8位<<8+低8位构成16位整数
      LastCaptureData=(LastCaptureData<<8)+CCPR1L;
    }
    else // 说明是第二个上升沿
    {
      NewCaptureData=CCPR1H;  //获得捕捉数据的高8位
      //高8位<<8+低8位构成16位整数
      NewCaptureData=(NewCaptureData<<8)+CCPR1L;
      g_Period=NewCaptureData-LastCaptureData; //计数值单位为us
      g_Frequency=(long)1000000/g_Period; // 得到周期

      LastCaptureData=0;   // 为下一次捕捉设定初始条件
      CCP1IE=0; //  停止捕捉中断产生,降低测量频率,
      // 否则在高频下会严重影响数码管扫描效果
    }
  }
  else
  {
    while(1);//  产生其它中断,必须查出后处理掉
  }
}
void main()
{
  InitCCP1(); // 初始化CCP模块1
  InitSMG(); //  初始化数码管
  while(1)
  {

    DisplayData(g_Frequency);  // 主循环就是显示频率
    CCP1IE=1; //  显示完毕后重新开启捕捉中断,启动新一次测量
  }
}

使用特权

评论回复
13
hemporer| | 2013-5-30 17:58 | 只看该作者
//  CCP捕捉例子1,测量某方波的周期(假设小于65536us)
//  MCU主频4MHz,TMR1不分频时,每个计数值代表1us,1000000us代表1s


#include "pic.h"
#include "delay.h"
#include "seg74.h"

  __CONFIG (HS & LVPDIS & WDTDIS);

unsigned int LastCaptureData=0; //上一次捕捉数据
unsigned int NewCaptureData=0;  // 本次捕捉数据
unsigned int g_Period=0;        // 保存周期的变量=两次捕捉数据之差
unsigned int g_Frequency=0;     // 保存频率的变量


void InitCCP1()
{
  TRISC2=1; // RC2做为捕捉输入引脚
  CCP1IF=0; // 捕捉标志位清零
  CCP1IE=1; //  捕捉中断使能
  PEIE=1;   // 外围中断使能
  GIE=1;    // 总中断使能
  T1CKPS1=0; // 预分频比1:1
  T1CKPS0=0;
  T1OSCEN=0; //关闭独立时钟振荡器
  TMR1CS=0; // 时钟来源于Fosc/4
  TMR1ON=1; // 使能定时器计数
  //以上五条语句建议写为:T1CON=0b00000001; // 内部定时器方式,无分频
  CCP1M3=0; //0101:捕捉模式1:1 , 每个上升沿触发
  CCP1M2=1;
  CCP1M1=0;
  CCP1M0=1;
  //以上四条语句建议写为:CCP1CON=0b00000101;
}

void interrupt Routine(void)
{
        if(CCP2IE && CCP2IF)
        {
                TMR1L = 0;
                TMR1H = 0;
                CCP2IF = 0;
                Period = CCPR2H << 8;
                Period += CCPR2L;

               
        }
}

void main()
{
  InitCCP1(); // 初始化CCP模块1
  InitSMG(); //  初始化数码管
  while(1)
  {
    DisplayData(g_Frequency);  // 主循环就是显示频率
  }
}

使用特权

评论回复
14
doob| | 2013-8-29 09:20 | 只看该作者
hemporer 发表于 2013-5-30 17:58
//  CCP捕捉例子1,测量某方波的周期(假设小于65536us)
//  MCU主频4MHz,TMR1不分频时,每个计数值代表1us, ...

  TRISC2=1; // RC2做为捕捉输入引脚
不明白这条指令,这条指令是把RC2作为输入口,但是单片机怎么知道是ccp1的捕捉输入口呢?
看资料都怎么设置一个捕捉口也没看到很清晰地描述。
   还望点拨一下,谢谢大虾;

使用特权

评论回复
15
opal11| | 2013-8-29 22:08 | 只看该作者
路过,学习。

使用特权

评论回复
16
hemporer| | 2013-8-30 20:21 | 只看该作者
doob 发表于 2013-8-29 09:20
TRISC2=1; // RC2做为捕捉输入引脚
不明白这条指令,这条指令是把RC2作为输入口,但是单片机怎么知道是 ...

这个看具体单片机
一般来说RC2是为ccp1所用
肯定要把它设置成输入模式的

我用的中断方式
void interrupt Routine(void)
{
        if(CCP2IE && CCP2IF)
        {
                TMR1L = 0;
                TMR1H = 0;
                CCP2IF = 0;
                Period = CCPR2H << 8;
                Period += CCPR2L;

               
        }
}

配置好ccp1con 和 定时器1的相关寄存器就好了

使用特权

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

本版积分规则

54

主题

117

帖子

2

粉丝