无法在 MPLAB 中将值 1 设置为引脚作为输入
Not able to set value 1 to pin as Input in MPLAB
我正在使用 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() 中。请帮助我。
这对于评论来说有点太长了,我想你可能会自己找到答案 - 但是,我会给你一些建议。
在main()
TRISEbits.TRISE2 = 1; //set E2 PORTE pins as input
PORTEbits.RE2 = 1; //Here I am not able to SET Value 1
将 E2 配置为输入后写入端口 E2 时,您期望出现什么行为?它在 the PIC18F458 data sheet 中有描述,特别是第 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;
没有按照你的预期进行。如果你 single-step this 在调试器中运行,它会卡在什么地方?你能看出原因吗?
好的,让我们稍微简化一下。如果您希望占空比在按钮的下降沿发生变化,并且您不想使用中断,那么您需要重组现有的结构。首先,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
这应该给你一个起点,希望对你有所帮助
我正在使用 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() 中。请帮助我。
这对于评论来说有点太长了,我想你可能会自己找到答案 - 但是,我会给你一些建议。
在main()
TRISEbits.TRISE2 = 1; //set E2 PORTE pins as input
PORTEbits.RE2 = 1; //Here I am not able to SET Value 1
将 E2 配置为输入后写入端口 E2 时,您期望出现什么行为?它在 the PIC18F458 data sheet 中有描述,特别是第 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;
没有按照你的预期进行。如果你 single-step this 在调试器中运行,它会卡在什么地方?你能看出原因吗?
好的,让我们稍微简化一下。如果您希望占空比在按钮的下降沿发生变化,并且您不想使用中断,那么您需要重组现有的结构。首先,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
这应该给你一个起点,希望对你有所帮助