Hello can someone tell me why my interrupt does not respond, with the debugger, I always get z = 0
double z; main { . . . . . . while(1) { CC1_M2 = 0x0001;// 001=>capture on posirtive Flanke CC1_T01CON = 0x0047; CC1_CC8IC = 0x00C0; // Interrupt enable und z = Periode ; }//end of while }// end of main void Drehzahl_messung(void) interrupt(0x18) { Periode = 100; }
or what I have since forgotten Thanks
Sorry, I can't help with your problem, since I don't work with the C166 processor.
But one thing to think about is your assign of the double value in the interrupt handler.
Is the C166 processor capable of writing a double (or if it is just an alias for a float) atomically? If not, then the main loop may read broken values if the interrupt happens in the middle of a read, unless you synchronizes the accesses, possibly by _atomic_/_endatomic_.
Another thing: Are floating point operations supported in both the interupt handler and the main program at the same time?
Does it work if you declare z volatile?
volatile double z;
I see a couple of things.
Your interrupt priority is on level zero which will never allow it to vector so you need to move it off of zero.
Secondly I didn't see where you globally enabled interrupts?
Thirdly, not sure of the code sequence but if you are looking for a interrupt on the rising edge of P2.8 then here is your example slightly modified.
#include <xc167.h> double z; double Periode; void main (void) { CC1_M2 = 0x0001;// 001=>capture on posirtive Flanke CC1_T01CON = 0x0047; CC1_CC8IC = 0x0044; // Interrupt enable und, ILVL = 1 PSW_IEN = 1; // globally enable interrupts while(1) { z = Periode ; }//end of while }// end of main void Drehzahl_messung(void) interrupt(0x18) { Periode = 100; }
Hope this helps
You can not resolve 'atomic-acess problem' with volatile - what 'volatile' does, it tells to the compiler "do not optimize a call to the variable, use explicit storage location to work with". The storage location for double is more than 16-bit word so additional guard mechanism still required.
-- Nikolay.
Yes, in this case the original code both misses the 'volatile' keyword and any code to make sure that it is isn't modified in the middle of a read.
You can not resolve 'atomic-acess problem' with volatile
I'm not suggesting it would. I'm suggesting that it may solve the original problem by not allowing writes to the variable z to be optimized out. It's worth a try.
Hello Firstly, I would like to thank all the people who tried to help me The problem was simply the PSW register in the
PSW_IEN = 1;
and also with the priority of the interrupt
CC1_CC8IC = 0x0044;
and that has works I just wanted to test whether my Prograam to interrupt and the changes worked. I will now in the interrupt a speed measurement program
Thanks Chris Wunderlich Thanks to all
"The problem was simply the PSW register in the"
This represents a third problem.
You still have to think about the other two. Use volatile and protect the read of the variable from being interrupted.
Hello altogether
Hello westermark
I have now a second problem: I have used volatile but I still get no good results I must measure the period between two positive transition flanks .. sometimes I have good result but does not remain constant, over and over period = 0, what could be the reason? I have to change my code or the funktion with which I will measure the time (periode)
double periode; volatile int Timer_alt; volatile int Timer_neu; volatile int Timer_Diff; void main (void) { . . . . . while(1) { CC1_M2 = 0x0001; //Bit3 allocated to Timer T0/T7 ,Bit 210 001=>capture on posirtive Flanke CC1_T01CON = 0x0047; //Bit6 0=>Timer is enabled ,Bit3 1=>Timer Mode,Bit210 111=>Timer Resolution 25,6 µs CC1_CC8IC = 0x0044; // Interrupt enable und Interrupt Flag enable PSW_IEN = 1; // globally enable interrupts periode = Timer_Diff*0.0000256; // Periode }//end of while }// end of main /* __|----|___|----|___|----|____ */ //010101 void Drehzahl_messung(void) interrupt 24 { Timer_alt = CC1_CC8 ; // Timer contents captured do{ }while (P2 & 0x0100); //wait of the Low signal Timer_neu = CC1_CC8 ;// Timer contents captured Timer_Diff = Timer_neu - Timer_alt; }
Thanks for your help
What is generating your pulses?
Have you verified that you don't have a bouncing signal, in which case the pulse may have ended before you enter your ISR. This will result in a zero length being sampled.
Timer_alt and Timer_neu don't need volatile if they are only used inside the ISR. The volatile keyword is only needed when a variable may be asynchronously updated by other code or the hardware.
The ISR may asynchronously update a variable with relation to the main loop. But the ISR does not see any asynchronous update (unless you support nested interrupts).
If the input signal produces bouncing, then you should learn your ISR to not assign to the global Timer_Diff variable until after you have figured out if you sampled a bounce or a real signal, i.e. that the pulse had a certain minimum length.
Another thing: Is there a reason for the use of a double? You can often use fixed-point arithmetic for handling this kind of data. But it depends a bit on what further evaluations you need to do with the value.
View all questions in Keil forum