Chip Turns Off?
Posted: Fri Oct 10, 2008 6:12 pm
Hey, I'm having a weird problem with my firmware development. It seems that no matter what code I write, my chip will run it for a while and then suddenly shut down. The LEDs all turn off, and communication comes to a halt. I've tried multiple programs doing various tasks, and the result is always the same. Since switching from an 18f452 to an 18f258, the problem is even worse, and the chip lasts less than a minute before shutting down. I think it may have something to do with the interrupts (that's the only thing all of my programs have in common), but my ISRs are extremely short and so far as I know, I followed the code format given in the C18 guide. I'd appreciate any advice you can give me.
Here's my current code for perusal - it's just a function for the LED display on the HP-488 board. The display() function changes digits every few milliseconds to give the user a smooth four digit display on a 25% duty cycle.
#include "main.h"
unsigned char disp_high;
unsigned char disp_low;
volatile char tick;
unsigned char display_digit=1;
#pragma code high_vector=0x08
void high_interrupt (void)
{
_asm GOTO high_isr _endasm
}
#pragma code
#pragma interrupt high_isr
void high_isr (void){ //No high-priority interrupts have been defined yet, will be used for USART
}
#pragma code low_vector=0x18
void low_interrupt (void)
{
_asm GOTO low_isr _endasm
}
#pragma code
#pragma interruptlow low_isr
void low_isr (void)
{
if(INTCONbits.TMR0IF){ //The timer "ticks" at a regular interval of a few milliseconds, telling the display to move to the next digit
INTCONbits.TMR0IF = 0;
TMR0H = 0xB1;
TMR0L = 0xDF;
tick++;
}
}
void display(void){
unsigned char num;
switch(display_digit++){//Each digit on the display is synchronized with four bits (i.e. a number 0-F)
case 1: LATA = 0x08;
num=disp_low%16;
break;
case 2: LATA = 0x04;
num=disp_low/16;
break;
case 3: LATA = 0x02;
num=disp_high%16;
break;
case 4: LATA = 0x01;
num=disp_high/16;
display_digit=1;
break;
default: display_digit=1;
}
switch (num){ //nZero, etc., are the 8-bit definitions for each number, setting each segment either on or off
case 0: LATB = nZero;
break;
case 1: LATB = nOne;
break;
case 2: LATB = nTwo;
break;
case 3: LATB = nThree;
break;
case 4: LATB = nFour;
break;
case 5: LATB = nFive;
break;
case 6: LATB = nSix;
break;
case 7: LATB = nSeven;
break;
case 8: LATB = nEight;
break;
case 9: LATB = nNine;
break;
case 10: LATB = nTen_A;
break;
case 11: LATB = nEleven_B;
break;
case 12: LATB = nTwelve_C;
break;
case 13: LATB = nThirteen_D;
break;
case 14: LATB = nFourteen_E;
break;
case 15: LATB = nFifteen_F;
break;
default: LATB = 0xF;
}
}
void io_port_init(void){
TRISA = 0xF0; //Lower four bits of A are outputs to control LED display
LATA = 0x05;
TRISB = 0x00; //PORTB is all outputs
LATB = 0xFF;
TRISC = 0xFF; //PORTC is all inputs for now
LATC = 0x00;
}
void init(void){
disp_high=0xF1;
disp_low=0x0E;
io_port_init();
OpenTimer0 (TIMER_INT_ON & T0_SOURCE_INT & T0_16BIT & T0_PS_1_1);
INTCON2bits.TMR0IP = 0; //Low interrupt priority for timer
RCONbits.IPEN=1; // Enable interrupt Priority
INTCONbits.GIEL=1; // Enable interrupt Low-Priority Interrupt
INTCONbits.GIEH=1; // Enable interrupt Global
}
void main(void){
init();
while(1){
if(tick){
display();
tick = 0;
}
}
}
Here's my current code for perusal - it's just a function for the LED display on the HP-488 board. The display() function changes digits every few milliseconds to give the user a smooth four digit display on a 25% duty cycle.
#include "main.h"
unsigned char disp_high;
unsigned char disp_low;
volatile char tick;
unsigned char display_digit=1;
#pragma code high_vector=0x08
void high_interrupt (void)
{
_asm GOTO high_isr _endasm
}
#pragma code
#pragma interrupt high_isr
void high_isr (void){ //No high-priority interrupts have been defined yet, will be used for USART
}
#pragma code low_vector=0x18
void low_interrupt (void)
{
_asm GOTO low_isr _endasm
}
#pragma code
#pragma interruptlow low_isr
void low_isr (void)
{
if(INTCONbits.TMR0IF){ //The timer "ticks" at a regular interval of a few milliseconds, telling the display to move to the next digit
INTCONbits.TMR0IF = 0;
TMR0H = 0xB1;
TMR0L = 0xDF;
tick++;
}
}
void display(void){
unsigned char num;
switch(display_digit++){//Each digit on the display is synchronized with four bits (i.e. a number 0-F)
case 1: LATA = 0x08;
num=disp_low%16;
break;
case 2: LATA = 0x04;
num=disp_low/16;
break;
case 3: LATA = 0x02;
num=disp_high%16;
break;
case 4: LATA = 0x01;
num=disp_high/16;
display_digit=1;
break;
default: display_digit=1;
}
switch (num){ //nZero, etc., are the 8-bit definitions for each number, setting each segment either on or off
case 0: LATB = nZero;
break;
case 1: LATB = nOne;
break;
case 2: LATB = nTwo;
break;
case 3: LATB = nThree;
break;
case 4: LATB = nFour;
break;
case 5: LATB = nFive;
break;
case 6: LATB = nSix;
break;
case 7: LATB = nSeven;
break;
case 8: LATB = nEight;
break;
case 9: LATB = nNine;
break;
case 10: LATB = nTen_A;
break;
case 11: LATB = nEleven_B;
break;
case 12: LATB = nTwelve_C;
break;
case 13: LATB = nThirteen_D;
break;
case 14: LATB = nFourteen_E;
break;
case 15: LATB = nFifteen_F;
break;
default: LATB = 0xF;
}
}
void io_port_init(void){
TRISA = 0xF0; //Lower four bits of A are outputs to control LED display
LATA = 0x05;
TRISB = 0x00; //PORTB is all outputs
LATB = 0xFF;
TRISC = 0xFF; //PORTC is all inputs for now
LATC = 0x00;
}
void init(void){
disp_high=0xF1;
disp_low=0x0E;
io_port_init();
OpenTimer0 (TIMER_INT_ON & T0_SOURCE_INT & T0_16BIT & T0_PS_1_1);
INTCON2bits.TMR0IP = 0; //Low interrupt priority for timer
RCONbits.IPEN=1; // Enable interrupt Priority
INTCONbits.GIEL=1; // Enable interrupt Low-Priority Interrupt
INTCONbits.GIEH=1; // Enable interrupt Global
}
void main(void){
init();
while(1){
if(tick){
display();
tick = 0;
}
}
}