// 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; // 显示完毕后重新开启捕捉中断,启动新一次测量
}
}
|