MCU stop after executing of subs.

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
Hi
Have this setup of 16F18877
When starts up all works like i should.
When i execute the sub "sluk_ur" sub to stop timer1
the time stops at it should, but after setting the time, i will have to execute the sub "start_ur".
the sub ran ok, but when it return to MAIN WHILE LOOP. the execution is stopped.
I have enabled all timers and interrupts i have "stopped" in "sluk_ur" sub.
Cleared all interrupts.,
Just dont know why i will not keeps going.
Code:
#include    "lcd3.c"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#pragma config FEXTOSC=XT
#pragma config RSTOSC=EXT1X
#pragma config CLKOUTEN=OFF
#pragma config CSWEN=ON
#pragma config FCMEN=ON
#pragma config MCLRE=ON
#pragma config PWRTE=OFF
#pragma config LPBOREN=OFF
#pragma config BOREN=ON
#pragma config BORV=LO
#pragma config ZCD=OFF
#pragma config PPS1WAY=ON
#pragma config STVREN=ON
#pragma config WDTCPS=WDTCPS_31
#pragma config WDTE=OFF
#pragma config WDTCWS=WDTCWS_7
#pragma config WDTCCS=SC
#pragma config WRT=OFF
#pragma config SCANE=available
#pragma config LVP=ON
#pragma config CP=OFF
#pragma config CPD=OFF

#define _XTAL_FREQ 4000000
#define FOSC 4000000L
#define back_light RB0
#define led1_on RE0
#define KN1 RC3
#define KN2 RC2
#define KN3 RA2
#define KN4 RA3
#define KN5 RC7
#define KN6 RC6
#define KN7 RC5
#define KN8 RC4

#define Skip_ROM             0xCC
#define Convert_T             0x44
#define Read_scratchpad     0xBE

#define Port_18B20             RB5
#define Tx_18B20             TRISB5 = 0
#define Rx_18B20             TRISB5 = 1

#define WAIT1                1000
#define WAIT2                500

#define DS18B20_CONV_TIME    750
#define DS18B20_RESET_PULSE 480
#define DS18B20_WAIT_TIME     60
#define DS18B20_PULLUP_TIME 2

#define ONEWIRE_PRESENT     0
#define ONEWIRE_ABSENT         1

unsigned int secund,hour,minut,rain,rainmonth,rainyear,shifttick,inaktiv;
unsigned int rainyear_part1,rainyear_part2,calyear,calmonth,caldate,calday;
unsigned char timestr[6],minutstr[6],secstr[6],rainstr[6],datestr[6];
bit sec,rainincome,showrain,knap4,knap1,knap2,knap3,knap5,knap6,knap7,knap8,leapyear;
unsigned char lsb;
    unsigned char msb;
    unsigned char decimal;
    unsigned char buffer[11];
    unsigned int sign_flag =0;
    unsigned int integer =0;
    unsigned int integer1 =0;
    unsigned int integer2 =0;
    unsigned int integer3 =0;
    unsigned int integer4 =0;
    signed int min,max,minold,minhele,minfraction,maxhele,maxfraction,total,fraction,now;
    int tempmax,minnegativ,maxnegativ;
    char hele[10],deci[10];
    int xpulse,x,negativ,maxxpulse;
char test[10];
unsigned char raindays[31];
volatile unsigned char week_day;
unsigned char mintime[3],maxx[3];
unsigned char maxtime[3],minx[3];
char mintemp[3],maxtemp[3];
const char * const day_of_week_names[] = {"Mandag ",
                                          "Tirsdag",
                                          "Onsdag ",
                                          "Torsdag",
                                          "Fredag ",
                                          "Lordag ",
                                          "Sondag "
                                         };
static void interrupt isr(void)   // Here is interrupt function - the name is unimportant.
{
  
if(TMR1IF)             // Was this a timer overflow?
    {
          TMR1IF=0;        // Clear interrupt flag, ready for next
        TMR1L=0x00;
         TMR1H=0x80;     // If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
                
         sec=1;             // adds a sec.
    }
if (IOCAF4)  // if pulse on RA4. rain income
{
    rainincome=1; // set bit to main loop
    IOCAF4=0;  // clear interrupt.
  
}
if (IOCCF2) // button 2 pressed.// set time.
{inaktiv=0; //just to turn off bcklight when nothing happpens
    back_light=1; // turns on backlight
    knap2=1; // set bit to main loop
    IOCCN2=0; // disable intterrupt,.for this button for now
    IOCCF2=0; // clear the interrupt
}
if (IOCAF3)  // buttom 4 pressed.
{
    inaktiv=0; ////just to turn off bcklight when nothing happpens
    back_light=1;// turns on backlight
    knap4=1; // set bit to main loop
IOCAF3=0; // clear interrupt-
}




}

    void setup(void)
{   
           
TRISA0=1; //set all A port in
TRISA1=1;
TRISA2=1;
TRISA3=1;
TRISA4=1;
TRISA5=1;
TRISA6=1;
TRISA7=1;

TRISB0=0; // port b0 = out
TRISB3=0; // PORT B3 = out
TRISB5=1;// CHANGE
TRISB6=1;
TRISB7=1;

TRISC0=1; // ALL C = IN
TRISC1=1;
TRISC2=1;
TRISC3=1;
TRISC4=1;
TRISC5=1;
TRISC6=1;
TRISC7=1;

TRISD0=0; // ALL D = out
TRISD1=0;
TRISD2=0;
TRISD3=0;
TRISD4=0;
TRISD5=0;
TRISD6=0;
TRISD7=0;

TRISE0=0; // E0 = out
TRISE1=1;
TRISE2=1;

WPUE1=1; // PULL UP no neeed have pullups. do it anyway
WPUE2=1;
WPUC2=1;
WPUC3=1;
WPUC4=1;
WPUC5=1;
WPUC6=1;
WPUC7=1;
IOCAN2=1; // negativ interrupt A2
IOCAN3=1; // negativ interrupt A3
IOCAP4=1; // interrupt on pin RA4  positive
IOCCN2=1;  // negativ interrupt C2
IOCCN3=1;  // negativ interrupt C3

ANSELA=0b00000000; // set alle digital.
ANSELB=0b00000000;
ANSELC=0b00000000;
ANSELD=0b00000000;
ANSELE=0b0000;

//timer 1 setup
T1CS0=0; // 0110 = SOCS
T1CS1=1;
T1CS2=1;
T1CS3=0;
T1CKPS0=0; // no prescale
T1CKPS1=0;
nT1SYNC=1; // no sync
  
lcd3_init();
lcd3_goto(0);
}

void start_ur (void) // Starter uret.
{
    RE0=0; // kill LED.
   TMR1IF=0; // clear interrupts  timer1
   IOCAF4=0; // RA4
   IOCAF2=0; //RA2 = knap3
   IOCAF3=0; // RA3 = Knap4
   IOCCF2=0; // RC2= knap 2
   IOCCF3=0; // RC3 = Knap1
   IOCIE=1; // enable IOC

   PEIE=1;  // enable interrupr
   IOCCN2=1; // interrupt knap2 again
   TMR1IE=1;  // enable interrupr for timer1
  
   GIE=1; // enable global interrupr
 
}     // slut "sub "start ur"
      
void sluk_ur (void) // Slukker uret
{
   IOCIE=0; // disable IOC
   TMR1IE=0;  // disable interrupr for timer1
   GIE=0; // disable global interrupr
   PEIE=0;  // disable interrupt
  
secund=0;            // sets sec = 0
RE0=1;         // turn on led

}// slut "sub sluk ur "

void vis_timedate (void)
     {
   
     lcd4_goto(0x03);
     lcd4_puts("TIME AND DATE");
     lcd4_goto(0x40);
     lcd4_puts("Time is =    :  :");
     lcd4_goto(0x4b);
     if (hour<10)lcd4_puts("0");
     utoa(rainstr,hour,10);
     lcd4_puts(rainstr);
     lcd4_goto(0x4e);
     if (minut<10)lcd4_puts("0");
     utoa(rainstr,minut, 10);
     lcd4_puts(rainstr);
     lcd4_goto(0x51);
     if (secund<10)lcd4_puts("0");
     utoa(rainstr,secund,10);
     lcd4_puts(rainstr);
     lcd4_goto(0x14);
     lcd4_puts("Date is =   -  -");
     lcd4_goto(0x1e);
     if (caldate<10)lcd4_puts("0");
     utoa(datestr,caldate,10);
     lcd4_puts(datestr);
     lcd4_goto(0x21);
     if (calmonth<10)lcd4_puts("0");
     utoa(rainstr,calmonth,10);
     lcd4_puts(rainstr);
     lcd4_goto(0x24);
     utoa(rainstr,calyear,10);
     lcd4_puts(rainstr);
     lcd4_goto(0x54);
     lcd4_puts("Day is ");
     for (unsigned char i=0;i<7;i++) lcd4_putch(day_of_week_names[calday][i]);
   
     }
void stil_ur (void) //Indstiller uret
{
    sluk_ur();         // Stopper tiden if times stop, then change lcd stops.
    lcd4_clear();
    vis_timedate();     // Viser uret / time date show
    //secund=0;
   do                  // Læser på knapperne
   {
    if (!RA2)     // Stiller timer fremad
   {
       hour++;                    // Lægger en time til
        if (hour==24) hour=0;     // hvis timer = 24 så 0.
        vis_timedate();            // viser vi har talt en op
        __delay_ms(255);         // venter lidt.
        __delay_ms(255);
               }
    if (!RA3) // Stiller minutter frem
   {
        minut++;                // lægger 1 minut til.
         if (minut==60) minut=0;// hvis minut = 60 så 0.
           vis_timedate();            // viser vi har talt op.
         __delay_ms(255);         // venter lidt.
         __delay_ms(255);
               }  
    if (!RC2)  // Stiller ugedagen
   {
          calday++;             // lægger 1 dag til.
         if (calday==7) calday=0; // hvis dag 7 så dag 0.
         vis_timedate();            // viser vi har talt op.
         __delay_ms(255);         // venter lidt.
               }  
    if (!RC6)  // Stiller date
   {
          caldate++;             // lægger 1 dag til.
         if (caldate==32) caldate=1; // hvis dag 7 så dag 0.
         vis_timedate();            // viser vi har talt op.
         __delay_ms(255);         // venter lidt.
               }  
  
    if (!RC5)  // Stiller month
   {
          calmonth++;             // lægger 1 dag til.
         if (calmonth==13) calmonth=1; // hvis moned 13 så 1.
         vis_timedate();            // viser vi har talt op.
         __delay_ms(255);         // venter lidt.
               }  
  
    if (!RC4)  // Stiller året
   {
          calyear++;             // lægger 1 dag til.
         vis_timedate();            // viser vi har talt op.
         __delay_ms(255);         // venter lidt.
               }
    if (!RC7)  // Stiller året ned
   {
          calyear--;             // trækker 1 dag fra.
         vis_timedate();            // viser vi har talt op.
         __delay_ms(255);         // venter lidt.
               }
  
  
    } while (RC3); // indtil knappen trykkes igen
  
start_ur();  //Starter uret

}// end stil uret


void main (void)
{
     setup();
     IOCAF4=0; // clear the interrupt for RA4.
   
    T1RD16=1; // turn on timer1
    TMR1ON=1; // turn on timer1
    T1GE=0; // gate allways count
    IOCIE=1; // enable IOC
    TMR1IE=1;  // enable interrupr for timer1
    GIE=1; // enable global interrupr
    PEIE=1;  // enable interrupr
    while (1)
    {
            if (knap2==1)  // set time/date
         {
               int p;
                p=0;  
             while (p<30)    // repaet until 100*30=3 SEC
             {
                __delay_ms(100);
                p++;
             }
                 if (RC2==0) // if stilled pressed after 2 sec.
                 {
                   
                     knap2=0;
                     stil_ur(); // go to sub set clock
                  
                 } 
            }
          
            if (sec==1) // if secund tick.
         {   secund++;
            // klokken();
          
             inaktiv++;
             sec=0;
           
         }
         if (inaktiv==30) // things to do when inactiv
         {
             back_light=0;
             inaktiv=0;
         }
          
    }
Only a part of code, but this part fails to "restart" after TIMER1 is stopped ( or just interrupt from it is disabled)
 

spinnaker

Joined Oct 29, 2009
7,830
What does fails to "restart mean"??? What do you expect it to do? You need to be more clear if you expect anyone to help.

Have you learned to use your debugger yet?
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
After i have set the time / date, the intend is to return to this part in main while loop, where it came from
Code:
 if (knap2==1)  // indstil time/date
         {
               int p;
                p=0;   
             while (p<30)    // løkke indtil 100*30=3 SEC
             {
                __delay_ms(100);
                p++;
             }
                 if (RC2==0) // if stilled pressed after 2 sec.
                 {
                    
                     knap2=0;
                     stil_ur();
                    RETURN HERE TO AFTER SET TIME..
                 }
        
         }
It does return to this place, and then it exit that IF sentense as it should, but the WHILE Loop is not been feed with timer1 overflow anymore.
My Timer1 will not "restart" or generate overflow after the stop while setting the clock/time/date
 

spinnaker

Joined Oct 29, 2009
7,830
Dont know how to use debug.
Have tried but just seem to execute and the watches never change value
Before you do anything else, sit down an learn to use it. It is not that difficult. Set break points, step through your code and figure out where it is hanging up. This is what any good software developer does.
 

spinnaker

Joined Oct 29, 2009
7,830
After i have set the time / date, the intend is to return to this part in main while loop, where it came from
Code:
 if (knap2==1)  // indstil time/date
         {
               int p;
                p=0;  
             while (p<30)    // løkke indtil 100*30=3 SEC
             {
                __delay_ms(100);
                p++;
             }
                 if (RC2==0) // if stilled pressed after 2 sec.
                 {
                   
                     knap2=0;
                     stil_ur();
                    RETURN HERE TO AFTER SET TIME..
                 }
       
         }
It does return to this place, and then it exit that IF sentense as it should, but the WHILE Loop is not been feed with timer1 overflow anymore.
My Timer1 will not "restart" or generate overflow after the stop while setting the clock/time/date

Sorry not following you. Do you have a timer interrupt??
 

spinnaker

Joined Oct 29, 2009
7,830
After i have set the time / date, the intend is to return to this part in main while loop, where it came from
Code:
 if (knap2==1)  // indstil time/date
         {
               int p;
                p=0;  
             while (p<30)    // løkke indtil 100*30=3 SEC
             {
                __delay_ms(100);
                p++;
             }
                 if (RC2==0) // if stilled pressed after 2 sec.
                 {
                   
                     knap2=0;
                     stil_ur();
                    RETURN HERE TO AFTER SET TIME..
                 }
       
         }
It does return to this place, and then it exit that IF sentense as it should, but the WHILE Loop is not been feed with timer1 overflow anymore.
My Timer1 will not "restart" or generate overflow after the stop while setting the clock/time/date

What is setting time and date? Where is the code that sets time and date?
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
Yes i have a timer1 interrupt, that generate a sec tick.
the part here
Code:
if (knap2==1)  // set time/date
         {
               int p;
                p=0;  
             while (p<30)    // repaet until 100*30=3 SEC
             {
                __delay_ms(100);
                p++;
             }
                 if (RC2==0) // if stilled pressed after 2 sec.
                 {
                   
                     knap2=0;
                     stil_ur(); // go to sub set clock
                  
                 } 
            }
is for catching the interrupt from pushbutton "knap2" or button2 in English,
reason for little loop is to hold the button for 3 sec before entering the time/date adjust.

this part here
Code:
void stil_ur (void) //Indstiller uret  // set time
{
sluk_ur();  // Stops time, so no interrups can interfere.
  lcd4_clear();  // clears the LCD
vis_timedate();  // Viser uret / time date show 
//secund=0; // set the secund to 0.
  do   // Læser på knapperne  //
  {
  if (!RA2)  // Stiller timer fremad  add 1 to hour
  {
  hour++; // Lægger en time til add 1 to hour
if (hour==24) hour=0;  // if hour = 24 then 0.
vis_timedate(); // update the LCD
  __delay_ms(255);  // wait a while.
  __delay_ms(255);
  }
  if (!RA3) // Stiller minutter frem  set minutes
  {
minut++; // lægger 1 minut til.
  if (minut==60) minut=0;// hvis minut = 60 så 0.
    vis_timedate(); // viser vi har talt op.
  __delay_ms(255);  // venter lidt.
  __delay_ms(255);
  } 
  if (!RC2)  // Stiller ugedagen  // set day of week
  {
   calday++;  // lægger 1 dag til.
  if (calday==7) calday=0; // hvis dag 7 så dag 0.
  vis_timedate(); // viser vi har talt op.
  __delay_ms(255);  // venter lidt.
  } 
  if (!RC6)  // Stiller date  sets the date
  {
   caldate++;  // lægger 1 dag til.
  if (caldate==32) caldate=1; // hvis dag 7 så dag 0.
  vis_timedate(); // viser vi har talt op.
  __delay_ms(255);  // venter lidt.
  } 
 
  if (!RC5)  // Stiller month  set month
  {
   calmonth++;  // lægger 1 dag til.
  if (calmonth==13) calmonth=1; // hvis moned 13 så 1.
  vis_timedate(); // viser vi har talt op.
  __delay_ms(255);  // venter lidt.
  } 
 
  if (!RC4)  // Stiller året   sets year
  {
   calyear++;  // lægger 1 dag til.
  vis_timedate(); // viser vi har talt op.
  __delay_ms(255);  // venter lidt.
  }
  if (!RC7)  // Stiller året ned  year down
  {
   calyear--;  // trækker 1 dag fra.
  vis_timedate(); // viser vi har talt op.
  __delay_ms(255);  // venter lidt.
  }
 
 
  } while (RC3); // indtil knappen trykkes igen   be in loop until RC3 button is pressed.
 
start_ur();  //Starter uret  starts the clock again.
}// end stil uret end of sub.


And here code for interrups, in case u didnt see it ;)
Code:
static void interrupt isr(void)   // Here is interrupt function - the name is unimportant.
{
  
if(TMR1IF)             // Was this a timer overflow?
    {
          TMR1IF=0;        // Clear interrupt flag, ready for next
        TMR1L=0x00;
         TMR1H=0x80;     // If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
                
         sec=1;             // adds a sec.
    }
if (IOCAF4)  // if pulse on RA4. rain income
{
    rainincome=1; // set bit to main loop
    IOCAF4=0;  // clear interrupt.
  
}
if (IOCCF2) // button 2 pressed.// set time.
{inaktiv=0; //just to turn off bcklight when nothing happpens
    back_light=1; // turns on backlight
    knap2=1; // set bit to main loop
    IOCCN2=0; // disable intterrupt,.for this button for now
    IOCCF2=0; // clear the interrupt
}
if (IOCAF3)  // buttom 4 pressed.
{
    inaktiv=0; ////just to turn off bcklight when nothing happpens
    back_light=1;// turns on backlight
    knap4=1; // set bit to main loop
IOCAF3=0; // clear interrupt-
}




}
 
Last edited:

spinnaker

Joined Oct 29, 2009
7,830
The reason that you should post with code tags is to preserve indenting. Don't you indent anything and format it properly?

You need to break your code down into smaller pieces. Keep adding more code a bit at a time till you figure out where the problem is.

For example.

for example the only thing in stil_ur is the do loop. Get that working. Add a little bit of code at a time.


void stil_ur (void) //Indstiller uret // set time
{
do // Læser på knapperne //
{

} while (RC3); // indtil knappen trykkes igen be in loop until RC3 button is pressed.

start_ur(); //Starter uret starts the clock again.

}// end stil uret end of sub.

}
 
Last edited:

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
Have been studing the debug, and some videos online, but still can get the hang of it...
cant even build the code, when debugger selected,

So back to test,
Added some test in my code, and found that after return from set time, the MCU just executes INTERRUPTS,
nothing in main while loop is executed anymore..
Like the MCU get lost of where it came from.
CORRECTION
after more test
It return to main loop and do a 35-40 runs and then no more,
ISR still works, but can't ofcourse not execute code,
Have added a LED Blink in ISR so know when timer1 overflow,
 
Last edited:

spinnaker

Joined Oct 29, 2009
7,830
Your ISR should not be checking for button press. That takes too long. ISR should be be very fast. If you need to check for a button press then set a flag. You then check for button press in the main loop if the flag is set. You need to remember to clear the flag after you act on it. You would use this method for any code that takes a long time in the ISR.
 

spinnaker

Joined Oct 29, 2009
7,830
It doesn't matter the size. Check for your inputs in the main loop.


Also temporarily reduce your ISR code to

if(TMR1IF) // Was this a timer overflow?
{
TMR1IF=0; // Clear interrupt flag, ready for next
TMR1L=0x00;
TMR1H=0x80; // If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second

sec=1; // adds a sec.
}


And the ISR is another source of your problem All of that code under this block

if(TMR1IF) // Was this a timer overflow?
{
TMR1IF=0; // Clear interrupt flag, ready for next
TMR1L=0x00;
TMR1H=0x80; // If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second

sec=1; // adds a sec.
}

Is always being executed for any ISR. If you want it only to execute for the timer ISR then additional code needs to be inside the if(TMR1IF) block.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
The other ISR are for interrupts on PORTS,
Other claims i should use as much as interrupts as possible.
But now i have added button check in main, and removed all IOC for PORTS,
Now it seems to work like it should.
 
Top