嗨,伙计们,我一直在研究一个计时器(TMR3)用来测量两个外部中断之间的时间的项目。另一计时器(TMR1)用于计数是否发生过溢出。第一个中断启动计时器,第二个中断关闭它,并调用一些后续计算的函数。然后在LCD.PIC18F26K40@ 64 MHz内部振荡器上显示,TMR3和TMR1没有前置或后置刻度。TMR3与FCYC同步,TMR1在TMR3OUT位上触发。目前,我在LCD上同时显示定时器值和计算值。我也有外部中断设置示波器,以准确地测量它们之间的时间。在Excel中,我把时间从范围内乘以FCYC(16MIPS)。我现在的问题是主计时器TMR3中的随机计数错误。我在TMR寄存器中平均得到1783个(额外的)“蜱”,但是它在整个地方(见附加的JPEG)。这在计算中造成很大的误差。如果它是一致的,那么我可以在计算中减去这个平均值。下面是代码的相关部分:VooStudioLa初始化(空隙){//NOSC HFIFToSC;NDIV 1;OSCCON1= 0x60;//CSWHOOD可以进行;SOSCPWR Low功率;OSCCON3= 0x00;//MFOEN禁用;LFOEN禁用;ADOEN禁用;OsChanq=0x00;//HFFRQ 64×MHz;OSCFRQ= 0x08;/OsTun= 0x00;}空TMR3-初始化(空隙){T3CONC:0x00;/CKPs 1:1;NT3Syc同步;TMR3ON关闭;T3RD16启用;T3GCON=0x00;//T3GE禁用;T3GTM禁用;T3GPOL低;T3GGO完成;T3GSPM禁用;T3GATE=0x00;/GSS T3GPIN;T3Clk=0x01;//CS FoC/4;TMR3H=0x00;/TMR3H 0;TMR3L= 0x00;/TMR3L 0;
time3ReLoad=(UTI1616T)((TMR3H和LT;和8;)8)TMR3L;/ /加载TMR值以重新加载可变的PIR4BITS。TMR3IF=0;/ /在启用中断之前清除标志。空隙TMR3IE=1;//允许TMRC1初始化(空隙){T1CONC:0x09;/NK1SIMC同步;TMR1ON关闭;T1RD16启用;T1GCON=0x40;//0Xe0;/T1GE启用;T1GPOL高;T1GGO完成;T1GSPM禁用;T1GATE=0x04;//TMR3溢出//GSS TMR0A溢出T1Clk=0xA;//TMR 3溢出//CS TMR0a溢出;TMR1H=0x00;TMR1L= 0x00;Time1ReLoVADAL=(UTI1616T)((TMR1H和LT;和8;)TMR1L);/ /加载TMR值以重新加载可变的PIR4BITS。TMR1IF=0;/ /在启用中断之前清除标志。PIE4BIT.TMR1IE=1;//启用TMR1中断。TMR1-启动时间();/启动TMR1}空隙中断高优先级ISRY高(空隙){if(Pr0BIT.In0&I&Apple;Pix0Bix.In0IE=1)/ /检查第一个波束是否已被破坏{PiR0BIT.In0IF=0;/ /切换标志TMR1H=0x00;/ /重置所有定时器寄存器TMR1L= 0x00;TMR3H=0x00;TMR3L= 0x00,TMR3ON=1;//打开Time//T1CONTITS。TMR1ON=1;//打开溢出计数器LATABIT.LATA5=0;//打开BNC };(PIR0BIT.I.1&IF;PAN01I.= 1){PIR0BIT.It1IF=0;/ /切换标志T3CONTIT.TMR3ON=0;/ /关闭定时器//T1CONTIT.TMR1ON= 0;//关闭溢出计数器LATABIT.LATA5=1;//关闭BNC速度(;);空隙中断低优先级IsRyLoad(空隙){if(Pir4BIT.TMR3IF=1)//TMR3中断服务例程{PIR4BITS.TMR3IF=0;TMR3H=0x00;TMR3L= 0x00;}(PiR4BIT.TMR1IF=1)//TMR1中断服务路由器Ne{PiR4BITS.TMR1IF=0;TMR1H=0x00;TMR1L= 0x00;}
以上来自于百度翻译
以下为原文
Hi guys,
I have been working on a project where a Timer (TMR3) is used to measure the time between two external interrupts. Another timer (TMR1) is used to count if any overflows have occurred. The first interrupt starts the timer, the second turns it off and calls a function for some subsequent calculations. Then it is displayed on an LCD.
PIC18F26K40 @64MHz Internal Oscillator, TMR3 and TMR1 have no pre- or post-scale. TMR3 is sync'd to FCYC and TMR1 is triggered on the TMR3OUT bit.
Currently I am displaying both timer values and the calculated value on the LCD. I also have the external interrupts set up to an oscilloscope to accurately measure the time between them. In Excel I have taken the time from the scope and multiplied by FCYC (16MIPS).
The problem I have at the moment is random count errors in the main timer, TMR3. I am getting an average of 1,783 more (extra) "ticks" in the TMR registers but its all over the place (see attached JPEG). This is causing significant error in the calculation. If it were consistent, I could subtract this average in the calculation.
Here are the relevant segments of code:
void OSCILLATOR_Initialize(void)
{
// NOSC HFINTOSC; NDIV 1;
OSCCON1 = 0x60;
// CSWHOLD may proceed; SOSCPWR Low power;
OSCCON3 = 0x00;
// MFOEN disabled; LFOEN disabled; ADOEN disabled; SOSCEN disabled; EXTOEN disabled; HFOEN disabled;
OSCEN = 0x00;
// HFFRQ 64_MHz;
OSCFRQ = 0x08;
// TUN 0;
OSCTUNE = 0x00;
}
void TMR3_Initialize(void)
{
T3CON = 0x00; //CKPS 1:1; nT3SYNC synchronize; TMR3ON off; T3RD16 enabled;
T3GCON = 0x00; //T3GE disabled; T3GTM disabled; T3GPOL low; T3GGO done; T3GSPM disabled;
T3GATE = 0x00; //GSS T3G_pin;
T3CLK = 0x01; //CS FOSC/4;
TMR3H = 0x00; //TMR3H 0;
TMR3L = 0x00; //TMR3L 0;
timer3ReloadVal=(uint16_t)((TMR3H << 8) | TMR3L); // Load the TMR value to reload variable
PIR4bits.TMR3IF = 0; // Clearing IF flag before enabling the interrupt.
PIE4bits.TMR3IE = 1; // Enable TMR3 interrupt.
}
void TMR1_Initialize(void)
{
T1CON = 0x09; //CKPS 1:1; nT1SYNC synchronize; TMR1ON off; T1RD16 enabled;
T1GCON = 0x40; //0xE0; //T1GE enabled; T1GTM enabled; T1GPOL high; T1GGO done; T1GSPM disabled;
T1GATE = 0x04; // tmr3 overflow //GSS TMR0_Overflow;
T1CLK = 0xA; //tmr 3 overflow //CS TMR0_Overflow;
TMR1H = 0x00;
TMR1L = 0x00;
timer1ReloadVal=(uint16_t)((TMR1H << 8) | TMR1L); // Load the TMR value to reload variable
PIR4bits.TMR1IF = 0; // Clearing IF flag before enabling the interrupt.
PIE4bits.TMR1IE = 1; // Enable TMR1 interrupt.
TMR1_StartTimer(); // Start TMR1
}
void interrupt high_priority ISR_high(void)
{
if (PIR0bits.INT0IF && PIE0bits.INT0IE == 1) //Check if the first beam has been broken
{
PIR0bits.INT0IF = 0; //Toggle the Flag
TMR1H = 0x00; //RESET all TIMER registers
TMR1L = 0x00;
TMR3H = 0x00;
TMR3L = 0x00;
T3CONbits.TMR3ON = 1; //Turn on the Timer
//T1CONbits.TMR1ON = 1; //Turn on the Overflow Counter
LATAbits.LATA5 = 0; //TURN ON BNC
}
if (PIR0bits.INT1IF && PIE0bits.INT1IE == 1)
{
PIR0bits.INT1IF = 0; //Toggle the Flag
T3CONbits.TMR3ON = 0; //Turn off the Timer
//T1CONbits.TMR1ON = 0; //Turn off Overflow counter
LATAbits.LATA5 = 1; //TURN OFF BNC
Velocity();
}
}
void interrupt low_priority ISR_low(void)
{
if (PIR4bits.TMR3IF == 1) //TMR3 Interrupt Service Routine
{
PIR4bits.TMR3IF = 0;
TMR3H = 0x00;
TMR3L = 0x00;
}
if (PIR4bits.TMR1IF == 1) //TMR1 Interrupt Service Routine
{
PIR4bits.TMR1IF = 0;
TMR1H = 0x00;
TMR1L = 0x00;
}
}
Attached Image(s)
0