ccp1.rar
(179.89 KB)
使用proteus软件仿真基于PIC16F877A的数字频率计
仿真的时候没有问题 正确的显示频率信号
但是烧写到硬件的时候
出现了
无法计算频率的问题
数码管显示的数字不断的在改变
本人用的 函数信号发生器 产生 的 50.27HZ的 VPP为2V的 方波信号
请各位不吝赐教
//220v的交流电源直接用电阻限流,经光耦隔离,形成脉冲送到ccp2捕捉、动态显示
//A口做位选,D口做段选
#include<PIC.H>
__CONFIG(0x3F71);
# define T0_2MS 6 //TMR0的2ms延时常数,8分频
# define LED_QW RA0
# define LED_BW RA1
# define LED_SW RA2
# define LED_GW RA3
//全局变量定义
char WW,QW,BW,SW,GW;
char FUN,D1,A;
unsigned int TTZ,TON;
//函数声明
void CSH(void);
void BCD(unsigned int);
void interrupt INT_ISR(void);
void DELAY(unsigned int);
void DELAY_I(unsigned int);
const char LED_CODE[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
//const char LED_CODE[17]={0b11000000,0b11111001,0b10100100,0b10110000,
// 0b10011001,0b10010010,0b10000010,0b11111000,
// 0b10000000,0b10010000,0b10001000,0b10000011,
// 0b11000110,0b10100001,0b10000110,0b10001110,0b11111111};
void main(void)
{
DELAY(10);
CSH();
while(1);
}
void interrupt INT_ISR(void)
{
long X;
unsigned int Y;
if(CCP2IF==1 && CCP2IE==1)
{
CCP2IF=0;
if(FUN<2)FUN++; //只在FUN<3时才加1
if(FUN==1) //第一次ccp2中断,开始tmr0计数
{
TMR1L=0;TMR1H=0;
CCP2CON=0;
CCP2CON=0b00000111; //每16个上升沿中断
CCP2IF=0;
PORTA=0xf0&PORTA; //关闭显示
PORTD=0x00;
}
else if(FUN==2) //弟二次ccp2中断,计算周期
{
TTZ=(CCPR2H<<8) | CCPR2L; //将双字节数变成整数型,ttz为频率计算用
CCP2CON=0;
CCP2IE=0;
PEIE=0;
X=200000000; //频率的100倍,显示2位小数
X=X/TTZ;
Y=X;
BCD(Y); //作bcd转换
D1=TON=0; //准备显示频率
T0IE=1;
FUN=3;
}
}
if(T0IF==1&&T0IE==1)
{
T0IF=0;
if(FUN==3)
{
TMR0=T0_2MS;
PORTA=0xf0&PORTA; //关闭显示
PORTD=0x00;
switch(D1)
{
case 0: //显示千位
PORTD=LED_CODE[GW];
LED_GW=1;
break;
case 1: //显示百位
PORTD=LED_CODE[SW];
PORTD=PORTD|0x80; //最高位为0,显示小数点
LED_SW=1;
break;
case 2: //显示十位
PORTD=LED_CODE[BW];
LED_BW=1;
break;
case 3: //显示个位
PORTD=LED_CODE[QW];
LED_QW=1;
break;
}
D1=D1+1; //D1=1~4分别显示千位、百位、十位、个位
if(D1>3)D1=0;
TON=TON+1;
if(TON>=200)
{
TON=D1=FUN=0; //显示次数到
PORTA=0xf0&PORTA; //关闭显示
PORTD=0x00;
DELAY_I(100); //灭100ms,以造成闪动效果
PIR2=0;
PEIE=1;
CCP2IE=1;
CCP1IE=1;
CCP2CON=0;
CCP1CON=0;
CCP2CON=0b00000101; //每1个上升沿中断
CCP1CON=0b00000101; //每1个上升沿中断
CCP2IF=0;
CCP1IF=0;
INTCON=0b11000000; //允许外围中断
}
}
}
}
void CSH(void) //初始化程序
{ OPTION=0b10000010; //TMR0分频系数为1:8
TRISB=0b00000001; //RB0为CIS选择
TRISA=0b00000000; //RA0,RA3为输入,RA4必须为输出才有脉冲
TRISC=0b00000010; //RC口除RC1/CCP2外全为输出
TRISD=0b00000000; //RD口全为输出
PORTA=0x00;
PORTD=0x00;
TON=D1=FUN=0;
PIR2=0;
PEIE=1;
CCP2IE=1; //允许捕捉中断
CCPR2H=CCPR2L=0;
CCP2CON=0;
CCP2CON=0b00000101; //每一个上升沿中断
TMR1H=TMR1L=0;
T1CON=0b00110001; //RMR1分频比为1:8
INTCON=0b11000000; //允许外围中断
}
void DELAY(unsigned int n)
{
unsigned int j;
char k;
for(j=0;j<n;j++)
for(k=246;k>0;k--)NOP();
}
void DELAY_I(unsigned int n) //延时函数,中断专用
{
unsigned int j;
char k;
for(j=0;j<n;j++)
for(k=246;k>0;k--)NOP();
}
void BCD(unsigned int R1)
{
WW=0;QW=0;BW=0;SW=0;GW=0;
while(R1>=10000)
{R1-=10000;WW++;}
while(R1>=1000)
{R1-=1000;QW++;}
while(R1>=100)
{R1-=100;BW++;}
while(R1>=10)
{R1-=10;SW++;}
GW=R1;
} |
|