脉冲宽度使用 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
我想在捕获模式下仅使用一个 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