CCP1中断读取CCPR1H:CCPR1L,但是读出的总是随机数

[复制链接]
5630|12
 楼主| hahahaluo 发表于 2007-12-25 10:07 | 显示全部楼层 |阅读模式
CCP1引脚输入1KHZ的方波,我用示波器看过,已经进入CCP1中断,但是中断中读取CCPR1H:CCPR1L,但是读出的总是随机数,给位帮我看看是什么问题,<br /><br />1.上电,运行,几分钟都是CCPR1H=0xF0,CCPR1L=0xC0,<br /><br />2.断电,电容放电,上电,运行,几分钟都是CCPR1H=0xCA,CCPR1L=0x56,<br /><br />3.PIC程序清除,断电,电容放电,上电,运行,几分钟都是CCPR1H=0xDF,CCPR1L=0xFF,<br /><br />4......<br /><br />#include&nbsp;&ltp18f2480.h&gt&nbsp;<br /><br /><br />unsigned&nbsp;char&nbsp;cap_high;<br />unsigned&nbsp;char&nbsp;cap_low;<br /><br /><br />void&nbsp;VectorHigh&nbsp;(void);<br />void&nbsp;HandlerHigh&nbsp;(void);<br /><br />#pragma&nbsp;code&nbsp;VectorHigh&nbsp;=&nbsp;0x08<br />void&nbsp;VectorHigh&nbsp;(void)<br />{<br />&nbsp;&nbsp;_asm<br />&nbsp;&nbsp;&nbsp;&nbsp;goto&nbsp;HandlerHigh&nbsp;//jump&nbsp;to&nbsp;interrupt&nbsp;routine<br />&nbsp;&nbsp;_endasm<br />}<br />#pragma&nbsp;code<br /><br />#pragma&nbsp;interrupt&nbsp;HandlerHigh<br />void&nbsp;HandlerHigh&nbsp;()<br />{<br />//CCP1中断----------------------------------<br /><br />&nbsp;if(PIR1bits.CCP1IF)&nbsp;&nbsp;<br />&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;PIR1bits.CCP1IF&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//一定要在中断里面赋值<br />&nbsp;cap_low=CCPR1L;<br />&nbsp;cap_high=CCPR1H;<br /><br />&nbsp;CCPR1H=0;<br />&nbsp;CCPR1L=0;<br />&nbsp;}<br /><br />}<br />#pragma&nbsp;code<br /><br />void&nbsp;main()&nbsp;<br />{&nbsp;<br />TRISCbits.TRISC2=&nbsp;1;&nbsp;//设定RC2为输入<br /><br />CCP1CON&nbsp;=&nbsp;0x04;//CCP1下降沿捕捉模式<br /><br />T3CON&nbsp;=&nbsp;0;<br /><br />CCPR1H=0;<br />CCPR1L=0;<br /><br />PIE1bits.CCP1IE=1;//CCP1中断打开<br />PIR1bits.CCP1IF=0;//CCP1溢出标志<br />IPR1bits.CCP1IP&nbsp;=&nbsp;1;//CCP1溢出中断优先级为高中断<br /><br />T1CON&nbsp;=&nbsp;0x00;//关闭定时器1<br /><br />PIE1bits.TMR1IE=1;//定时器1中断打开<br />PIR1bits.TMR1IF=0;//定时器1溢出标志<br />IPR1bits.TMR1IP&nbsp;=&nbsp;1;//定时器1溢出中断优先级为高中断<br /><br />INTCONbits.GIE&nbsp;=&nbsp;1;//全局中断打开<br />INTCONbits.PEIE=1;//外围设备中断打开<br /><br />for(;;);<br />}&nbsp;<br /><br /><br />帮帮我吧,崩溃了<br />
systemchip 发表于 2007-12-25 15:41 | 显示全部楼层

定时器都没开,怎么工作?

  
 楼主| hahahaluo 发表于 2007-12-25 16:34 | 显示全部楼层

我又试了下,好像不是这个原因

#include&nbsp;&ltp18f2480.h&gt&nbsp;<br /><br />unsigned&nbsp;char&nbsp;cap_high;<br />unsigned&nbsp;char&nbsp;cap_low;<br /><br />void&nbsp;VectorHigh&nbsp;(void);<br />void&nbsp;HandlerHigh&nbsp;(void);<br /><br />#pragma&nbsp;code&nbsp;VectorHigh&nbsp;=&nbsp;0x08<br />void&nbsp;VectorHigh&nbsp;(void)<br />{<br />&nbsp;&nbsp;_asm<br />&nbsp;&nbsp;&nbsp;&nbsp;goto&nbsp;HandlerHigh&nbsp;//jump&nbsp;to&nbsp;interrupt&nbsp;routine<br />&nbsp;&nbsp;_endasm<br />}<br />#pragma&nbsp;code<br /><br />#pragma&nbsp;interrupt&nbsp;HandlerHigh<br />void&nbsp;HandlerHigh&nbsp;()<br />{<br />//CCP1中断----------------------------------<br /><br />&nbsp;if(PIR1bits.CCP1IF)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;PIR1bits.CCP1IF&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//一定要在中断里面赋值<br />&nbsp;&nbsp;&nbsp;&nbsp;cap_low=CCPR1L;<br />&nbsp;&nbsp;&nbsp;&nbsp;cap_high=CCPR1H;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;CCPR1H=0;<br />&nbsp;&nbsp;&nbsp;&nbsp;CCPR1L=0;<br />&nbsp;&nbsp;&nbsp;&nbsp;LATBbits.LATB1&nbsp;=&nbsp;!LATBbits.LATB1;//后加的,判断是否进入中断<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />}<br />#pragma&nbsp;code<br /><br />void&nbsp;main()&nbsp;<br />{&nbsp;<br />TRISCbits.TRISC2=&nbsp;1;&nbsp;//设定RC2为输入<br /><br />TRISB&nbsp;=&nbsp;0;//后加的,定义PB.0-.7口作输出<br /><br />CCP1CON&nbsp;=&nbsp;0x04;//CCP1下降沿捕捉模式<br /><br />T3CON&nbsp;=&nbsp;0x01;//无论T3CON=0x00还是0x01,都进入中断,结果一样<br /><br />CCPR1H=0;<br />CCPR1L=0;<br /><br />PIE1bits.CCP1IE=1;//CCP1中断打开<br />PIR1bits.CCP1IF=0;//CCP1溢出标志<br />IPR1bits.CCP1IP&nbsp;=&nbsp;1;//CCP1溢出中断优先级为高中断<br /><br />T1CON&nbsp;=&nbsp;0x01;//无论T1CON=0x00还是0x01,都进入中断,结果一样<br /><br />PIE1bits.TMR1IE=0;//定时器1中断打开<br />PIR1bits.TMR1IF=0;//定时器1溢出标志<br />IPR1bits.TMR1IP&nbsp;=&nbsp;1;//定时器1溢出中断优先级为高中断<br /><br />INTCONbits.GIE&nbsp;=&nbsp;1;//全局中断打开<br />INTCONbits.PEIE=1;//外围设备中断打开<br /><br />for(;;);<br />}&nbsp;<br /><br />看到楼上回复,我又用示波器测了下,结果还是一样<br /><br />
systemchip 发表于 2007-12-25 23:16 | 显示全部楼层

:

捕捉时间发生后,其并不会复位计数器,所以从相邻两个计数结果差异就可以得到两次捕捉时间的间隔。。。。。
兰天白云 发表于 2007-12-26 08:25 | 显示全部楼层

LS正解

  
 楼主| hahahaluo 发表于 2007-12-26 09:33 | 显示全部楼层

得到的结果是CCPR1= 0x4e44

void&nbsp;HandlerHigh&nbsp;()<br />{<br />//CCP1中断----------------------------------<br /><br />if(PIR1bits.CCP1IF)&nbsp;&nbsp;<br />{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;PIR1bits.CCP1IF&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//一定要在中断里面赋值<br />cap_low=CCPR1L-cap_low;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//差值<br />cap_high=CCPR1H-cap_high;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//差值<br /><br />}<br /><br />}<br /><br />修改了下中断,如果不发生溢出,cap_high、cap_low的值应该接近,<br /><br />icd2不能实时跟踪CCPR1,所以我在main()中加入串口发送4次/秒,<br />不占用中断波特率115200,看cap_high、cap_low的值,每次都是4e&nbsp;44<br /><br />再问下下,被捕捉信号1KHZ(PIC晶振4M),差值应该是03e8,对不对??
 楼主| hahahaluo 发表于 2007-12-26 09:50 | 显示全部楼层

感觉自己找问题的方向不对,版主有没有好的建议

1.上电,运行,几分钟都是CCPR1H=0x4e,CCPR1L=0x44,<br /><br />2.断电,换新的芯片,上电,运行,几分钟都是CCPR1H=0x84,CCPR1L=0x2c,<br /><br />3.PIC程序清除,断电,电容放电,上电,运行,几分钟都是CCPR1H=0x84,CCPR1L=0x2c,<br /><br />4......<br /><br />感觉自己找问题的方向不对,版主有没有好的建议<br /><br />谁有CCP1捕捉的例程,参考下,我手上只有16F87X的一个例子,希望有多点作参考
兰天白云 发表于 2007-12-26 11:20 | 显示全部楼层

考虑一下,打开/关闭CCP(在程序中)

  
 楼主| hahahaluo 发表于 2007-12-26 13:16 | 显示全部楼层

我找到原因了

正如systemchip所说,定时器开关有问题,不知道为什么<br /><br />过程:<br /><br />1.像上面程序配置好CCP1相关的寄存器,一定要打开两个中断使能和一个定时器开关<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PIE1bits.CCP1IE=1;//CCP1中断打开<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PIE1bits.TMR1IE=0;//定时器1中断打开<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T1CONbits.TMR1ON&nbsp;=&nbsp;1;//打开定时器1<br />否则,CCPR1读出值是随机的,或者根本就进不了中断<br /><br />2.中断程序<br />void&nbsp;HandlerHigh&nbsp;()<br />{<br />//CCP1中断----------------------------------<br />TMR1H=0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//定时器1一定要在中断里面清0<br />TMR1L=0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//进入中断先清0,保证计时精度<br /><br />if(PIR1bits.CCP1IF)&nbsp;&nbsp;<br />{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;PIR1bits.CCP1IF&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//一定要在中断里面赋值<br />&nbsp;&nbsp;&nbsp;&nbsp;cap_low=CCPR1L;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;cap_high=CCPR1H-;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />}<br /><br />}<br /><br />这两句一定要加:<br />TMR1H=0;<br />TMR1L=0;<br />否则读的是差值,而且程序跳不出中断(不知道为什么?)&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />3.使用定时器3,寄存器T3CON的T3ECCP1和T3CCP1一定要配置,资料上对18F2480说的不完整:只说2480没有这两个寄存器。<br />T3CONbits.T3ECCP1&nbsp;=&nbsp;1;//定时器3是CCP1的时钟源<br />T3CONbits.T3CCP1&nbsp;=&nbsp;0;//定时器3是CCP1的时钟源<br />如果不配置,CCP1中断能进入,但是CCPR1读出值是随机的<br /><br />终于搞出来,感觉自己还是细节上出错,否则不会这么久
systemchip 发表于 2007-12-26 15:15 | 显示全部楼层

:

2.中断程序<br />void&nbsp;HandlerHigh&nbsp;()<br />{<br />//CCP1中断----------------------------------<br />TMR1H=0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//定时器1一定要在中断里面清0<br />TMR1L=0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//进入中断先清0,保证计时精度<br /><br />if(PIR1bits.CCP1IF)&nbsp;&nbsp;<br />{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;PIR1bits.CCP1IF&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//一定要在中断里面赋值<br />&nbsp;&nbsp;&nbsp;&nbsp;cap_low=CCPR1L;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;cap_high=CCPR1H-;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />}<br /><br />}<br /><br />这两句一定要加:<br />TMR1H=0;<br />TMR1L=0;<br />否则读的是差值,而且程序跳不出中断(不知道为什么?)&nbsp;&nbsp;<br /><br /><br />---建议不要这样操作,因为这样会丢失计数器在中断延迟/现场保护期间的计数数据,因为你无法得知这段期间记数的数据(尤其是当你使用C语言编程时候,中断程序中将加入部分中断现场保护代码),这样会导致捕捉结果的误差,当然你可以人为的进行数据补偿。<br />&nbsp;&nbsp;&nbsp;另外如果这样操作的话,该Timer就不能做其他的记数/记时控制,造成资源的浪费。<br />&nbsp;&nbsp;&nbsp;所以还是建议你使用从相邻两个计数结果差异得到两次捕捉时间的间隔。<br />
systemchip 发表于 2007-12-26 15:38 | 显示全部楼层

void&nbsp;main()&nbsp;<br />{&nbsp;<br />TRISCbits.TRISC2=&nbsp;1;&nbsp;//设定RC2为输入<br />CCP1CON=0x00;<br />TMR1H=0x00;<br />TMR1L=0x00;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;clear&nbsp;Timer1&nbsp;Counter<br /><br />CCPR1H=0;<br />CCPR1L=0;<br /><br />T3CON&nbsp;=&nbsp;0x00;//Timer1&nbsp;for&nbsp;CCP<br /><br />CCP1CON&nbsp;=&nbsp;0x04;//CCP1下降沿捕捉模式<br /><br /><br />PIE1bits.CCP1IE=1;//CCP1中断打开<br />PIR1bits.CCP1IF=0;//CCP1溢出标志<br />IPR1bits.CCP1IP&nbsp;=&nbsp;1;//CCP1溢出中断优先级为高中断<br /><br />RCONbits.IPEN=1;<br />INTCONbits.GIE&nbsp;=&nbsp;1;//全局中断打开<br />INTCONbits.PEIE=1;//外围设备中断打开<br /><br /><br />T1CONbits.TMR1ON&nbsp;=1;//open&nbsp;Timer1<br /><br />while(1);<br />}&nbsp;<br />
 楼主| hahahaluo 发表于 2007-12-26 17:23 | 显示全部楼层

systemchip果然老道,知道我下步在想什么,这方法真好

void&nbsp;HandlerHigh&nbsp;()<br />{<br />//CCP1中断----------------------------------<br /><br />if(PIR1bits.CCP1IF)&nbsp;&nbsp;<br />{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;PIR1bits.CCP1IF&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//一定要在中断里面赋值<br />&nbsp;&nbsp;&nbsp;&nbsp;if(ccpnumber==0)cap=CCPR1;<br />&nbsp;&nbsp;&nbsp;&nbsp;if(ccpnumber==1)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;cap=CCPR1-cap;<br />&nbsp;&nbsp;&nbsp;&nbsp;cap_high=cap/0x0100;<br />&nbsp;&nbsp;&nbsp;&nbsp;cap_low=cap;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;ccpnumber++;<br />}<br /><br />}<br /><br />1KHZ捕捉,<br />第一种方法直接读,捕捉值03&nbsp;dd&nbsp;(左右),偏差大<br />第二种方法差值读,捕捉值03&nbsp;e8(偶尔有03&nbsp;e9)<br />估计把PIR1bits.CCP1IF&nbsp;=&nbsp;0;&nbsp;&nbsp;放到最后,出现03&nbsp;e9的次数会更少<br />
strangestar 发表于 2012-9-6 11:44 | 显示全部楼层
小弟也在写类似的应用程序,但是一开始是进不了中断,挣扎可很久,后来进去了却没法读取数据,不懂为什么,希望楼主帮帮忙。谢谢啦

//功能:实现捕捉完成频率测量功能
//具体设置:ccp1con=00000101上升沿捕捉;


#include<pic.h>
#include<math.h>
#define uchar unsigned char;
#define uint unsigned int;
void init();
void interrupt int_ccp();//中断
unsigned int hz;//频率
unsigned char n1,n2,n3,n4,n5;
void disp();//显示
void delay(int n);
unsigned int p,q,tm,count,flag=0;
const int table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

void main()
{
  init();
  while(1)
  {
    disp();//delay(1);
  }
}
void init()//初始化
{  
  TRISC=0;PORTC=0;
  TRISC2=1;TRISB=0;TRISD=0;
  TMR1L=0X00;
  TMR1H=0X00;
  CCPR1L=0;
  CCPR1H=0;
  CCP1CON=0B00000111;//16个采样一次
  PIR1=0;//标志位清零
  PIE1=0X05;//使能
  INTCON=0XC0;//总中断打开
  T1CON=0X01;
  //PORTC=0X01;

}
void interrupt int_ccp()
{
   GIE=0;
   if(TMR1IF==1)
     {
       TMR1IF=0;
       TMR1L=0;
       TMR1H=0;
       count++;
     }
   if(CCP1IF==1);
     {
       CCP1IF=0;
       flag=!flag;
       if(flag==1)
          {
            TMR1L=0;
            TMR1H=0;
            count=0;
            
          }
       else
          {
            PORTC=0X01;
            tm=CCPR1H<<8|CCPR1L;
            hz=(count*65534+tm)/4000000;
            hz=15/hz;
            
          }
     }
   TMR1ON=1;   
   GIE=1;  
}
void disp()
{
   n1=hz/10000;
    n2=hz%10000/1000;
    n3=hz%1000/100;
    n4=hz%100/10;
    n5=hz%10;
  PORTB=0xff;
  PORTD=table[n1];
  RB1=0;
  delay(5);
  PORTD=table[n2];
  RB1=1;
  RB2=0;
  delay(5);
  PORTD=table[n3];
  RB2=1;
  RB3=0;
  delay(5);
  PORTD=table[n4];
  RB3=1;
  RB4=0;
  delay(5);
  PORTD=table[n5];
  RB4=1;
  RB5=0;
  delay(5);
}
void delay(int n)
{
  uint p,q;
  for(p=n;p>0;p--)
  for(q=110;q>0;q--);
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

41

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部