我正在尝试开始一个使用PIC18F24J10的项目。试图为此使用SDCC。在这一点上,我已经将我的代码简化为简单地确定正在发生的事情,因为我已经看到奇怪的行为已经有一段时间了,直到我弄清楚正在发生什么,才能真正地继续下去。我不知道这是不是我目前唯一的问题,但我不知道为什么会这样。计时器中断触发,再加上#定义的循环导致PORTC上的LED每秒闪烁两次。如果我只做一个PORTC=0xFF和PORTC=0,这是很好的。但当我试图超越这一点的时候就会变得很奇怪。
...
#define _RC0 31
#define _RC1 32
#define _RC2 33
#define _RC3 34
#define _RC4 35
#define _RC5 36
#define _RC6 37
#define _RC7 38
#define HI 1
#define LO 0
void why(unsigned char p, int z)
{
if(z == HI)
{
if(p == _RC0) PORTCbits.RC0 = 1;
else if(p == _RC1) PORTCbits.RC1 = 1;
else if(p == _RC2) PORTCbits.RC2 = 1;
else if(p == _RC3) PORTCbits.RC3 = 1;
else if(p == _RC4) PORTCbits.RC4 = 1;
else if(p == _RC5) PORTCbits.RC5 = 1;
else if(p == _RC6) PORTCbits.RC6 = 1;
else if(p == _RC7) PORTCbits.RC7 = 1;
}
else if(z == LO)
{
PORTC = 0b11110000;
}
else
{
PORTC = 0b10101010;
}
}
void timer_isr (void) __interrupt(1) __using (1)
{
TMR0H=0;
TMR0L=0;
why(_RC0, LO);
why(_RC1, LO);
why(_RC2, LO);
WAIT_CYCLES(5000);
why(_RC0, HI);
why(_RC1, HI);
why(_RC2, HI);
WAIT_CYCLES(5000);
}
void main(void)
{
WDTCONbits.SWDTE = 0;
WDTCONbits.SWDTEN = 0;
TRISC = 0b00000000;
PORTC=0b00000000;
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
INTCONbits.TMR0IF = 0;
INTCONbits.TMR0IE = 1;
T0CONbits.T08BIT = 0;
T0CONbits.T0CS = 0;
T0CONbits.PSA = 1;
TMR0H = 0;
TMR0L = 0;
T0CONbits.TMR0ON = 1;
while(1)
{
}
}在上面的代码中,四个LED应该闪烁,而其他四个应该继续。相反,发光二极管停留在10101010模式,发生在“其他”块,这应该发生时,“为什么”被调用除了HI或LO以外的任何值。我从来没有用其他东西来称呼它,那么它为什么会达到这个程度呢?
UPDATE -进一步减少,不再有中断或未指定的包含/定义。这是整个程序,我仍然看到同样的行为。将模式从10101010改为10101011,这样我就可以验证芯片实际上是用新代码编程的,而且看起来是这样的。
#include "pic16/pic18f24j10.h"
#define WAIT_CYCLES(A) for(__delay_cycle = 0;__delay_cycle < A;__delay_cycle++)
int __delay_cycle;
#define HI 1
#define LO 0
void why(int z)
{
if(z == HI)
{
PORTC = 0b11111111;
}
else if(z == LO)
{
PORTC = 0b11110000;
}
else
{
PORTC = 0b10101011;
}
}
void main(void)
{
TRISC = 0b00000000;
PORTC=0b00000000;
while(1)
{
why(LO);
WAIT_CYCLES(5000);
why(HI);
WAIT_CYCLES(5000);
}
}发布于 2015-04-22 16:47:07
一旦中断被断言,它就不会被清除。这会导致重复调用timer_isr()。没有任何其他代码可以到达。必须通过中断服务例程在软件中清除TMR0IF位。
记住,你不仅需要在ISR上花费比计时器更少的时间--这是一个很好的做法,花费最少的时间。
删除延迟,只需切换一个标志或增加一个寄存器。在主while (1)循环中,监视标志或计数器,并从那里调用为什么()。
https://stackoverflow.com/questions/29785399
复制相似问题