从PIC教材上找的一段程序码,关于PIC16F877A用于频率捕捉的,但是源程序敲进去后数码管无显示;教材附带hex文件显示正常。急,求解!谢谢!
以下为程序码:
//-----------------------------------------------------------------
// 名称: 用工作于捕获方式的CCP1设计的频率计
//-----------------------------------------------------------------
// 说明: 在切换不同的频率输入后按下K1按键,数码管上将显示当前频率值.
// 两次捕获的时间差值即为当前输入频率的周期,倒数可得频率.
//
//-----------------------------------------------------------------
#include <pic.h>
#define INT8U unsigned char
#define INT16U unsigned int
#define _XTAL_FREQ 4000000UL
//按键定义
#define Key_DOWN() (RC5 == 0)
//共阴数码管0~9的数字编码,最后一位为黑屏
const INT8U SEG_CODE[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00 };
//const INT8U SEG_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//分解后的待显示数位
INT8U Display_Buffer[] = {0,0,0,0};
//显示开关控制变量
INT8U Disp_ON = 0;
//连续两次捕获计数变量
volatile INT16U CAPi = 0,CAPj = 0;
//连续三次检测的频率值
volatile INT16U Freq[] = {0,0,0};
//-----------------------------------------------------------------
// 数码管显示频率
//-----------------------------------------------------------------
void Show_FRQ_ON_DSY()
{
//INT8U i = 0;
if (!Disp_ON) return; //如果禁止显示则直接返回
for (INT8U i = 0; i < 4; i++)
{
PORTB=0X00; //暂时关闭数码管
PORTD=~(0X10<<i); //先发送扫描码(RD4-RD7依次扫描)
PORTB=SEG_CODE[Display_Buffer[i]]; //发送数字段码
if(i==0)
RB7=1; //最高位加小数点
__delay_ms(2);
}
}
//------------------------------------------------------------------
// CCP1输入捕获中断子程序(6次捕获,获取3次检测的频率值)
//------------------------------------------------------------------
void interrupt CCP1_Capture_INT()
{
static INT8U Fi = 0; //频率数组索引
if(CCP1IF) //读取第一次捕获值
{
if(CAPi==0)
CAPi=((CCPR1H<<8)+CCPR1L);
else //第二次捕获
{
CAPj=((CCPR1H<<8)+CCPR1L);
CAPj=1000000UL/(CAPj-CAPi); //根据相减得到周期计算频率(us)
Freq[Fi]=CAPj; //保存第i次检测到的频率并递增索引
if(++Fi==3) //达到3次后开始判断检测频率是否相等
{
Fi=0;
if(Freq[0]==Freq[1]&&Freq[0]==Freq[2]) //如果3次检测频率相等,则停止检测,并分解显示数位
{
CCP1IE=0; //禁止CCP1中断
TMR1ON=0; //禁止TIMER1计数
for(INT8U i=3;i!=0xff;i--) //分解频率数位并放入显示缓冲
{
Display_Buffer[i]=CAPj%10;
CAPj/=10; // a/=b等同于a=a/b;
}
Disp_ON=1; //开显示
return; //返回
}
}
TMR1H=TMR1L=CAPi=CAPj=0; //如未完成连续3次检测(6次捕获)则继续(TMR1和相关变量清零)
}
CCP1IF=0; //软件清0中断标志位
}
}
//------------------------------------------------------------------
// 主程序
//------------------------------------------------------------------
void main()
{
ADCON1=0x06; //关闭模拟端口
TRISC5=1; //按键输入
TRISC2=1; //CCP1输入
TRISB=PORTB=0X00; //数码管显示端口输出
TRISD=PORTD=0X00;
CCP1CON=0X05; //设置CCP1捕捉模式,捕捉上升沿
CCP1IF=0; //清除CCP1中断标志
TMR1ON=0; //TMR1停止
while(1)
{
if(Key_DOWN()) //按键判断
{
__delay_ms(10); //延时消抖
if(Key_DOWN()) //确认按下,开始检测频率
{
PORTB=0X00; //关闭共阴极数码管段码(黑屏)
Disp_ON=0; //禁止显示
CCP1IE=0; //使能CCP1捕获中断
TMR1ON=1; //启动TMR1中断计数
PEIE=1; //使能外设中断
GIE=1; //开中断
}
}
Show_FRQ_ON_DSY(); //数码管刷新显示频率
}
}
此帖出自
小平头技术问答
一周热门 更多>