I use IC to capture an input square wave, and then generate my output square wave by PWM model .
The frequency of my output is several times of the imput wave, such as 2 times, 5 times, so much as
60 times. I use IC to detect the rising edge and the trailing edge to get the pulse width, according this to determine the period of the PWM.
But I found when my input wave frequency change, the output can't be change together with the input
wave, even the times of the frequency also can't be contain.
Whether I need to close my PWM at the end of PWM period and enable it at the beginning of the
wave edge. How can I make my output wave change following the input wave change.
My programme, the input and output wave are attached.
Original Attachment has been moved to: ECT.rar
Radek,
In addition to bug 1, writing to TFLG1 doesn't make any sense when TFFCA==1.
Meng,
so is your problem that change of output PWM frequency happens much later than the change of input frequency? It is because you made your IC sensitive to rising edges only, TCTL4 =1 , EDG0B:EDG0A = 01. And this is what you see on oscillogram: PWM frequency changes soon after rising input edge, when there's a change in time difference between two adjacent rising input edges.
Edward
Hi Meng,
The period and duty registers for each channel are double buffered so that if they change while the channel is enabled, the change will NOT take effect until one of the following occurs:
• The effective period ends
• The counter is written (counter resets to $00)
• The channel is disabled
In this way, the output of the PWM will always be either the old waveform or the new waveform, not some variation in between. If the channel is not enabled, then writes to the period register will go directly to the latches as well as the buffer.
So, period and duty cycle should be automatically updated according to the last value before the end of the active period. You may try to write into PWMCNTx counter for reset counter to zero and force to load new values. The command PWME_PWME1 = 1; should not have any influence on output and you could remove it.
Unfortunately, this description didn’t fit exactly to your measurement results and I suppose that there must be some other issue.
I have three additional doubts related to your code:
1. The command ECT_TFLG1_C0F = 1; is not the correct way how to clear a flag – it is read/modify/write command and it will clear all currently pending flags. Please use rather ECT_TFLG1 = 0x01; or ECT_TFLG1_C0F = ECT_TFLG1_C0F_MASK; for clearing such flag. It should not cause any problem in your code, but it is still not correct. For more details, please look at application note AN2554 Clearing and Disabling Interrupt Flags http://www.nxp.com/files/microcontrollers/doc/app_note/AN2554.pdf
2. You didn’t implement overflow interrupt for input capture. Are you sure that time2-time1 is always smaller than full timer counter period?
3. The type of variables delaytime, aa, bb, cc and signalf is unsigned int. Are you sure that you didn’t lose any precision during calculations like signalf=delaytime*0.001*4/MUL_FREQ;?
0.001 is float number.
Please check whether any overflow or underflow cannot cause an issue.
Shouldn’t be better to calculate with unsigned long variables?
Please ensure that your formula is correct (signalf=delaytime/2500).
For example:
aa=delaytime*0.001; //16000*0.001=16
bb=aa*4; //16*4=64
cc=bb/MUL_FREQ; //64/10=6
I hope it helps you.
Have a great day,
Radek
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Radek,
Thanks for your help, I have modifed my programme according to your ideas. And there are
serveral points need to discuss with you.
1. When I remove the comment PWME_PWME1 = 1, there is no ouput,and the output appear after it added.
So I think this command is necessary.
2. I have corrected the command ECT_TFLG=0X01;
3. I changed the format of signalf from int to float to avoid data lose. It's very important , and thank you told me this point.
4. Because I know the frequency range of my input is 0-200Hz, corrospending to 0-5ms, and the ECT frequency
is 32M/128=1/4M ,4us, the full timer counter period is less than 2^16. Therefore, I didn't process this overfolw at present.
5. I add the command PWMCNT01=0X00 before I update my output.
6. In order to follow the input better, I change the capture edge from rising to both rising and falling. corresponding to
ECT_TCTL4 = 0x03;
I found the output still can't follow the change of input, how can I do then?
Have a good time!
Hi Meng,
1. The command PWME_PWME1 = 1; should stay in init_pwm() function. I do not see any reason for keeping it in Refresh_PWM() function.
2. I am sorry, but you statements “my input is 0-200Hz” and “the full timer counter period is less than 2^16” do not make sense for me for now.
3. I am sorry for the probably confusing sentence about PWMCNTx counter. You should update period and duty cycle registers and after that write PWMCNTx counter (not before). This will reset PWM counter and force to load period and duty cycle from registers buffers. Note: Writing to the counter while the channel is enabled can cause an irregular PWM cycle to occur.
4. Please do not mix automatic and manual flag clearing. Please comment out either command ECT_TSCR1_TFFCA = 1; in initialize_ect() function or command ECT_TFLG=0X01; in capture() ISR according Edward’s recommendation.
I hope it helps you.
Have a great day,
Radek
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Radek,
I have modified my programme. But I find the output still can't follow the change of input.
when the input period change from 30ms to 50ms the output frequency-multiplier signal can't
keep 3 times of the input.
The wave and programme attached.
In addition, whether the output can track the input signal in-phase, how to do?
Thanks!
Have a nice day!
Meng
Hi Meng,
signalf=delaytime/1000*4;
PWMPER01=signalf*1000/10;
This code generates the same result for 0~999, 1000~1999, 2000~2999,… delaytime.
So, there is a chance that both 30ms and 50ms input signal generates the same PWM period.
Is it correct, that you want PWM period = high or low time of input signal/2.5?
In that case please don’t use that division by 1000.
The code:
signalf=delaytime*4;
PWMPER01=signalf/10;
should give you result without losing accuracy. Be aware, that maximum delaytime must be smaller than 16383 otherwise you have to change signalf type to unsigned long and retype delaytime value to unsigned long prior signalf calculation. For example:
unsigned long signalf;
signalf=((unsigned long) delaytime) * 4;
PWMPER01=(unsigned int) (signalf/10);
I hope it helps you.
Have a great day,
Radek
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi RadekS,
I modified my programme,but the problem remains.
I reply the email to admin@community.freescale.com, it was undelivered.
Can you give me your email I want to send my programme to you and contract you directly.
Thanks ,
Have a nice day!
Meng
Hi Meng,
You may attach code here when you switch editor into advanced mode:
and then click on Attach link:
If you want to share something which is not public, please create a ticket:
How to submit a new question for NXP Support
As last option, you may send it to me at radek.sestak@nxp.com.
I hope it helps you.
Have a great day,
Radek
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
HI Radek,
I can't fine the buttons ''use advanced editor' and "attach" on my reply page https://community.nxp.com/inbox .
My page is as follow:
I have already sent you an email, I don't know whether you have received it, I haven't received your reply.
This address is right ?‘right?radek.sestak@nxp.com’radek.sestak@nxp.com’