CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

pic18F4550 working two timers interruption same time & O

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rald



Joined: 04 Sep 2013
Posts: 25

View user's profile Send private message

pic18F4550 working two timers interruption same time & O
PostPosted: Sat Jul 29, 2017 1:34 pm     Reply with quote

hello experts:

I have a question about timers, and also an issue to fix in my project.

first: about timers, when I configure two interruption by timers I see that only one is running, my question is can I run two timer interruptions with different periods at the same time? yes or no... one is for 1 sec the other is for 1 ms.

second: my device is presenting random failing which it is mean that for 10 test just fails 1, I need that my device never fail, so can use OSCF interruption to monitor this errors? does anyone know if there is some way to prevent errors?

POST: my code is huge and I can not put the code here just parts of it.

Code:

      do{
     while((sensor_odometro == 0) && (boton_dos == 1)){   
         off(led_status);                                                                               
         delay_ms(1);
         x++;  //esta equis controla los 6 minutos iniciales 
         x3++;   
         if((x3 >= 500)&&(tiempo_cortesia == 0)){
            calculo_tiempo = ceil(345000-((contador_pulsos * 345000)/general));
            do{
               delay_ms(1);
               if(x++ >= calculo_tiempo){
                    *distancia = (contador_pulsos*1000)/general;
                    contador_pulsos = 0;   
                    tiempo_cortesia = 1;
                    x = 0;
                    break;       
               }       
            } while((sensor_odometro == 0) && (boton_dos == 1));
            break;
         }         
         if((x >= calculo_tiempo)||(tiempo_cortesia == 1)){
            kilometro_cortesia = 1;
            tiempo_cortesia = 1;                 
            if(x3 >= 500){               
               x3 = 0;                                                                                 
               while((sensor_odometro == 0) && (boton_dos == 1)){
                    delay_ms(1);
                    x2++; 
                    if(x2 >= control_tiempo){ 
                         *pago = *pago + 10;
                         x2 = 0;
                         borrar;
                         pantalla_precio(*pago);   
                    }                                             
               }
            }               
         }
      }
      x3 = 0;         
//--------------------------------------------------------------------------------
      if((contador_pulsos++ >= general) || (kilometro_cortesia == 1)){   
         tiempo_cortesia = 1;   
         kilometro_cortesia = 1;
         if(contador_pulsos >= pulsos_mts){
            *pago = *pago + 10;
            *distancia = *distancia + metros_float;                                                                       
            contador_pulsos = 0;
            borrar;
            pantalla_precio(*pago);
         }                             
      }
//--------------------------------------------------------------------------------
      while((sensor_odometro == 1) && (boton_dos == 1)){   
         on(led_status);                                                                               
         delay_ms(1);
         x++;  //esta equis controla los 6 minutos iniciales 
         x3++;   
         if((x3 >= 500)&&(tiempo_cortesia == 0)){
            calculo_tiempo = ceil(345000-((contador_pulsos * 345000)/general));
            do{
               delay_ms(1);
               if(x++ >= calculo_tiempo){
                    *distancia = (contador_pulsos*1000)/general;
                    contador_pulsos = 0;   
                    tiempo_cortesia = 1;
                    x = 0;
                    break;       
               }
               calculo_tiempo = (x*general)/345000;
            } while((sensor_odometro == 1) && (boton_dos == 1));
            break;
         }         
         if((x >= calculo_tiempo)||(tiempo_cortesia == 1)){
            kilometro_cortesia = 1;
            tiempo_cortesia = 1;                 
            if(x3 >= 500){               
               x3 = 0;                                                                                 
               while((sensor_odometro == 1) && (boton_dos == 1)){
                    delay_ms(1);
                    x2++; 
                    if(x2 >= control_tiempo){ 
                         *pago = *pago + 10;
                         x2 = 0;
                         borrar;
                         pantalla_precio(*pago);   
                    }                                             
               }
            }               
         }
      }
      x3 = 0;
   }while(boton_dos == 1);


thanks.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jul 29, 2017 3:41 pm     Reply with quote

some points...
Generally speaking, a timer once set, can only interrupt at one 'rate'. So you could use two timers, one for the 1hz rate, one for the 1ms rate.
OR you could just have a 1ms timer ISR and count inside it for 1000 times to give the 1Hz interrupt.
If you have a look at the software RTC in the code library, you'll have a better understanding of what I'm saying.

As for the random failures, you'll have to cut/disable code until you find the problem IF it is software generated. One possible problem could be the delay_ms(1); you have in the code you have shown. There is the possibility the random failure is caused by hardware, say EMI, noise, PCB traces.

Since your program is large, I assume you did it in 'sections'. If so, did it work fine until the last 'section' of code was compiled? If so, then somewhere in THAT section is where the problem is....maybe...

Jay
rald



Joined: 04 Sep 2013
Posts: 25

View user's profile Send private message

PostPosted: Sat Jul 29, 2017 4:57 pm     Reply with quote

hi temtronic

I have been testing and testing, with different timings in pin A0 which is the sensor_odometro...
I discover that my problem is delay_ms, because, for example, if the pin state changes before the delay ends the pic take the pulse as two states instead of just one.
Do you have how can I keep the port clean to prevent this?

thanks.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jul 29, 2017 5:43 pm     Reply with quote

You need to add some kind of 'filtering'. It could be as simple as a capacitor to 'smooth' out the sensor signal. If the sensor is a mechanical switch it should have an R-C filter between it and the PIC input pin.
You can either do a lot of math or just try a 1K in series, then a .1 mfd to ground. Test this see what happens. If it fails at higher speeds, decrease the cap value, try again...

Hope this helps.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sun Jul 30, 2017 12:20 am     Reply with quote

The other thing not mentioned, is the general rule for interrupts.

Interrupt handlers should do just what is necessary, and exit immediately.
Now this does not mean that code needs to only be one or two instructions, but it does mean that anything that takes significant time, should not be inside an interrupt handler.

On a 1mSec interrupt, assuming you are running the 4550, at 48Mhz, there is time for just a total of 12000 machine instructions between each interrupt. Sounds huge, but it takes about 65 instructions just to get into and out of an interrupt handler. A simple array access, will use about 20 instructions. A int32 division will take over 1000 machine instructions, while a float division takes this up to nearly 1500. Suddenly 12000 instructions is not that much....
Even worse, anything that 'deadlocks' the interrupt. So (for instance), a serial interrupt, that tries to read two characters. The interrupt is saying _one_ character has arrived. Asking for a second, means the interrupt has to wait for this to arrive. At this point, till it arrives, the code is stuck in the interrupt. :(

Since interrupts when called are 'polled' (each is handled in turn), if your handler routine for the first interrupt called, takes longer than the time between it's activation, no other interrupt will be called.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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