|
|
View previous topic :: View next topic |
Author |
Message |
joshkeys
Joined: 16 Aug 2005 Posts: 37 Location: Fredericton,NB
|
Freezing on Powerup, MCLR reset fixes problem |
Posted: Sat Jan 20, 2007 9:10 pm |
|
|
Hi all,
I am having a problem where when I turn on the power to my project, it freezes immediatley. I am using 2 external interrupts, and it appears to enter one of the external interrupts and freeze. If I dot a MCLR reset, the code will work just great for as long as needed.
I am using a pullup on the MCLR (36K)
All pwr pins have 10uF cap
5v regulator has 22uf cap on pins..
I figured that the initial transients were causing a lot of noise, so I added the 22 uf cap to the output of the 5V regulator.
The interrupts are int0 and int1 on a PIC18F4320.
The code below is a test that I ran and it causes the problem.. so may be relative.. I excluded the pile of code below as it is all functions I created and not related.. also ignore the asm bit.
Code: |
#include <18F4320.h>
#device ICD=TRUE
#device adc=8
#use delay(clock=8000000)
#fuses NOWDT,INTRC, NOFCMEN,INTRC_IO,NOBROWNOUT, NOPUT, NOCPD, STVREN, DEBUG, NOLVP, NOWRT, NOWRTD, NOIESO, NOEBTR, NOEBTRB, NOPROTECT, NOCPB, NOWRTB, NOWRTC
#include <string.h>
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//% I/O %
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#define Start pin_B0
#define Reset pin_B1
#define Red pin_B2
#define Brake pin_B3
#define Gas pin_B4
#define Green pin_B5
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//% LCD Display %
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#define RS pin_C0
#define RW pin_C1
#define Enable pin_C2
#define Backlight pin_C4
#define DB0 pin_D0
#define DB1 pin_D1
#define DB2 pin_D2
#define DB3 pin_D3
#define DB4 pin_D4
#define DB5 pin_D5
#define DB6 pin_D6
#define DB7 pin_D7
#define A 0x41
#define B 0x42
#define C 0x43
#define D 0x44
#define E 0x45
#define F 0x46
#define G 0x47
#define H 0x48
#define I 0x49
#define J 0x4A
#define K 0x4B
#define L 0x4C
#define M 0x4D
#define N 0x4E
#define O 0x4F
#define P 0x50
#define Q 0x51
#define R 0x52
#define S 0x53
#define T 0x54
#define U 0x55
#define V 0x56
#define W 0x57
#define X 0x58
#define Y 0x59
#define Z 0x5A
#define Space 0xFE
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//% Global Variables %
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//% Function Declarations %
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void on();
void clear();
void initialize();
void mode();
void home();
void write(int letter);
#int_EXT
EXT_isr()
{
output_bit(Green,1);
delay_ms(1000);
}
#int_EXT1
EXT1_isr()
{
output_bit(Red,1);
delay_ms(1000);
}
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,255,16);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
enable_interrupts(GLOBAL);
#asm
MOVF 0xFD3,W
IORLW 0x70
MOVWF 0xFD3
//MOVLW 0xC0
//IORWF 0xFF2,F
#endasm
//initialize();
while(1){
output_bit(Green,0);
output_bit(Red,0);
}
}
|
So when it freezes, all that happens is the green LED comes on. so for some reason on powerup the int0 is being triggered and then freezing as I can put it to ground and nothing will happen.
Any help or thoughts would be greatly appreciated.
Thx,
Josh |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sat Jan 20, 2007 11:35 pm |
|
|
Quote: |
I am using a pullup on the MCLR (36K)
|
It is ok but if you replace it for a value close to 10K it will be safest.
Quote: |
figured that the initial transients were causing a lot of noise, so I added the 22 uf cap to the output of the 5V regulator.
|
Add a .01uF decoupling ceramic capacitor close to +5V power pin.
Quote: |
#fuses NOWDT,INTRC, NOFCMEN,INTRC_IO,NOBROWNOUT, NOPUT, NOCPD, STVREN, DEBUG, NOLVP, NOWRT, NOWRTD, NOIESO, NOEBTR, NOEBTRB, NOPROTECT, NOCPB, NOWRTB, NOWRTC
|
1) INTRC and INTRC_IO are mutually excluyents. Delete INTRC_IO
2) Replace NOPUT by PUT.
3) Add NOPBADEN to configure PORTB as digital input channels on RESET
Quote: |
#define A 0x41
#define B 0x42
..........................
..........................
#define Y 0x59
#define Z 0x5A
|
There are no reason to define the ASCII code. The compiler already ¨knows¨ that ´B´= ´A´+ 1
Code: |
#int_EXT
EXT_isr()
{
output_bit(Green,1);
delay_ms(1000);
}
|
It is not a good practice to include such long delay inside an interrupt handler.
It should be as fast as posible, do not forget that while the processor is servicing
an interrupt, it is not doing its main task.
You can test the EXT interrupts with this code:
Code: |
#int_EXT
EXT_isr()
{
output_high(Green);
EXT_Int_0_FLAG = TRUE;
}
#int_EXT1
EXT1_isr()
{
output_high(Red);
EXT_Int_1_FLAG = TRUE;
}
void main()
{
delay_ms(100); // add a short delay waiting to stabilize after power up.
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ|OSC_TIMER1);
while(1)
{
if(EXT_Int_0_FLAG)
{
delay_ms(500); // to see the Green LED ON
EXT_Int_0_FLAG=FALSE;
}
else
{output_low(Green);}
if(EXT_Int_1_FLAG)
{
delay_ms(500); // to see the Red LED ON
EXT_Int_1_FLAG=FALSE;}
else
{output_low(Red);}
}
}
|
Humberto |
|
|
joshkeys
Joined: 16 Aug 2005 Posts: 37 Location: Fredericton,NB
|
Thanks! |
Posted: Sun Jan 21, 2007 1:25 pm |
|
|
I believe the problem was with portB not configured as input on startup causing a multitude of interrupts on startup. And I believe the interrupts have a stack? Either way it seems to work great now! Thx. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sun Jan 21, 2007 5:12 pm |
|
|
Quote: |
And I believe the interrupts have a stack?
|
NOP. Once in the Interrupt Service Routine, the source(s) of the interrupt is determined
by polling the interrupt flag bits.
The stack is used to store the return address, not to store further interrupts.
Quote: |
Either way it seems to work great now!
|
Apparently. This test only is toggling some LEDs and you get the same visual effect,
but conceptually there are a big difference. In a real application while you spend 1000ms
inside an interrupt, the global interrupt enable bit was cleared to disable further
interrupts, so the processor can´t do anything but wasting time inside an interrupt
and it can´t ´see´ another events that can trigger other interrupts.
The way I show you, the processor can service ANY interrupts while spending
the LED on-time.
Humberto |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|