0

我正在使用 MPLAB 对 PIC 套件 14f458 执行操作。

现在我想创建一个代码,使用按钮通过微控制器传递不同数量的电压电源 LED。第一次按下按钮时,我应该得到 10% DC 的波形,第二次和第三次分别为 50% 和 95%。

我已经解决了这个问题,但仍然将 RE2 PORT 的值设为 0 而不是 1。而且我也不知道在释放按钮时如何停止计时器。

我的代码如下:

#include<stdio.h>                       //Standard I/O Library
#include<p18cxxx.h>                     //for TRISA,E and PORTA,E declaration
#pragma config WDT = OFF                //watchdog counter
#pragma config OSC = HS, OSCS = OFF
#pragma config PWRT = OFF, BOR = ON, BORV = 45
#pragma config DEBUG = OFF, LVP = OFF, STVR = OFF

void timer_10()
{
    CCP1CON = 0;
    PR2 = 249;
    CCPR1L = 24;
    TRISCbits.TRISC2 = 0;
    T2CON = 0x00;
    CCP1CON = 0x3c;
    TMR2 = 0;
    T2CONbits.TMR2ON = 1;
    while(1)
    {
        PIR1bits.TMR2IF = 0;
        while(PIR1bits.TMR2IF == 0);
    }
}

void timer_50()
{
    CCP1CON = 0;
    PR2 = 249;
    CCPR1L = 124;
    TRISCbits.TRISC2 = 0;
    T2CON = 0x00;
    CCP1CON = 0x2c;
    TMR2 = 0;
    T2CONbits.TMR2ON = 1;
    while(1)
    {
        PIR1bits.TMR2IF = 0;
        while(PIR1bits.TMR2IF == 0);
    }
}

void timer_95()
{
    CCP1CON = 0;
    PR2 = 249;
    CCPR1L = 236;
    TRISCbits.TRISC2 = 0;
    T2CON = 0x00;
    CCP1CON = 0x2c;
    TMR2 = 0;
    T2CONbits.TMR2ON = 1;
    while(1)
    {
        PIR1bits.TMR2IF = 0;
        while(PIR1bits.TMR2IF == 0);
    }
}

void main()
{
    int i = 1;
    ADCON1 = 0x06;                      //Sets RA0 to digital mode
    CMCON = 0x07;
    TRISEbits.TRISE2 = 1;               //set E2 PORTE pins as input
    PORTEbits.RE2 = 1;                  //Here I am not able to SET Value 1

    while(1)
    {
        while(PORTEbits.RE2 == 0)
        {
            switch(i)
            {
                case 1:
                    timer_10();
                    break;
                case 2:
                    timer_50();
                    break;
                case 3:
                    timer_95();
                    break;
            }
            if(i<4)
            {
                i++;
                if(i>=4)
                {
                    i=1;
                }
            }
        }
    }
}

我的编译器卡在函数 timer_10() 中。请帮我。

4

2 回答 2

0

这对于评论来说有点太长了,我认为您可能能够自己找到答案 - 但是,我会给您一些指示。

在主()

TRISEbits.TRISE2 = 1;               //set E2 PORTE pins as input
PORTEbits.RE2 = 1;                  //Here I am not able to SET Value 1

在将 E2 配置为输入后写入端口 E2 时,您期望什么行为?它在PIC18F458 数据手册中进行了描述,特别是第 9.5 节

在 timer_10()

void timer_10()
{
    CCP1CON = 0;
    PR2 = 249;
    CCPR1L = 24;
    TRISCbits.TRISC2 = 0;
    T2CON = 0x00;
    CCP1CON = 0x3c;
    TMR2 = 0;
    T2CONbits.TMR2ON = 1;
    while(1)
    {
        PIR1bits.TMR2IF = 0;
        while(PIR1bits.TMR2IF == 0);
    }
}

你说你的编译器卡住了,但我假设你的意思是调试器,因为你能够运行main()观察PORTEbits.RE2 = 1;没有按照你的预期做。如果您在调试器中单步执行此操作,它会卡在哪里?你能明白为什么吗?

于 2018-03-18T09:47:14.380 回答
0

好的,让我们稍微简化一下。如果您希望占空比在按钮的下降沿改变,并且您不想使用中断,那么您需要重组您拥有的内容。首先,timer_x 例程有几个问题: 1) 你不需要 while 循环,这就是你被卡住的原因。2)如果您删除该循环,您将不断调用一个计时器例程,该例程将重置寄存器值,您将不会得到您期望的结果。此外,由于您没有使用中断,谁在乎是否设置了溢出标志,只需保持设置即可。要解决此问题,首先,删除所有 timer_x 例程。接下来,您需要一个定时器程序来读取开关输入。请记住,所有开关都有开关弹跳,因此读取一个值是不可靠的。你要么需要慢慢阅读开关,以大于开关弹跳(约 50 毫秒)的速度运行您的例程,如果您连续有两个相同的读数,或者您可以更快地读取它,但您需要更多相同的读数才能了解您有一个稳定的值。从那里,您只能在第一个下降沿增加“i”,而不是一直按住开关(除非您想要那样)。你的主程序应该看起来像(原谅定时器寄存器的快捷方式):

Main()
if (tmr2.overflow)     // 50ms switch read timer
{
  switchCurrent = PORTE2;
}
if (   (switchCurrent == swtichLast)    // Two readings of the same value
    && (!switchCurrent)                 // and switch is pressed
    && (!switchUpdated)  )              // and haven't updated the pwm yet
{
      switchUpdated = TRUE;             // Only allow one update per switch 
      i++;
      if (i > 4)
      {
          i = 0;
      }
      switch (i)
      {
         case 0:
             CCPR1L = 24;
             break;
         case 1:
             CCPR1L = 124;
             break;
        ... and so on.  Note, the only difference in each case is CCPR1L, so just rewrite that register instead of resetting everything.
}
switchLast = swtichCurrent;
if (swtichCurrent)
    switchUpdated = 0

这应该给你一个起点,希望它有帮助

于 2018-03-24T19:10:10.287 回答