脉冲宽度使用 pic 18f4550

pulse width using pic 18f4550

我想在捕获模式下仅使用一个 CCP 模型和 pic 18f4550 来测量脉冲持续时间,所以我尝试在第一时间检测上升沿,当检测到上升沿时,timer1 打开并进入捕获模式更改为下降沿,用这种方法我必须测量脉冲宽度,但我使用的代码效果不佳! 当我使用两个 CCP 模型时,这很好。 如果有人能提供帮助,我将不胜感激。

#include <stdio.h>
#include <stdlib.h>

#include "osc_config.h"
#include "LCD_8bit_file.h"
#include <string.h>



void main()
{
    unsigned long comtage;
    unsigned long DEPHASAGE[20];
    float Deph_tempo;
    
    TRISCbits.TRISC2=1;
   
    
    IRCF0=1;     
    IRCF1=1;
    IRCF2=1;  
    
    LCD_Init();
    
    LCD_String_xy(0,0,"Deph.tempo"); 
 
    PIE1bits.CCP1IE=1;
    PIR1bits.CCP1IF=0; 
    
    
    CCP1CON=0b00000101; 
    CCPR1=0;        
    
    T1CONbits.RD16=1;
    T1CKPS0=0;
    T1CKPS1=0;
    TMR1CS=0;
    
    TMR1IF=0; 
    TMR1=0; 
        
        
    while(1)        
    {    
        
     
       if(PIR1bits.CCP1IF==1){ 
        
        TMR1ON=1; 
        PIR1bits.CCP1IF=0;
        
        CCP1CON=0b00000100;
        
        while(!(PIR1bits.CCP1IF==1)) 
            
         comtage= TMR1; 
         PIR1bits.CCP1IF=0;
         
           Deph_tempo = (((float)comtage /30.518)/65536 ); 
            sprintf(DEPHASAGE,"%.5f  ",Deph_tempo); 

            LCD_String_xy(2,0,DEPHASAGE);
            
       }
         
        TMR1=0;
        TMR1ON=0; 
        CCP1CON=0b00000101;
    }                              
}

减少等待 CCP1IF 时执行的指令数将提高精度。你试过这个吗?

// ...

while (1)        
{    
    CCP1CON         = 0b00000101;
    PIR1bits.CCP1IF = 0;
    TMR1ON          = 0; 
    TMR1            = 0;

    // if your comms with the LCD use interrupts:
    //
    // disable interrupts here 

    while (!PIR1bits.CCP1IF)
        ;

    TMR1ON          = 1; 
    CCP1CON         = 0b00000100;
    PIR1bits.CCP1IF = 0;
    
    while (!PIR1bits.CCP1IF)
       ; 

    compte = TMR1; 
    
    // if your comms with the LCD use interrupts:
    //
    // enable interrupts here 

    // refresh display

    // if your comms with the LCD use interrupts:
    //
    // you may want to add a small delay here, to
    // allow for comms to the LCD to end.
    // this may not be necessary, depending on the
    // signal frequency. 
}

// ...

如果这不起作用,您应该检查 LCD 是否没有使用中断。

如果是,你应该:

  • 读取样本前禁用中断
  • 计时时保持中断禁用
  • 在更新显示之前启用中断
  • 在进行下一次采样之前添加一个延迟,延迟应该足够长,以便 LCD 缓冲区清空。

这是不使用中断的解决方案...我认为使用引脚更改中断和免费 运行 计时器会获得更好的结果。

编辑:编写此解决方案后,我在您的代码中发现了这些代码行周围的错误:

    while(!(PIR1bits.CCP1IF==1))   // this is missing a ;
        
     comtage= TMR1;                // this line gets executed in the loop
                                   // and adds instructions to the 
                                   // loop, this probably more than                     
                                   // halves the precision of your 
                                   // results.

                                   // the imprecision is increased with
                                   // your code that runs after the if block