【问题标题】:time between two edges pic 18f4550两条边之间的时间 pic 18f4550
【发布时间】:2021-07-18 02:42:02
【问题描述】:

我想使用图片 18f4550 中的两个 CCP 模块计算两个不同信号的两个上升沿之间的时间间隔。 计算思路如下图所示。

模拟工作正常,但我的电路不是。我不知道我的代码是否有问题。如果有人有解决此问题的答案或线索,我将不胜感激!如果您有任何问题,请随时提出。

#pragma config FOSC = INTOSC_EC
#define _XTAL_FREQ 8000000

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "LCD_8bit_file.h"
#include <string.h>

unsigned long comtage, capt0, x;
char DEPHASAGE[20];
char pulse[20];
float period, dephTempo, deph, phi;

void main()
{
    IRCF0 = 1;     /* set internal clock to 8MHz */
    IRCF1 = 1;
    IRCF2 = 1;  
    
    LCD_Init();
    
    LCD_String_xy(0, 1, "Dephasage[rad]"); 
 
    T3CONbits.RD16 = 1;  
    T3CKPS0 = 0;
    T3CKPS1 = 0;
    TMR3CS = 0;
    
    TMR3IF = 0; 
      
    while (1)        
    {    
        CCP2CON         = 0b00000101;
        CCP1CON         = 0b00000101;
        PIR2bits.CCP2IF = 0;
        PIR1bits.CCP1IF = 0;
        TMR3ON          = 0; 
        TMR3            = 0;

        if (PIR1bits.CCP1IF == 1) {
            TMR3ON          = 1; 
    
            while (!PIR2bits.CCP2IF); 
            comtage = TMR3; 
            dephTempo = (((float)comtage / 30.518) / 65536); 
    
            sprintf(pulse,"%.3f  ", dephTempo);
            LCD_String_xy(0, 0, "Dephasage : ");
            LCD_String_xy(2, 9, pulse);
        }
    }
}                              

【问题讨论】:

  • edit您的问题并告诉我们什么不起作用。

标签: c microcontroller pic microchip pulse


【解决方案1】:

当您使用实际电路测试原理图时,会出现其他问题,例如电容性和电阻性寄生效应,并且会在计时之后出现。此外,可能有抖动噪声。如果您有示波器,请尝试确定是否有太多噪音。尝试在这些线上添加下拉/上拉,确保您有良好的接地连接。但是在找到你的代码之后,你应该采取类似于 CTC 的方法:你对输入信号进行快速采样,然后检查你的采样数组,如果有多个 1 多于 0,你就捕获了边沿触发。

【讨论】:

    【解决方案2】:

    我有一个更好的方案供您的应用程序实施。但首先让我们谈谈代码中的不良做法。

    1. 在您的主 while 循环中设置 CCP 模块:

      CCP2CON         = 0b00000101;
      CCP1CON         = 0b00000101;
      PIR2bits.CCP2IF = 0;
      PIR1bits.CCP1IF = 0;
      TMR3ON          = 0; 
      TMR3            = 0;
      

      你最好在程序进入无限while循环之前这样做。

    2. 您直接处理定时器读取,而 CCP 模块捕获您配置它捕获的边沿的值。

      comtage = TMR3;
      
    3. 我没有看到您将 CCP 引脚配置为输入。您必须通过设置相应的 TRIS 位将它们配置为输入,以使它们正常工作。

    所以我推荐的场景的结构是这样的:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include "LCD_8bit_file.h"
    #include <string.h>
    
    unsigned long comtage, capt0, x;
    char DEPHASAGE[20];
    char pulse[20];
    float period, dephTempo, deph, phi;
    
    
    /******************** Utility funcs ********************/
    void setupSysClock() {
        IRCF0 = 1;     /* set internal clock to 8MHz */
        IRCF1 = 1;
        IRCF2 = 1;
    }
    
    void setupCCP1withTMR1() {
        CCP1CON         = 0b00000101;
        PIR1bits.CCP1IF = 0;
        TRISCbits.TRISC2 = 1; // set CCP1 pin as input
    }
    
    void setupCCP2withTMR3() {
        CCP2CON         = 0b00000101;
        PIR2bits.CCP2IF = 0;
        
        // T3 goes for CCP2 and CCP1, PS 1:1, internal CS
        T3CON = (1 << T3CCP2) | (0 << T3CKPS1) | (0 << T3CKPS0) | (1 << T3CCP1) | (0 << TMR3CS);
        TMR3 = 0;
        
        // In config bits you must choose RC1 pin for the CCP2 if necessary although it so by default
        TRISCbits.TRISC1 = 1 // set CCP2 pin as input
    }
    
    void rearm() {
        CCP1CON = 0x5
        CCP2CON = 0x5
        PIR1bits.CCP1IF = 0;
        PIR2bits.CCP2IF = 0;
        TMR3 = 0;
        TMR3ON = 1;
    }
    
    void suspend() {
        CCP1CON = 0;
        CCP2CON = 0;
    }
    
    
    void main()
    {
        setupSysClock(); // setu internal clock
        
        setupCCP1withTMR1(); // setup CCP1 for capture mode 
        
        setupCCP2withTMR3(); // setup CCP1 for capture mode with TMR3
        
        LCD_Init();
        
        LCD_String_xy(0, 1, "Dephasage[rad]"); 
     
        
        while (1)        
        {   
            while(!CCP2IF); // Wait for the second rising edge
            // Event has occured process, first make sure that the CCP1 rised first
            if(!CCP1F) {
                // An invalid sequence occured ignore and rearm. Note that the sequence of signals is important.
                rearm();
                continue;
            }
            /* The sequence is correct let's process the event. Here you will have
            two captured value in CCPR1 and CCPR2 registers. First one is the captured value of the T3 when the first rising event occured. Second one is the captured value of the T3 when the second rising event occured. You have to get the delta of the two captured values first. This delta value is the elapsed ticks between the two discrete rising input signals. This is what the capture hardware is made for ;)
            Now first we shuld suspend the CCP modules to avoid unwanted captures
            while we process the previous value. Because if another capture occures
            before we process the previous value, the new capture value will be
            overwritten over the old value that we need for computation.
            */
            suspend(); // suspend the CCP modules while processing
            uint16_t timeDelta = CCPR2 - CCPR1; // Calculate the difference
            
            dephTempo = (((float)timeDelta / 30.518) / 65536); 
    
            sprintf(pulse,"%.3f  ", dephTempo);
            LCD_String_xy(0, 0, "Dephasage : ");
            LCD_String_xy(2, 9, pulse);
            
            // Now that we finished processing we can rearm the CCP for new captures
            rearm();
        }
    }                              
    

    我在编辑器中编写了这段代码,并没有在 MPLAB 中编译。所以你必须编译和测试代码。您可以给我反馈,让我进一步提供帮助。

    需要注意的重要一点:如果两个信号之间的时间量很大,则必须增加 Timer3 的预分频器,或者必须为 TMR3 寄存器使用互补变量以防溢出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-13
      • 2015-01-10
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      相关资源
      最近更新 更多