Hi everybody How can I restart the controller by internal rautine?(To simulate the external restart button)
An alternative method is to jump at the reset location (called warm boot). for example if your reset vector is located at 0x0000, you can use this C statement (*((const void(code*)(void)) 0x0000 ))(); (equivalent with LCALL 0 )
"An alternative method is to jump at the reset location" Alternative to what? Did you actually read the thread? "(*((const void(code*)(void)) 0x0000 ))();" You've gone a bit over the top with the asterisks. Try: ((void(code *)(void))0x0000)(); Stefan
"Did you actually read the thread?" Obviously not - as he missed the bit about restoring all SRFs to their default values.
Dear Stefan Both statements are corect. Both make a warm boot. But there is a DIFERENCE: Our statements are translated diferent :
((void(code *)(void))func_adr)(); --->LCALL 00H (*((const void(code*)(void)) 0x0000 ))(); --->LJMP 00H
"Our statements are translated diferent" Not when I compile them: 46: (*((const void(code*)(void)) 0x0000 ))(); 000050 120000 LCALL 00H 47: 48: ((void (code *)(void)) 0) (); 000053 120000 LCALL 00H Stefan
Hi everybody. Thank you all for your answers. I am using DK3200. I am using your advices during external interrupt. The problem is that the CPU is stucked after the reset function.(the reset function is the last function in the interrupt routine). I need the reset as the last function in the interrupt routine. In addition I don't want to waste another pin for hardware reset. Thank you all Kobi
.... I forgot some thing. I think that the writing to the LCD is the source of the problem.(but I need it) I am adding the code
void lid_int (void) interrupt 0 using 3 // LID Interrupt { unsigned char *chr_ptr; EX0 &= 0x00;//Disable external 0 interrupt IE0 &= 0; // Clear INT0 flag P1_2 = 0; // Disable relay PWM_Duty_Cyl(0,255); PWM_Duty_Cyl(1,255); uPSD_PWM_Disable(); P3_1 = 0; // Disable BL motor P3_0 = 0; // Disable turbine motor P1_1 = 0; // disable sensors lcd_clear(); chr_ptr = "THE LID IS OPEN!\n"; while (*chr_ptr != NULL) { if (*chr_ptr == '\n') { chr_ptr++; Cursor_LCD ^= 0x40; //goto next line Cursor_LCD &= 0xC0; //return to position 0 LCD_reg.LCD_CMD_WR = Cursor_LCD; } else { BusyCheck(); LCD_reg.LCD_RAM_WR = *chr_ptr++; } } while(P3_2 == 0) // Until the LID is open { } (*((const void(code*)(void)) 0x0000 ))(); }
You can't do the software reset from within an ISR because an IRET will never be executed. This means that the 8051 interrupt mechanism will not be reset and no further interrupts of equal or lower priority will be serviced. You must do your software reset from non-ISR code with all interrupts disabled. Remember that this method is not a real reset - you are just restarting your code. Why do you need to do a software reset anyway? Stefan
"I don't want to waste another pin for hardware reset." But in your code:
while(P3_2 == 0) // Until the LID is open { } (*((const void(code*)(void)) 0x0000 ))();
View all questions in Keil forum