![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
rald
Joined: 04 Sep 2013 Posts: 25
|
pic18F4550 working two timers interruption same time & O |
Posted: Sat Jul 29, 2017 1:34 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Sat Jul 29, 2017 3:41 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
rald
Joined: 04 Sep 2013 Posts: 25
|
|
Posted: Sat Jul 29, 2017 4:57 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Sat Jul 29, 2017 5:43 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Sun Jul 30, 2017 12:20 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|