|
|
View previous topic :: View next topic |
Author |
Message |
RENNICK
Joined: 06 Apr 2020 Posts: 1 Location: TEC. INSTRUMENTISTA
|
Stack overflow 16F883 |
Posted: Thu Apr 09, 2020 6:47 pm |
|
|
Good evening. I made a program of a decreasing clock since I need it in ccs compiler. It is a subroutine of another main one. It works until when it has to repeat the cycle it starts presenting error of [PIC16 CORE] PC = 0x03E8. Stack underflow executing RETURN instruction. [U1], if you have any ideas to correct this error, I would appreciate it.
Code: |
#include <16f883.h>
#fuses xt, nowdt
#use delay (Clock=4Mhz)
#define LCD_DATA_PORT getenv("SFR:PORTC")
#define LCD_ENABLE_PIN PIN_A0
#define LCD_RS_PIN PIN_A2
#define LCD_RW_PIN PIN_A1
#include <lcd.c>
#use standard_io(c)
int16 desbordamiento=0;
int s=0;
int m=0;
int c=0;
void pausa(void)
{
lcd_gotoxy(1,2);
lcd_putc("TIEMPO RESTATNTE: pausa\n");
while(input(pin_b0)==0){ // pulsa tecla stop se retorna
if(input(pin_b6)==1){ //pulsa la tecla play retorna y sigue decrementando
do{
}
while(input(pin_b6)==1);
c=0;
return;
}
}
}
void configuracion(void) //:::::::::: Función de Configuración ::::::::::
{
enable_interrupts(int_ext); //Habilitamos la interrupción externa
ext_int_edge(l_to_h); // se habilita la interrupcion ext. de bajo a alto
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); //Preescaler 256 Timer0
set_timer0(224); //Establecemos el timer0 a 224 para obtener 10ms
enable_interrupts(int_timer0); //Habilitamos la interrupción del timer0
enable_interrupts(global); //Habilitamos todas las interrupciones del PIC
}
void inicio(void) //Función Aplicacion de señal MENU RUN::::::::::
{
configuracion();
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("Aplic. \n");
lcd_gotoxy(28,1);
lcd_putc("% 00\n");
lcd_gotoxy(1,2);
lcd_putc("TIEMPO RESTATNTE: \n");
while (TRUE)
{
lcd_gotoxy(26,2);
printf(lcd_putc,"(%02u:%02u)",m,s);
}
}
void tiempo()
{
lcd_putc('\f');
lcd_gotoxy(8,1);
lcd_putc("*** MENU DE TIEMPO ***\n");
lcd_gotoxy(1,2);
lcd_putc("TIEMPO RESTATNTE: \n");
while(true){
lcd_gotoxy(26,2);
printf(lcd_putc,"(%02u:%02u)",m,s);
delay_ms(200);
lcd_gotoxy(26,2);
printf(lcd_putc,"( :%02u)",s);
delay_ms(200);
}
return;
}
void main(void)
{
lcd_init();
enable_interrupts(int_rb);
enable_interrupts(int_ext); //Habilitamos la interrupción externa
ext_int_edge(l_to_h);
enable_interrupts(global);
delay_ms(300);
while(true)
{
lcd_gotoxy(4,1);
lcd_putc("\f menu main \n");
delay_ms(1500);
break;
}
tiempo();
}
#int_timer0
void timer_reloj(void) //Función de Interrupción Timer,RELOJ:::::::::
{
desbordamiento++;
if(desbordamiento==10) // es 100 para 1 seg, pero se coloca 10 para hacerlo dinamico en la simulacion
{
desbordamiento=0;
if(s!=0){
s--;
}
if(m==0&&s==0)
{
m=0;
s=0;
disable_interrupts(int_timer0);
clear_interrupt(int_timer1);
clear_interrupt(int_rb);
clear_interrupt(int_ext);
main();
}
if(s==0)
{
s=59;
if(m!=0){
s=59;
m--;
}
}
}
set_timer0(224); //se carga el timer0 de nuevo para 10 mseg
}
#int_RB
ext_isr(){
if(input(pin_b4)==1){
do {
}
while(input(pin_b4)==1);
m=m+1;
if(m==60){
m=60;
}
}
if(input(pin_b5)==1){
do {
}
while(input(pin_b5)==1);
if(m!=0){
m=m-1;
}
}
if(input(pin_b6)!=0){
do {
}
while(input(pin_b6)!=0);
if(c==1){
pausa();
}
c++;
inicio();
}
if((input(pin_b0)==1)||(input(pin_b7)==1))
{
do {
}
while((input(pin_b0)==1)||(input(pin_b7)==1));
s=0;
m=0;
disable_interrupts(int_timer0);
clear_interrupt(int_timer1);
clear_interrupt(int_rb);
clear_interrupt(int_ext);
main();
}
} |
_________________ I DEDICATE TO INSTRUMENTATION A BRANCH OF ELECTRICITY THAT IS IN CHARGE OF PROCESS CONTROL |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 09, 2020 8:10 pm |
|
|
Your program has a lot of coding bugs.
But the bug that's causing your stack problem is this one:
Quote: |
disable_interrupts(int_timer0);
clear_interrupt(int_timer1);
clear_interrupt(int_rb);
clear_interrupt(int_ext);
main();
}
}
|
You should not call main() in CCS. If you want to restart the program at
main() in CCS, you can make a outer while() loop. Example:
Quote: |
void main(void)
{
while(TRUE)
{
lcd_init();
enable_interrupts(int_rb);
enable_interrupts(int_ext);
ext_int_edge(l_to_h);
enable_interrupts(global);
delay_ms(300);
while(true)
{
lcd_gotoxy(4,1);
lcd_putc("\f menu main \n");
delay_ms(1500);
break;
}
tiempo();
}
}
|
Or another option is to call reset_cpu(). Example:
Quote: |
}
while((input(pin_b0)==1)||(input(pin_b7)==1));
s=0;
m=0;
disable_interrupts(int_timer0);
clear_interrupt(int_timer1);
clear_interrupt(int_rb);
clear_interrupt(int_ext);
reset_cpu();
} |
Normally, this method of programming is not done. But it will restart
the program. |
|
|
|
|
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
|