I want to measure the width of each pulse from an external signal. For this I set up a timer to run continuously,trigger at the rising edge and capture at the falling edge. There is an ISR attached to the interrupt terminal of the timer and is called Channel_1_ISR as can be seen below.
The ISR runs once since the led state is only toggled once but not after that. What am I missing?
Good catch but that doesn't explain why the led is only toggled once because I know there is a constant 2ms pulse being fed to the timer. When I put print statements in the for loop then those work indicating that the ISR runs only once initially and never runs after that. My only guess is that something is disabling the ISR but I am unsure of what.
I just added in the volatile but as expected it doesn't solve the problem here. Thanks for pointing that out though.
I believe that when using a trigger you have to reset Timer after isr also, else only one interrupt will fire. Please post your project for review. File->Create workspace bundle-> minimal
You could use Timer_ReadStatus() API to clear any of the interrupt bits. The capture freezes the current counter statre into the FIFO, so to measure the time between pulses, easiest is to reset the counter to zero. Since it is a down counter you need to subtract the capture value from the period value.
A tip for later measures: When you are interested in the pulse width, just connect the enable input to the signal.
I have changed the code in the ISR to the following and am writing 100000 into the counter as the initial value. I am still getting the wrong results though for the pulse width. As I vary the pulse width from 1 to 2ms there is close to no difference in the value of the counter.
I downloaded your code but as I move throttle from 1ms to 2ms there is no difference in the counter value- it is always at 99971. At least there is consistency now. Interestingly, the frequency of the blinking led matches that of the input signal indicating that the pulse width is being detected correctly but for some reason the stored value is incorrect.
Close- Im trying to read throttle,yaw,pitch and roll from an RC transmitter. I was planning on doing this with pin change interrupts which is what I found on a DIY flight controller online for an arduino. The flight controller has a 250Hz refresh rate using an Arduino which is impressive for an Arduino however I wanted to write a flight controller with a faster refresh rate and psoc UDBs I thought would allow me to get more out of the cpu by delegating control of sending esc pulses and reading receiver inputs to the UDB components. Having the ISR though defeats the purpose so I would like to try to save receiver inputs without an ISR in the first place. I could do this easily by writing verilog code for an FPGA but Id rather have just one controller on board rather than an MCU and an FPGA.
Replace the line containing
Channel_1_Count = Channel_1_Timer_ReadCounter();
Channel_1_Count = Channel_1_Timer_ReadCapture();
Sorry, deleted the wrong line
It still does not work unfortunately- the value I see when I print to screen oscillates around 6200 despite changing input pulse from 1 to 2ms. I double checked with an arduino to make sure that the signal can be detected correctly-therefore there is no problem with the outputs of the receiver.
Once in a while there seems to be a "glitch" and the value printed is ~2400 but apart from that it is almost always ~6200.
I have attached the bundle below.
Here are the files showing the outputs- the names are self explanatory but I printed the output by putting the print statement in the ISR itself and in main for 1ms and 2ms pulse input. The results are way off and I can't seem to figure out what's going wrong. Perhaps cypress' UDBs cant handle this frequency however 1000 Hz is hardly what I'd call high frequency. I will try the pin change ISR technique to see if that works- it should since it works flawlessly on a 16MHz arduino.
Here are two projects... one is more software oriented... the other is a more HW oriented solution.
I added a bunch of commands to the serial program to help.
The key 't': puts out a 1234us pulse (to be measured)
The key 'y' puts out a 12ms pulse (which causes overflow)
I will write about exactly how they both work with screen shots later in the week on iotexpert.com
Notice that I changed the unit of measure to uS so that the calculations were easy