微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

脉冲宽度使用 pic 18f4550

如何解决脉冲宽度使用 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,"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,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 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。